Volver al blog

Cómo reducir la tasa de prohibición en web scraping al 5%: 12 métodos probados de protección

Analizamos 12 métodos probados para reducir la tasa de prohibición al hacer scraping: desde la configuración de proxies hasta la simulación del comportamiento de un usuario real. Ejemplos prácticos y soluciones listas.

📅10 de febrero de 2026
```html

Si te dedicas al scraping de marketplaces, monitoreo de precios de la competencia o recopilación de datos de sitios web, conoces el problema: los sitios bloquean direcciones IP, requieren captcha o devuelven páginas vacías. El ban rate (porcentaje de solicitudes bloqueadas) puede alcanzar el 70-90%, haciendo imposible el scraping. En este artículo analizaremos métodos concretos que ayudarán a reducir el ban rate al 5-10% y recopilar datos de manera estable.

Examinaremos tanto soluciones técnicas (rotación de proxies, encabezados HTTP, fingerprinting) como patrones de comportamiento (retrasos, imitación de acciones del usuario). Todos los métodos han sido probados en la práctica al hacer scraping de Wildberries, Ozon, Avito y plataformas extranjeras.

Por qué los sitios bloquean scrapers: principales desencadenantes

Antes de analizar los métodos de protección, es importante entender cómo los sitios identifican el tráfico automatizado. Los sistemas anti-bot modernos (Cloudflare, Akamai, DataDome, Imperva) analizan decenas de parámetros de cada solicitud. Estos son los principales desencadenantes de bloqueo:

Desencadenantes a nivel de red:

  • Demasiadas solicitudes desde una sola dirección IP (por ejemplo, más de 100 solicitudes por minuto)
  • IP de rangos conocidos de centros de datos (AWS, Google Cloud, Hetzner)
  • Inconsistencia geográfica: una IP de Rusia solicita la versión en inglés del sitio
  • Ausencia de registro DNS inverso para la dirección IP

Desencadenantes a nivel HTTP:

  • Ausencia o encabezados HTTP incorrectos (User-Agent, Accept-Language, Referer)
  • El orden de los encabezados difiere del estándar del navegador
  • La versión TLS/SSL no corresponde al navegador declarado
  • Ausencia de cookies o uso incorrecto de las mismas

Desencadenantes a nivel de navegador (JavaScript):

  • Ausencia de ejecución de JavaScript (si usas un cliente HTTP simple)
  • Browser fingerprinting: Canvas, WebGL, AudioContext, fuentes instaladas
  • Ausencia de movimiento del ratón, scroll, clics
  • Tamaño de la ventana del navegador (los navegadores headless suelen tener tamaños no estándar)
  • Presencia de automatización: propiedades navigator.webdriver, window.chrome

Desencadenantes de comportamiento:

  • Navegación demasiado rápida entre páginas (menos de 1 segundo)
  • Intervalos idénticos entre solicitudes (por ejemplo, exactamente cada 2 segundos)
  • Recorrido secuencial de páginas (1, 2, 3, 4...) sin saltos
  • Ausencia de acciones típicas del usuario: búsqueda, filtros, visualización de imágenes

Por ejemplo, al hacer scraping de Wildberries, un error típico es enviar solicitudes cada 0.5 segundos desde una sola IP. El sistema anti-bot Cloudflare identificará instantáneamente el patrón y bloqueará la IP durante 24 horas. Un usuario real tarda 5-15 segundos en ver la ficha de un producto, hace scroll en la página, hace clic en las imágenes.

Rotación de proxies: cómo cambiar correctamente las direcciones IP

El uso de proxies es un método básico para reducir el ban rate. Pero es importante no solo comprar proxies, sino configurar correctamente la rotación. Aquí están las estrategias probadas:

Elección del tipo de proxy para scraping

Tipo de proxy Ban rate Velocidad Cuándo usar
Proxies de centros de datos Alto (40-60%) Muy alta Sitios simples sin protección, scraping masivo con gran pool de IP
Proxies residenciales Bajo (5-15%) Media Marketplaces (Wildberries, Ozon), sitios con Cloudflare, redes sociales
Proxies móviles Muy bajo (2-8%) Baja Sitios con protección agresiva, versiones móviles de aplicaciones

Para el scraping de marketplaces (Wildberries, Ozon, Avito) se recomiendan proxies residenciales: tienen IPs de usuarios domésticos reales que son difíciles de distinguir del tráfico normal. Los proxies de centros de datos son adecuados para sitios menos protegidos o cuando se necesita máxima velocidad con gran volumen de datos.

Estrategias de rotación de direcciones IP

Estrategia 1: Rotación por tiempo

Cambia la IP cada 5-10 minutos. Este es el equilibrio óptimo: suficientemente largo para no levantar sospechas con cambios frecuentes, pero suficientemente frecuente para no acumular historial de solicitudes en una sola IP.

Ejemplo: Al hacer scraping de un catálogo de 1000 productos con un intervalo de 3 segundos entre solicitudes, una IP estará activa aproximadamente 100 solicitudes, luego ocurre el cambio.

Estrategia 2: Rotación por número de solicitudes

Cambia la IP después de 50-150 solicitudes. Esto ayuda a evitar la acumulación de actividad sospechosa en una sola dirección. Añade aleatoriedad: no exactamente 100 solicitudes, sino de 80 a 120.

Ejemplo: Configura el script para que después de un número aleatorio de solicitudes (80-120) ocurra la rotación de proxy del pool.

Estrategia 3: Sticky sessions (proxies de sesión)

Para sitios que requieren autorización o trabajan con carrito de compras, usa sticky sessions: fijación de IP durante la sesión (10-30 minutos). Esto permite mantener las cookies y no levantar sospechas al cambiar de IP dentro de una misma sesión.

Ejemplo: Al hacer scraping del área personal en Ozon, usa una sola IP para el inicio de sesión y todas las solicitudes posteriores dentro de una sesión de 15 minutos.

Importante: No uses la misma IP para diferentes tareas. Si una IP fue bloqueada al hacer scraping de un sitio, no la uses inmediatamente para otro: espera 24-48 horas.

Tamaño del pool de proxies

El tamaño mínimo del pool depende de la intensidad del scraping:

  • Baja intensidad (hasta 10,000 solicitudes por día): 10-20 proxies
  • Intensidad media (10,000 - 100,000 solicitudes por día): 50-100 proxies
  • Alta intensidad (más de 100,000 solicitudes por día): 200+ proxies o residenciales con rotación automática

Para proxies residenciales con rotación en cada solicitud (rotating proxies), el tamaño del pool puede ser menor, ya que el proveedor automáticamente asigna una nueva IP de su pool de millones de direcciones.

User-Agent y encabezados HTTP: imitación de un navegador real

Incluso con buenos proxies, pueden bloquearte si los encabezados HTTP parecen sospechosos. Los sitios analizan no solo el User-Agent, sino también el orden de los encabezados, sus valores y correspondencia entre sí.

User-Agent correcto

No uses el mismo User-Agent para todas las solicitudes. Crea una lista de navegadores populares y elige aleatoriamente de ella:

user_agents = [
    # Chrome en Windows
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    # Chrome en macOS
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    # Firefox en Windows
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
    # Safari en macOS
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15",
    # Edge en Windows
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
]

Error: Usar versiones obsoletas de navegadores (por ejemplo, Chrome 80) levantará sospechas inmediatamente. Actualiza la lista de User-Agent cada 2-3 meses, siguiendo las versiones actuales en el sitio whatismybrowser.com.

Conjunto completo de encabezados HTTP

Los navegadores modernos envían 15-20 encabezados. Aquí está el conjunto mínimo necesario para imitar Chrome:

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
    "Accept-Language": "es-ES,es;q=0.9,en-US;q=0.8,en;q=0.7",
    "Accept-Encoding": "gzip, deflate, br",
    "DNT": "1",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Cache-Control": "max-age=0",
    "sec-ch-ua": '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Windows"'
}

Presta atención a los encabezados Sec-Fetch-* y sec-ch-ua-*: aparecieron en las nuevas versiones de Chrome y su ausencia puede delatar la automatización.

El orden de los encabezados importa

Los navegadores envían los encabezados en un orden determinado. Por ejemplo, Chrome siempre coloca Host primero, luego Connection, User-Agent y así sucesivamente. Si usas la biblioteca requests de Python, el orden puede ser alfabético, lo que delatará la automatización.

Solución: usa bibliotecas que formen correctamente los encabezados (curl_cffi para Python, got para Node.js) o navegadores headless (Puppeteer, Playwright, Selenium) que generan encabezados como un navegador real.

Retrasos entre solicitudes: intervalos óptimos

Uno de los métodos más simples pero efectivos para reducir el ban rate son los retrasos correctos entre solicitudes. Un usuario real no puede abrir 10 páginas por segundo, por lo que las solicitudes demasiado rápidas provocan bloqueos instantáneos.

Retrasos aleatorios en lugar de fijos

No uses un retraso fijo (por ejemplo, exactamente 2 segundos entre solicitudes). Los sistemas anti-bot identifican fácilmente este patrón. Usa un intervalo aleatorio:

import random
import time

# En lugar de retraso fijo
time.sleep(2)  # ❌ Malo

# Usa un intervalo aleatorio
delay = random.uniform(2.5, 5.5)  # ✅ Bueno
time.sleep(delay)

Intervalos recomendados para diferentes sitios

Tipo de sitio Retraso mínimo Retraso recomendado Ejemplos
Marketplaces con protección 3-5 seg 5-10 seg Wildberries, Ozon, Lamoda
Tablones de anuncios 2-4 seg 4-8 seg Avito, Yula, CIAN
Sitios de noticias 1-2 seg 2-4 seg RBC, Kommersant, Vedomosti
API sin restricciones 0.5-1 seg 1-2 seg APIs abiertas, feeds RSS

Retrasos adaptativos basados en respuestas del servidor

Un enfoque avanzado es cambiar dinámicamente los retrasos según las respuestas del servidor:

base_delay = 3.0  # Retraso base
delay_multiplier = 1.0

response = requests.get(url, headers=headers, proxies=proxies)

# Si recibimos captcha o 429, aumentamos el retraso
if response.status_code == 429 or 'captcha' in response.text.lower():
    delay_multiplier *= 1.5
    print(f"Protección detectada, aumentando retraso a {base_delay * delay_multiplier}s")

# Si todo está bien, podemos acelerar un poco
elif response.status_code == 200:
    delay_multiplier = max(1.0, delay_multiplier * 0.95)

time.sleep(random.uniform(base_delay * delay_multiplier, base_delay * delay_multiplier * 1.5))

Este enfoque permite ralentizar automáticamente al detectar protección y acelerar cuando el sitio no muestra agresividad.

Protección contra fingerprinting: Canvas, WebGL, fuentes

Si el sitio usa JavaScript para verificación, los simples encabezados HTTP no son suficientes. Los sistemas anti-bot modernos crean una "huella digital" del navegador (fingerprint) basada en decenas de parámetros: Canvas, WebGL, fuentes instaladas, zona horaria, resolución de pantalla y otros.

Parámetros principales del fingerprinting

Canvas fingerprinting

El sitio dibuja una imagen invisible en Canvas y la lee. Diferentes navegadores y sistemas operativos renderizan la imagen de manera diferente, creando una huella única. Los navegadores headless a menudo generan el mismo Canvas, lo que delata la automatización.

WebGL fingerprinting

Similar a Canvas, pero usa renderizado 3D. Se lee información sobre la tarjeta gráfica, controladores, extensiones soportadas. Los navegadores headless a menudo muestran renderizado por software (SwiftShader) en lugar de GPU real.

Fuentes instaladas

JavaScript puede determinar la lista de fuentes instaladas. Los navegadores headless suelen tener un conjunto mínimo de fuentes del sistema, lo que difiere de un usuario real con Microsoft Office, Adobe y otros programas instalados.

Propiedades de Navigator

Las propiedades navigator.webdriver, navigator.plugins, navigator.languages delatan la automatización. Por ejemplo, en Selenium navigator.webdriver === true, lo que es detectado instantáneamente por los sistemas anti-bot.

Herramientas para bypass de fingerprinting

Para el bypass de fingerprinting usa herramientas especializadas:

  • Undetected ChromeDriver (Python): versión modificada de Selenium que oculta signos de automatización
  • Puppeteer Stealth (Node.js): plugin para Puppeteer que sustituye parámetros de fingerprint
  • Playwright con stealth: similar a Puppeteer, pero con mejor soporte de diferentes navegadores
  • Navegadores antidetección (Dolphin Anty, AdsPower, Multilogin): para quienes no quieren escribir código, estos navegadores sustituyen automáticamente el fingerprint

Ejemplo de uso de undetected-chromedriver en Python:

import undetected_chromedriver as uc

# Creamos navegador con protección contra detección
options = uc.ChromeOptions()
options.add_argument('--disable-blink-features=AutomationControlled')

driver = uc.Chrome(options=options)
driver.get('https://example.com')

# Verificamos que navigator.webdriver === undefined
webdriver_status = driver.execute_script("return navigator.webdriver")
print(f"navigator.webdriver: {webdriver_status}")  # Debe ser None/undefined

Gestión de cookies y sesiones

Muchos sitios usan cookies para rastrear el comportamiento de los usuarios. La gestión correcta de cookies ayuda a evitar bloqueos y parecer un usuario real.

Guardar y reutilizar cookies

En lugar de crear una nueva sesión en cada solicitud, guarda las cookies y reutilízalas. Esto imita el comportamiento de un usuario real que regresa al sitio:

import requests
import pickle

session = requests.Session()

# Primera visita: obtenemos cookies
response = session.get('https://example.com')

# Guardamos cookies en archivo
with open('cookies.pkl', 'wb') as f:
    pickle.dump(session.cookies, f)

# Más tarde cargamos cookies
with open('cookies.pkl', 'rb') as f:
    session.cookies.update(pickle.load(f))

# Ahora las solicitudes parecen de un usuario que regresa
response = session.get('https://example.com/catalog')

Calentamiento de sesión antes del scraping

No comiences el scraping directamente en las páginas objetivo. Imita el comportamiento de un usuario real:

  1. Abre la página principal del sitio
  2. Espera 2-5 segundos
  3. Abre la página de categoría o sección
  4. Espera 3-7 segundos
  5. Solo después de esto comienza a hacer scraping de las páginas objetivo

Esto crea un historial de actividad en las cookies y reduce la probabilidad de bloqueo.

Manejo de session cookies y tokens

Algunos sitios generan tokens únicos en la primera visita y los verifican en solicitudes posteriores. Por ejemplo, Wildberries usa un token en el encabezado x-requested-with. Siempre guarda estos tokens de la primera respuesta y envíalos en solicitudes posteriores.

Renderizado de JavaScript: cuándo es necesario

Muchos sitios modernos cargan contenido a través de JavaScript. Si usas un cliente HTTP simple (requests en Python, axios en Node.js), obtendrás una página vacía o un placeholder. En estos casos es necesario el renderizado de JavaScript.

Cuándo se necesita renderizado de JavaScript

  • El sitio usa React, Vue, Angular: el contenido se carga después de la carga inicial de la página
  • Los datos se cargan mediante solicitudes AJAX/Fetch
  • El sitio requiere ejecución de JavaScript para generar tokens o cookies
  • Hay protección contra bots que requiere ejecución de código JS (por ejemplo, Cloudflare Challenge)

Herramientas para renderizado de JavaScript

Herramienta Lenguaje Velocidad Bypass de protección
Selenium Python, Java, C# Lenta Medio (con undetected-chromedriver)
Puppeteer Node.js Media Bueno (con puppeteer-extra-plugin-stealth)
Playwright Python, Node.js, Java Rápida Excelente
Splash HTTP API Media Débil

Para la mayoría de las tareas se recomienda Playwright: es más rápido que Selenium, mejor para bypass de protección y tiene una API más conveniente.

Alternativa: interceptar solicitudes API

A menudo se puede evitar el renderizado de JavaScript si encuentras las solicitudes API que el sitio usa para cargar datos. Abre DevTools (F12) → pestaña Network → filtro XHR/Fetch y mira qué solicitudes envía el sitio. Luego repite estas solicitudes directamente a través del cliente HTTP.

Ejemplo: Wildberries carga datos de productos a través de la API https://catalog.wb.ru/catalog/.... En lugar de renderizar toda la página, puedes solicitar esta API directamente, lo que es 10-20 veces más rápido.

Bypass de captcha: soluciones automáticas

Incluso con proxies y encabezados correctos puedes encontrarte con captcha. Existen varios enfoques para resolverla:

Tipos de captcha y métodos de resolución

reCAPTCHA v2 (casilla "No soy un robot")

Se resuelve mediante servicios de reconocimiento: 2Captcha, Anti-Captcha, CapMonster. Costo: $1-3 por 1000 resoluciones. Tiempo de resolución: 10-30 segundos.

reCAPTCHA v3 (invisible, basada en puntuación)

Más compleja. Analiza el comportamiento del usuario y asigna una puntuación de 0 a 1. Bypass: uso de navegadores headless con fingerprint correcto + imitación de acciones del usuario (movimiento del ratón, clics).

hCaptcha

Análogo a reCAPTCHA, usado en muchos sitios. Se resuelve mediante los mismos servicios de reconocimiento. Costo: $0.5-2 por 1000 resoluciones.

Cloudflare Challenge

JavaScript-challenge que verifica el navegador. Bypass: uso de bibliotecas especializadas (cloudscraper para Python, cloudflare-scraper para Node.js) o servicios (FlareSolverr).

Integración de servicio de reconocimiento de captcha

Ejemplo de integración de 2Captcha en Python:

from twocaptcha import TwoCaptcha

solver = TwoCaptcha('YOUR_API_KEY')

try:
    # Resolvemos reCAPTCHA v2
    result = solver.recaptcha(
        sitekey='6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
        url='https://example.com'
    )
    
    # Obtenemos token de resolución
    captcha_token = result['code']
    
    # Enviamos formulario con token
    response = requests.post('https://example.com/submit', data={
        'g-recaptcha-response': captcha_token
    })
    
except Exception as e:
    print(f"Error al resolver captcha: {e}")

Importante: Resolver captcha ralentiza el scraping 10-30 veces y aumenta el costo. Úsalo solo cuando otros métodos no funcionen. Primero intenta mejorar los proxies, fingerprint y retrasos.

Rate limiting: cómo no exceder los límites del sitio

Muchos sitios tienen límites explícitos o implícitos en el número de solicitudes. Exceder estos límites lleva a bloqueo temporal o permanente de la IP.

Determinación de límites del sitio

Presta atención a los encabezados HTTP en las respuestas del servidor:

  • X-RateLimit-Limit: número máximo de solicitudes en el período
  • X-RateLimit-Remaining: cuántas solicitudes quedan
  • X-RateLimit-Reset: cuándo se restablecerá el límite (Unix timestamp)
  • Retry-After: en cuántos segundos se puede repetir la solicitud

Si recibes el código de estado 429 (Too Many Requests), significa que se excedió el límite. Lee el encabezado Retry-After y espera el tiempo indicado antes de la siguiente solicitud.

Implementación de rate limiter

Crea un mecanismo de control de velocidad de solicitudes:

```