Tutorial: ¿Como hacer Web Scraping Profesionar APIs y TLS Fingerprint?

  • Autor Autor Rainyis
  • Fecha de inicio Fecha de inicio
Rainyis

Rainyis

Alfa
Verificado
Verificación en dos pasos activada
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Casi todo el mundo que empieza en el web scraping comete el mismo error: centrarse únicamente en el frontend.
  • Si la web es estática -> requests + beautifulsoup.
  • Si es dinámica -> selenium o playwright.
Esta es la forma "clásica", pero es ineficiente y lenta. Está bien para aprender, pero en el mundo real, el 99% de las webs se pueden scrapear sin abrir un navegador, ahorrando recursos y tiempo.

Hoy os vengo a explicar cómo se hace el web scraping profesional: Ingeniería inversa de APIs + TLS Fingerprinting.

1. TLS Fingerprint​

Las webs modernas no solo miran tu User-Agent. Analizan tu "TLS Fingerprint" (una huella técnica de cómo tu cliente establece la conexión segura). La librería estándar de Python (requests) tiene una huella muy obvia y es bloqueada fácilmente por Cloudflare o Akamai.

Para evitarlo, usaremos librerías como curl_cffi, que simulan la huella exacta de un navegador real (Chrome, Safari, etc.).

2. Atacar la API, no el HTML​

Nunca extraigas datos del HTML si puedes evitarlo. El HTML cambia, se rompe y viene lleno de basura (CSS, JS). Lo ideal es interceptar la API que alimenta la web.

¿Cómo se hace?:
  1. Abre la web (ej: Nike) y pulsa F12 (DevTools).
  2. Ve a la pestaña Network y filtra por Fetch/XHR.
  3. Recarga la página o haz scroll. Verás aparecer peticiones JSON.
  4. Busca la que contiene los datos que te interesan (precios, nombres, stock).

1766960769796.webp


3. Caso práctico​

En el ejemplo de Nike, encontramos una API que devuelve los productos en formato JSON limpio. Para llevar esto a Python sin dolor:
  1. Click derecho en la petición > Copy >Copy as cURL (bash).
  2. Ve a curlconverter.com y pega el código.
  3. Importante: Selecciona la librería curl_cffi en las opciones de salida (para evitar bloqueos), o usa el código de abajo adaptado.
Aquí tenéis el código funcional simulando ser un navegador real para evitar el bloqueo (he limpiado los parámetros de la url y los he introducido en el diccionario params para que este más estructurado, esto lo suele hacer curlconverter solo, pero hay a veces que falla):

Python:
from curl_cffi import requests
#url de la API
url = 'https://api.nike.com/discover/product_wall/v1/marketplace/ES/language/es-ES/consumerChannelId/d9a5bc42-4b9c-4976-858a-f159cf99c647?path=/es/w/hombre-lifestyle-zapatillas-13jrmznik1zy7ok'


params = {
  'attributeIds': ['16633190-45e5-4830-a068-232ac7aea82c', '0f64ecc7-d624-4e91-b171-b83a03dd8550','193af413-39b0-4d7e-ae34-558821381d3f'],
  'queryType': 'PRODUCTS',
  'anchor': '24',  # <-- Aquí controlas la paginación (empezar en el producto 24)
  'count': '24',   # <-- Cantidad de productos a traer
}


#Headers mínimos (normalmente es bueno dejar el accept, accept-language, priority, referer y origin, ya que de lo demás se encarga la TLS fingerprint.
#En este caso a parámetros específicos de nike que son necesarios a si que también los dejaremos (anonymousid, nike-api-caller-id)
headers = {
  'accept': '*/*',
  'accept-language': 'es-ES,es;q=0.9',
  'anonymousid': 'unknown-anonymousid',
  'nike-api-caller-id': 'nike:dotcom:browse:wall.client:2.0',
  'origin': 'https://www.nike.com',
  'priority': 'u=1, i',
  'referer': 'https://www.nike.com/',
}

response = requests.get(
  url,
  params=params,
  headers=headers,
  impersonate='firefox135' # Suelo usar firefox en vez de chrome, ya que he tenido mejores experiencias para bypassear anti-bots
)

if response.status_code == 200:
  data = response.json()
  print("Éxito! Datos obtenidos:")
  print(data)
else:
  print(f"Error: {response.status_code}")

¿Por qué hacer esto?​

  1. Eficiencia brutal: Descargas solo los datos (JSON de 10kb) en vez de toda la web (HTML/JS/Imágenes de 2MB).
  2. Velocidad: En este ejemplo, sacas 24 productos en 1 sola petición. Con Selenium tendrías que esperar a que cargue el DOM.
  3. Estabilidad: Aunque Nike cambie el diseño de su web (colores, botones), la API suele mantenerse igual mucho más tiempo.
  4. Facilidad: Normalmente las APIs no tienen un sistema anti-bots tan restrictivo como el de las webs que visita el usuario lo que permite evitar CAPTCHAS

Resumen​

Si quieres dedicarte al scraping, aprende a leer la pestaña Network y usa librerías que soporten TLS Fingerprinting (curl_cffi en Python o tls-client en Go/Node).

Si os ha gustado el aporte o tenéis dudas con alguna web que se os resista, dejad un comentario. Si veo interés, en el próximo post explicaré cómo automatizar la paginación (el parámetro anchor) para descargar catálogos enteros en segundos.
 
Última edición:
Hola como estas?
Me podrias ayudar a realizar uno?
Saludos.
 
Bien, es algo que no conocía.
 
Ese es el problema principal de las webs basadas en front, que tienen los datos super expuestos
 
He hecho varios raspados, pero este parece más suave.
 
Casi todo el mundo que empieza en el web scraping comete el mismo error: centrarse únicamente en el frontend.
  • Si la web es estática -> requests + beautifulsoup.
  • Si es dinámica -> selenium o playwright.
Esta es la forma "clásica", pero es ineficiente y lenta. Está bien para aprender, pero en el mundo real, el 99% de las webs se pueden scrapear sin abrir un navegador, ahorrando recursos y tiempo.

Hoy os vengo a explicar cómo se hace el web scraping profesional: Ingeniería inversa de APIs + TLS Fingerprinting.

1. TLS Fingerprint​

Las webs modernas no solo miran tu User-Agent. Analizan tu "TLS Fingerprint" (una huella técnica de cómo tu cliente establece la conexión segura). La librería estándar de Python (requests) tiene una huella muy obvia y es bloqueada fácilmente por Cloudflare o Akamai.

Para evitarlo, usaremos librerías como curl_cffi, que simulan la huella exacta de un navegador real (Chrome, Safari, etc.).

2. Atacar la API, no el HTML​

Nunca extraigas datos del HTML si puedes evitarlo. El HTML cambia, se rompe y viene lleno de basura (CSS, JS). Lo ideal es interceptar la API que alimenta la web.

¿Cómo se hace?:
  1. Abre la web (ej: Nike) y pulsa F12 (DevTools).
  2. Ve a la pestaña Network y filtra por Fetch/XHR.
  3. Recarga la página o haz scroll. Verás aparecer peticiones JSON.
  4. Busca la que contiene los datos que te interesan (precios, nombres, stock).

Ver el archivo adjunto 1560706

3. Caso práctico​

En el ejemplo de Nike, encontramos una API que devuelve los productos en formato JSON limpio. Para llevar esto a Python sin dolor:
  1. Click derecho en la petición > Copy >Copy as cURL (bash).
  2. Ve a curlconverter.com y pega el código.
  3. Importante: Selecciona la librería curl_cffi en las opciones de salida (para evitar bloqueos), o usa el código de abajo adaptado.
Aquí tenéis el código funcional simulando ser un navegador real para evitar el bloqueo (he limpiado los parámetros de la url y los he introducido en el diccionario params para que este más estructurado, esto lo suele hacer curlconverter solo, pero hay a veces que falla):

Python:
from curl_cffi import requests
#url de la API
url = 'https://api.nike.com/discover/product_wall/v1/marketplace/ES/language/es-ES/consumerChannelId/d9a5bc42-4b9c-4976-858a-f159cf99c647?path=/es/w/hombre-lifestyle-zapatillas-13jrmznik1zy7ok'


params = {
  'attributeIds': ['16633190-45e5-4830-a068-232ac7aea82c', '0f64ecc7-d624-4e91-b171-b83a03dd8550','193af413-39b0-4d7e-ae34-558821381d3f'],
  'queryType': 'PRODUCTS',
  'anchor': '24',  # <-- Aquí controlas la paginación (empezar en el producto 24)
  'count': '24',   # <-- Cantidad de productos a traer
}


#Headers mínimos (normalmente es bueno dejar el accept, accept-language, priority, referer y origin, ya que de lo demás se encarga la TLS fingerprint.
#En este caso a parámetros específicos de nike que son necesarios a si que también los dejaremos (anonymousid, nike-api-caller-id)
headers = {
  'accept': '*/*',
  'accept-language': 'es-ES,es;q=0.9',
  'anonymousid': 'unknown-anonymousid',
  'nike-api-caller-id': 'nike:dotcom:browse:wall.client:2.0',
  'origin': 'https://www.nike.com',
  'priority': 'u=1, i',
  'referer': 'https://www.nike.com/',
}

response = requests.get(
  url,
  params=params,
  headers=headers,
  impersonate='firefox135' # Suelo usar firefox en vez de chrome, ya que he tenido mejores experiencias para bypassear anti-bots
)

if response.status_code == 200:
  data = response.json()
  print("Éxito! Datos obtenidos:")
  print(data)
else:
  print(f"Error: {response.status_code}")

¿Por qué hacer esto?​

  1. Eficiencia brutal: Descargas solo los datos (JSON de 10kb) en vez de toda la web (HTML/JS/Imágenes de 2MB).
  2. Velocidad: En este ejemplo, sacas 24 productos en 1 sola petición. Con Selenium tendrías que esperar a que cargue el DOM.
  3. Estabilidad: Aunque Nike cambie el diseño de su web (colores, botones), la API suele mantenerse igual mucho más tiempo.
  4. Facilidad: Normalmente las APIs no tienen un sistema anti-bots tan restrictivo como el de las webs que visita el usuario lo que permite evitar CAPTCHAS

Resumen​

Si quieres dedicarte al scraping, aprende a leer la pestaña Network y usa librerías que soporten TLS Fingerprinting (curl_cffi en Python o tls-client en Go/Node).

Si os ha gustado el aporte o tenéis dudas con alguna web que se os resista, dejad un comentario. Si veo interés, en el próximo post explicaré cómo automatizar la paginación (el parámetro anchor) para descargar catálogos enteros en segundos.
Claro que sí, guapi.
 
Atrás
Arriba