Volver al blog
La ciencia del web scraping
Raluca PenciucLast updated on May 13, 202615 min read

Cabeceras HTTP Web Scraping: Deja de ser bloqueado

Cabeceras HTTP Web Scraping: Deja de ser bloqueado
En resumen: los encabezados HTTP suelen ser la razón por la que tu rastreador recibe un error 403 mientras que tu navegador carga la misma URL sin problemas. Esta guía muestra qué encabezados inspeccionan realmente los sistemas antibots, cómo capturar el conjunto de encabezados de un navegador real desde DevTools, cómo enviarlos y rotarlos correctamente en Python y Node.js, y cuándo deja de merecer la pena el ajuste manual y resulta más recomendable utilizar una API de rastreo gestionada.

La mayoría de los scrapers bloqueados no lo son por su IP. Son bloqueados por la solicitud que envían antes incluso de que comience el cuerpo. El scraping web con encabezados HTTP consiste en hacer que los metadatos de tu cliente parezcan los de un navegador real en lugar de los de una biblioteca predeterminada de Python o Node.js, y es la herramienta más barata y menos utilizada que tienes contra la detección antibots.

En HTTP, un encabezado es un par nombre-valor separado por dos puntos que contiene metadatos sobre la solicitud o la respuesta: la identidad del cliente, los idiomas aceptados, la codificación, las cookies, el contexto de seguridad y más. La referencia de MDN sobre encabezados HTTP y el RFC 9110 definen la semántica canónica. Los sistemas de detección comparan el conjunto de encabezados de tu scraper con la huella digital de una sesión real de Chrome o Firefox, y cualquier discrepancia en los valores, la presencia, las mayúsculas o el orden puede marcar la solicitud.

Esta guía está dirigida a ingenieros de backend, datos y operaciones cuyos rastreadores devuelven códigos de estado 403, 429, cuerpos vacíos o una página diferente a la que ve el navegador. Al finalizar, sabrás qué encabezados son importantes, cómo leerlos desde DevTools y reproducirlos en Python o Node.js, cómo gestionar el orden de los encabezados y las huellas digitales TLS, y cuándo dejar de ajustar y delegar la capa de solicitudes a un servicio gestionado.

Encabezados HTTP: Introducción al web scraping: Encabezados frente a cookies, actualizado

Empieza por entender bien el modelo. Un encabezado de solicitud es metadato que tu cliente adjunta a una solicitud saliente: quién eres, qué aceptas, de dónde vienes. Un encabezado de respuesta es metadato que el servidor devuelve: indicaciones de estado, tipo de contenido, reglas de caché y Set-Cookie directivas.

Las cookies no son un protocolo independiente; son un encabezado con estado. El servidor las distribuye a través de Set-Cookie, y tu cliente las devuelve en un Cookie encabezado en cada solicitud posterior. Según el RFC 6265, ese intercambio mantiene activas las sesiones, transporta tokens de autenticación, fija la ubicación geográfica y almacena segmentos A/B.

Para el web scraping de encabezados HTTP, ambas capas son importantes. Si se estropea cualquiera de ellas, el cliente parecerá nuevo en cada visita, que es exactamente lo que busca la detección de bots. Nuestra guía sobre cookies HTTP explica la mecánica subyacente.

Qué encabezados vigilan realmente los sistemas antibots

Los servidores no valoran todos los encabezados por igual. Una breve lista hace el trabajo pesado en las pilas de huellas digitales reales, y los mismos nombres aparecen en todos los proveedores de detección. Los apartados H3 a continuación cubren esos encabezados más o menos en orden de impacto para el web scraping de encabezados HTTP, desde el que casi todo el mundo se equivoca (User-Agent) hasta las pistas del cliente y las cookies por sesión.

User-Agent: el encabezado más comprobado y más falsificado

User-Agent identifica el software del cliente, el sistema operativo y el motor del navegador, y es el primer encabezado que comprueban los sistemas anti-bot. Los valores predeterminados como python-requests/2.x o el valor predeterminado de axios se bloquean al instante porque ningún visitante real los envía. El perfil más común en el mundo real es Chrome en Windows, por lo que ese es el objetivo más seguro para imitar.

Hay dos patrones que fallan con total seguridad. El primero es reutilizar un único UA en millones de solicitudes. El segundo es editar un UA real a mano, cambiando un dígito, y acabar con una versión que ningún navegador real ha lanzado jamás. En el momento de escribir este artículo, comprueba que coincide con una versión actual de Chrome o Firefox en lugar de copiar una cadena de versión de cualquier tutorial, incluido este.

Accept, Accept-Language y Accept-Encoding

Estos tres indican qué contenido puede gestionar tu cliente. Accept enumera los tipos MIME, Accept-Language enumera configuraciones regionales como en-US,en;q=0.9, y Accept-Encoding enumera los algoritmos de compresión (gzip, deflate, br). Los navegadores reales envían aquí valores ricos y ordenados, y las cadenas exactas difieren entre Chrome y Firefox.

Las trampas son sutiles. Una IP residencial de EE. UU. emparejada con Accept-Language: ru supone una discrepancia en la huella digital. Enviar br (Brotli) pero luego no poder descodificar un cuerpo Brotli parece igual de propio de un bot. Haz coincidir Accept-Language con la ubicación geográfica de tu proxy y solo anuncia formatos de compresión que tu cliente HTTP realmente descomprima de forma transparente.

Referer y Origin

Referer indica al servidor qué página ha enviado al usuario a esta URL. Una visita a una página de producto específica sin Referer parece sospechoso, ya que los visitantes reales suelen llegar desde un motor de búsqueda, una lista de categorías o un enlace interno. Establece una Referer , como una búsqueda en Google o la propia página de categorías del sitio.

Origin es su primo más estricto: los navegadores lo adjuntan a las solicitudes POST y fetch/XHR de origen cruzado. Si estás reproduciendo una llamada a la API que has observado en DevTools, copia el Origin encabezado tal cual, o el servidor considerará la solicitud como falsificada.

Sec-Fetch y Client Hints (Sec-CH-UA)

Los navegadores Chromium modernos añaden una familia de encabezados de contexto de seguridad que las guías de scraping más antiguas ignoran: Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, y Sec-Fetch-User. Describen si la solicitud es una navegación de primer nivel, un recurso incrustado o una XHR de origen cruzado. Una carga directa de la página desde una pestaña nueva suele enviar Sec-Fetch-Site: none, Sec-Fetch-Mode: navigate, y Sec-Fetch-Dest: document.

las pistas del cliente (Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform) repiten tu perfil de agente de usuario de forma estructurada. La comprobación de la huella digital es sencilla: si tu User-Agent afirma que es Chrome en Windows, pero tu Sec-CH-UA-Platform dice "macOS", se te marca. Indica siempre la fuente User-Agent, Sec-CH-UAy Sec-CH-UA-Platform utiliza la misma captura de pantalla real del navegador para que sean coherentes entre sí.

Cookies y encabezados de sesión

Tras la primera solicitud, Cookie se convierte en el encabezado con mayor carga de identidad que envías. Los sistemas antibots lo utilizan para rastrear si una sesión está activa, si has aceptado un banner de consentimiento y si tu token CSRF proviene de la misma renderización que el formulario que estás enviando. Si eliminas las cookies entre solicitudes, parecerás un visitante nuevo cada vez.

Los encabezados personalizados como x-csrf-token, x-api-key, y Authorization aparecen en los puntos finales XHR detrás de las SPA modernas. Extráelas del HTML o de una respuesta JSON anterior y, a continuación, adjúntalas a la llamada de datos real. Sin ese paso, la API devuelve un 401 o resultados vacíos.

Captura encabezados de navegador reales desde DevTools

Deja de adivinar los valores de los encabezados. Abre el sitio de destino en una sesión normal de Chrome o Firefox, haz clic con el botón derecho y selecciona Inspeccionar, luego cambia a la pestaña Red. Vuelve a cargar la página, haz clic en la primera solicitud de documento (el HTML) y abre el panel Encabezados. La sección Encabezados de solicitud es tu referencia.

Hay dos trucos que te ahorrarán tiempo. Haz clic con el botón derecho en la solicitud y selecciona «Copiar como cURL» para volcar la llamada completa, incluyendo encabezados, cookies y cuerpo, en un comando listo para el shell. Y antes de reproducirla, elimina los valores específicos de la sesión como Cookie, x-client-data, y cualquier token CSRF de un solo uso.

Valida la reproducción dirigiéndola a httpbin.org/headers, que devuelve exactamente lo que envió tu cliente. Si la respuesta no coincide con la captura de DevTools, tu biblioteca HTTP está reescribiendo datos. Nuestra guía de encabezados de respuesta de cURL cubre tácticas de inspección más avanzadas.

Enviar encabezados personalizados en Python y Node.js

El patrón es el mismo en todos los clientes HTTP: crea un diccionario con los nombres y valores de los encabezados, adjúntalo a la solicitud y reutiliza una sesión para que las cookies persistan. Las dos secciones específicas de cada lenguaje que aparecen a continuación muestran los escollos que surgen a gran escala.

Python (requests y httpx)

Con requests, pasa un headers dict a get, y utiliza un Session para que las cookies se mantengan entre llamadas:

import requests

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/<current> Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Dest": "document",
}

with requests.Session() as s:
    s.headers.update(headers)
    r = s.get("https://httpbin.org/headers")
    print(r.json())

El inconveniente: requests no conserva el orden de los encabezados de forma fiable, lo cual es una debilidad conocida en materia de huellas digitales. Para el web scraping de encabezados HTTP a gran escala, es preferible httpx, que mantiene el orden de inserción exacto de tu diccionario y es compatible con HTTP/2. Crea el diccionario en el mismo orden que mostraban las DevTools y la imagen de la conexión se mantendrá coherente.

Node.js (axios y fetch)

En Node.js, tanto axios como los nativos fetch aceptan un headers objeto. Reutiliza una instancia de axios para compartir los valores predeterminados y utiliza un «cookie jar» (axios-cookiejar-support o similar) para que las sesiones se mantengan entre solicitudes:

import axios from "axios";

const client = axios.create({
  headers: {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
                  "AppleWebKit/537.36 (KHTML, like Gecko) " +
                  "Chrome/<current> Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Dest": "document",
  },
});

const { data } = await client.get("https://httpbin.org/headers");
console.log(data);

Ten cuidado con los valores predeterminados de axios como X-Requested-With: XMLHttpRequest, que filtra la biblioteca. Anúlalos o elimínalos explícitamente. Nuestro análisis en profundidad de los encabezados de Axios cubre los patrones de evitación de detección en la capa de solicitud.

Orden de los encabezados, mayúsculas y minúsculas, y huellas digitales TLS

Los nombres de los encabezados no distinguen entre mayúsculas y minúsculas según el RFC, pero su mayúsculas y minúsculas y su orden son, en gran medida, una huella digital. El Chrome real envía User-Agent con esa misma mayúscula/minúscula en una ranura específica relativa a Accept y Sec-Fetch-*. Python requests históricamente pone los nombres en minúsculas y no garantiza el orden; httpx conserva lo que le des; axios suele ser fiel, pero añade sus propios valores predeterminados si no los eliminas.

Eso es solo la mitad del panorama. Incluso con un conjunto de encabezados perfecto, tu protocolo de enlace TLS es su propia huella digital. JA3 y el más reciente JA4 calculan el hash de los conjuntos de cifrado, las extensiones y las curvas elípticas que ofrece tu cliente. Una pila TLS de Python que dice ser Chrome pero que ofrece el orden de cifrado de OpenSSL es una mentira evidente; consulta tlsfingerprint.io para ver lo detectable que es eso.

Medidas de mitigación: utiliza un cliente compatible con HTTP/2 con una configuración TLS realista (curl_cffi, tls-client en Python; undici con TLS personalizado en Node), o pasa a un proxy oculto o una API gestionada que se encargue de la capa TLS por ti.

Rota y actualiza los conjuntos de encabezados a gran escala

A gran escala, la rotación de encabezados HTTP en el web scraping funciona a nivel de sesión, no a nivel de solicitud. Mantenga un conjunto de encabezados realista durante la vida útil de sus cookies, y cámbielo solo cuando inicie una nueva identidad. Cambiar User-Agent a mitad de sesión es en sí misma una señal de detección.

Crea un conjunto de cientos de conjuntos de encabezados reales a partir de las versiones actuales de Chrome, Firefox, Edge y Safari. Actualízalo a medida que se actualicen los navegadores; de lo contrario, destacarás por utilizar el UA del año pasado. Combina la rotación de encabezados con la rotación de proxies para que ni la IP ni los encabezados por sí solos se conviertan en una clave estable. Nuestra guía para evitar bloqueos de IP y el tutorial sobre proxies en Python requests cubren el aspecto de los proxies.

Encabezados predeterminados de la biblioteca que debes eliminar antes de enviar

Antes de que se envíe cualquier solicitud, revisa lo que tu biblioteca envía sin que se le pida. Indicios comunes:

  • User-Agent: python-requests/<version> o el UA predeterminado de axios
  • X-Requested-With: XMLHttpRequest de axios
  • Accept: */* en lugar de una lista MIME real
  • Connection: close cuando los navegadores reales mantienen la conexión
  • inyectado por el proxy Via, X-Forwarded-For, y Forwarded

Sustituye los cuatro primeros por valores realistas y prueba tu proxy con httpbin.org/headers para detectar el último grupo.

Depuración de bloqueos basados en encabezados: una lista de verificación

El ciclo de depuración para el web scraping de encabezados HTTP es breve. Cuando obtengas un 403, un 429 o un cuerpo vacío que el navegador muestra correctamente, sigue esta lista en orden:

  1. Compara los encabezados. Compara la captura de DevTools con httpbin.org/headers línea por línea.
  2. Cambia el User-Agent por una cadena diferente de Chrome o Firefox actual y vuelve a intentarlo.
  3. Comprueba Accept-Encoding. Si lo indicas br, confirma que tu cliente lo descomprime; de lo contrario, descártalo.
  4. Verifica las cookies. Confirma Cookie coincide con la sesión que has preparado.
  5. Repítelo con cURL desde Copy as cURL. Si cURL funciona y tu código no, la diferencia está en tu cliente. Si cURL también falla, el problema está en la IP o en TLS, no en los encabezados.

Cuándo pasar de los encabezados manuales a una API de scraping gestionada

El scraping web con encabezados HTTP manuales tiene un límite. Pasa a la siguiente fase cuando te encuentres con cualquiera de estos casos:

  • Bloqueos TLS o JA3/JA4 que persisten incluso con encabezados perfectos. La solución está por debajo de HTTP.
  • Concurrencia superior a unos pocos cientos de sesiones, donde los grupos de UA y las galletas recién generados se convierten en un servicio propio.
  • Coste de rotación en horas de ingeniería que supera lo que cobra un punto final gestionado por cada éxito.
  • Objetivos difíciles detrás de la gestión de bots empresariales que vinculan las sesiones a una huella digital completa del navegador.

Una API de scraper gestionada o un proxy sigiloso controla los encabezados, el TLS, las IP y los reintentos detrás de un único punto final, por lo que tu código conserva la lógica de análisis. Nuestra guía de 2026 sobre web scraping sin ser bloqueado cubre toda la ruta de escalado.

Puntos clave

  • Los encabezados predeterminados de las bibliotecas son la pista más evidente. Sustituye python-requests/x.y los UA, los valores predeterminados de axios y X-Requested-With antes que nada.
  • Captura, no inventes. Extrae conjuntos de encabezados de DevTools o Copy as cURL, elimina los valores específicos de la sesión y valida con httpbin.org/headers.
  • La coherencia interna es más importante que el mero realismo. User-Agent, Sec-CH-UA, Sec-CH-UA-Platform, y Accept-Language todos deben describir el mismo navegador, sistema operativo y ubicación geográfica.
  • El orden y el TLS son tan importantes como los valores. Da preferencia a httpx a requests en Python, y utiliza un cliente compatible con TLS (o una API gestionada) cuando se utilice la identificación de huellas digitales JA3/JA4.
  • Rota por sesión, no por solicitud. Mantén un conjunto de encabezados durante la vida útil de la cookie, actualiza el conjunto a medida que se actualizan los navegadores y combínalo con la rotación de proxies.

Preguntas frecuentes

¿Por qué siguen bloqueándose mis solicitudes después de haber copiado los encabezados exactos de Chrome?

Normalmente porque los encabezados no son la única señal. Tu handshake TLS (JA3/JA4), el orden de los frames HTTP/2, la reputación de la IP y la falta de cookies de sesión crean una huella digital de tu cliente de forma independiente. Incluso los encabezados con bytes idénticos fallan cuando la pila TLS subyacente dice «Python» en lugar de «Chrome». Vuelve a enviar la solicitud con cURL: si cURL tiene éxito y tu código no, la diferencia está por debajo de la capa de encabezados.

¿Con qué frecuencia debo rotar las cadenas User-Agent y los conjuntos completos de encabezados entre las solicitudes?

Rótalas por sesión, no por solicitud. Un visitante real mantiene el mismo navegador durante toda la visita, por lo que una sesión que cambia User-Agent en pleno vuelo es en sí misma sospechosa. Mantén un conjunto de encabezados durante la vida útil de su jarra de cookies y, a continuación, elige uno nuevo para la siguiente sesión. Actualiza el conjunto subyacente cada pocas semanas, a medida que Chrome y Firefox lanzan nuevas versiones estables.

¿Sigo necesitando configurar encabezados HTTP si utilizo un navegador sin interfaz gráfica como Playwright o Puppeteer?

Sí, en parte. Un navegador sin interfaz gráfica envía encabezados realistas automáticamente, incluyendo Sec-CH-UA y Sec-Fetch-*, por lo que puedes saltarte la mayor parte del trabajo manual. Aún así, debes anular el modo sin interfaz gráfica User-Agent (que a menudo incluye HeadlessChrome), configurar un Accept-Language para la ubicación geográfica de tu proxy y desactivar el navigator.webdriver indicador mediante un complemento de ocultación o un indicador de inicio.

¿Puede una API de scraping gestionada o un proxy inteligente gestionar automáticamente los encabezados HTTP por mí?

Sí. Las API de scraping gestionadas y las redes de proxies de ocultación eligen un conjunto de encabezados realista por cada objetivo, lo asocian a una IP residencial y un perfil TLS, y lo rotan todo de forma sincronizada. Tú envías la URL de destino y ellos te devuelven el HTML o JSON. La disyuntiva es el coste por solicitud frente al tiempo de ingeniería que supone crear y mantener tu propia pila de encabezados, proxies y huellas digitales.

¿Cómo puedo saber si un bloqueo se debe a los encabezados, a la IP o a una huella digital TLS?

Aísla una variable cada vez. Primero, vuelve a enviar tu solicitud exacta curl --resolve desde la misma IP; si cURL tiene éxito, el problema está en los encabezados o en el orden de tu cliente HTTP. A continuación, cambia a una IP residencial diferente con los mismos encabezados; si el bloqueo desaparece, la IP estaba marcada. Si nada de esto ayuda, lo más probable es que el culpable sea el handshake TLS.

Conclusión

El scraping de encabezados HTTP no es la parte más glamurosa de crear un scraper, pero es la que ofrece mayor rendimiento con un mínimo esfuerzo. Captura los encabezados reales del navegador, envíalos en el orden que utilizó el navegador, mantén User-Agent, Sec-CH-UAy Accept-Language internamente coherentes, rotan por sesión en lugar de por solicitud, y elimina los valores predeterminados de la biblioteca que delatan la automatización. Ese conjunto de hábitos elimina la mayoría de los 403 y 429 fáciles antes incluso de que tengas que recurrir a un proxy.

Más allá de eso, el ajuste manual se topa con un muro. Las huellas digitales JA3/JA4, la gestión de bots empresariales y la gran concurrencia empujan el trabajo más allá de la capa de encabezados, y ese es el momento adecuado para dejar de hacerlo a mano y dejar que un servicio gestionado se encargue de ello. Si tu pila se encuentra en ese punto, la API Scraper de WebScrapingAPI gestiona los encabezados, los perfiles TLS, las IP residenciales y los reintentos detrás de un único punto final, de modo que conservas la lógica de análisis y te libras de la carrera armamentística de las huellas digitales. Empieza por ahí cuando los encabezados manuales dejen de ser la opción más económica.

Acerca del autor
Raluca Penciuc, Desarrollador full-stack @ WebScrapingAPI
Raluca PenciucDesarrollador full-stack

Raluca Penciuc es desarrolladora full stack en WebScrapingAPI, donde se dedica a crear rastreadores, mejorar las técnicas de evasión y buscar formas fiables de reducir la detección en los sitios web de destino.

Empieza a crear

¿Estás listo para ampliar tu recopilación de datos?

Únete a más de 2000 empresas que utilizan WebScrapingAPI para extraer datos de la web a escala empresarial sin ningún gasto de infraestructura.