Manejar CAPTCHAs al hacer scraping

Tipos de CAPTCHA, estrategias de prevención que son más eficaces que resolver, y el papel crítico de los proxies en la evitación de CAPTCHA. Ejemplos de código para detección y enrutamiento.

Manejar CAPTCHAs al hacer scraping

Por qué CAPTCHAS Son los Obstáculos más Grandes del Raspador

Los CAPTCHAs existen para distinguir a los humanos de los bots, y son cada vez más eficaces en ello. Cuando su rascador encuentra un CAPTCHA, significa que el sitio de destino ha detectado comportamiento automatizado: su frecuencia de solicitud era demasiado alta, su IP tiene baja confianza, o su huella de navegador parecía sospechosa. La mejor estrategia de CAPTCHA es la prevención, no la solución.

Esta guía cubre los tipos de CAPTCHAs que encontrará, por qué la prevención es más eficaz y más barata que la solución, y cómo los proxies juegan un papel crítico en evitar completamente CAPTCHAs.

Este artículo es parte de nuestro Guía completa de Proxies de Rastreo Web serie. Para entender los sistemas de detección, consulte Cómo los sistemas anticuerpos detectan proxies.

Tipos de CAPTCHA en 2026

Tipos de CAPTCHA en 2026
TipoCómo funcionaDificultad para pasar
reCAPTCHA v2 (checkbox)Haga clic en "No soy un robot" + desafío opcional de imagenMediana
reCAPTCHA v3 (invisible)Comportamiento de puntuación 0.0-1.0 sin interacción del usuarioDuro
hCaptchaProblemas de selección de imágenes (similar a reCAPTCHA v2)Mediana
Cloudflare TurnstileDesafío del navegador, generalmente invisibleDuro
Imagen personalizada CAPTCHAProblemas específicos del sitio (texto distorsionado, rompecabezas)Variable
Prueba de trabajoEl navegador debe calcular un hash (Cloudflare Under Attack)Mediana

CAPTCHAs invisibles Son la amenaza real

Los CAPTCHAs más peligrosos para raspadores son los que nunca ves. reCAPTCHA v3 y Cloudflare Turnstile ejecutar en el fondo, analizar los movimientos del ratón, comportamiento de desplazamiento, patrones de escritura y entorno del navegador. asignan una puntuación de confianza sin mostrar ningún reto, y si la puntuación es demasiado baja, la solicitud está bloqueada o redirigida silenciosamente.

Prevención vs Solución: Por qué gana la prevención

Prevención vs Solución: Por qué gana la prevención
EnfoqueCosto por CAPTCHASpeedConfiabilidadEscalabilidad
Prevención (no se activaron CAPTCHAs)$0Instant InstantMás altoExcelente
CAPTCHA resolviendo servicios1-3 por 1.000 dólares10-60 segundos85-95%Moderado
Ais-based auto-solving2-5 por 1.000 dólares5-30 segundos70-90%Limited
A escala, la prevención ahorra dinero y tiempo. Solver 100.000 CAPTCHAs por día cuesta $100-500 y añade horas de latencia. Impedirlos no cuesta nada más que una gestión adecuada y de solicitud.

Estrategia de prevención 1: Utilizar ejes residenciales de alta calidad

La medida de prevención más eficaz de CAPTCHA es el uso de proxies residenciales con altas puntuaciones de confianza. Los IPs residenciales son asignados a hogares reales por los ISP, por lo que los sitios web no pueden distinguir fácilmente sus solicitudes de tráfico de usuarios genuino.

import requests
# Residential proxy — high trust score, fewer CAPTCHAs
PROXY = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
def scrape_with_residential(url: str) -> str:
    """Use residential proxies to avoid triggering CAPTCHAs."""
    session = requests.Session()
    session.proxies = {"http": PROXY, "https": PROXY}
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/120.0.0.0 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",
    })
    resp = session.get(url, timeout=30)
    return resp.text

La piscina residencial de ProxyHat proporciona IPs de ISP reales en 190 países, dando a cada solicitud la mayor puntuación de confianza posible. See Residencial vs Datacenter Proxies for Scraping para una comparación detallada.

Estrategia de prevención 2: Patrones de solicitud realistas

CAPTCHAs son a menudo desencadenados por patrones de comportamiento robóticos, no sólo reputación IP. Haz que tu raspador parezca humano:

Python Implementation

import requests
import random
import time
PROXY = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 Safari/605.1.15",
]
REFERRERS = [
    "https://www.google.com/",
    "https://www.bing.com/",
    "https://duckduckgo.com/",
    None,  # Direct visit
]
def human_like_scrape(urls: list[str]) -> list[str]:
    """Scrape with realistic human behavior patterns."""
    results = []
    session = requests.Session()
    session.proxies = {"http": PROXY, "https": PROXY}
    for url in urls:
        # Randomize headers per request
        headers = {
            "User-Agent": random.choice(USER_AGENTS),
            "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",
            "Connection": "keep-alive",
            "Upgrade-Insecure-Requests": "1",
        }
        referrer = random.choice(REFERRERS)
        if referrer:
            headers["Referer"] = referrer
        try:
            resp = session.get(url, headers=headers, timeout=30)
            results.append(resp.text)
        except requests.RequestException:
            results.append(None)
        # Human-like delays: 1-5 seconds with occasional longer pauses
        if random.random() < 0.1:
            time.sleep(random.uniform(5, 15))  # 10% chance of long pause
        else:
            time.sleep(random.uniform(1, 4))
    return results

Node.js Implementation

const HttpsProxyAgent = require('https-proxy-agent');
const fetch = require('node-fetch');
const agent = new HttpsProxyAgent('http://USERNAME:PASSWORD@gate.proxyhat.com:8080');
const USER_AGENTS = [
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
];
function randomDelay() {
  const isLongPause = Math.random() < 0.1;
  const ms = isLongPause
    ? 5000 + Math.random() * 10000
    : 1000 + Math.random() * 3000;
  return new Promise(r => setTimeout(r, ms));
}
async function humanLikeScrape(urls) {
  const results = [];
  for (const url of urls) {
    const headers = {
      'User-Agent': USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)],
      'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
      'Accept-Language': 'en-US,en;q=0.9',
    };
    try {
      const res = await fetch(url, { agent, headers, timeout: 30000 });
      results.push(await res.text());
    } catch {
      results.push(null);
    }
    await randomDelay();
  }
  return results;
}

Estrategia de prevención 3: Rotación IP inteligente

La forma en que giras IPs afecta directamente las tasas de CAPTCHA. La rotación agresiva (nueva IP cada solicitud) puede aumentar realmente CAPTCHAs en algunos sitios, porque una serie de solicitudes de diferentes IPs que acceden a la misma ruta de sesión parece sospechosa.

import requests
import uuid
def create_session_for_site(site_id: str):
    """Create a sticky session that maintains the same IP per site.
    This avoids the suspicious pattern of different IPs accessing the same flow."""
    session_id = uuid.uuid5(uuid.NAMESPACE_URL, site_id).hex[:8]
    proxy = f"http://USERNAME-session-{session_id}:PASSWORD@gate.proxyhat.com:8080"
    session = requests.Session()
    session.proxies = {"http": proxy, "https": proxy}
    return session
# Same IP for all requests to a specific product section
session = create_session_for_site("example.com-electronics")
page1 = session.get("https://example.com/electronics?page=1")
page2 = session.get("https://example.com/electronics?page=2")
page3 = session.get("https://example.com/electronics?page=3")
# Different IP for a different section
session2 = create_session_for_site("example.com-clothing")
clothes1 = session2.get("https://example.com/clothing?page=1")

Para más patrones de rotación, vea Estrategias de Rotación Proxy para Raspado de Escala Grande.

Estrategia de prevención 4: Límites de la tasa de respeto

Los CAPTCHA son a menudo la escalada después de la limitación de tarifas. Si maneja correctamente las señales límite de velocidad, rara vez ve CAPTCHAs:

import requests
import time
PROXY = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
CAPTCHA_INDICATORS = [
    "captcha",
    "recaptcha",
    "hcaptcha",
    "challenge",
    "verify you are human",
    "please complete the security check",
]
def is_captcha_page(html: str) -> bool:
    """Detect if the response is a CAPTCHA challenge page."""
    html_lower = html.lower()
    return any(indicator in html_lower for indicator in CAPTCHA_INDICATORS)
def scrape_with_captcha_detection(urls: list[str]) -> list[dict]:
    results = []
    session = requests.Session()
    session.proxies = {"http": PROXY, "https": PROXY}
    captcha_count = 0
    backoff = 2.0
    for url in urls:
        try:
            resp = session.get(url, timeout=30)
            if resp.status_code == 200 and not is_captcha_page(resp.text):
                results.append({"url": url, "status": "success", "body": resp.text})
                captcha_count = 0
                backoff = max(backoff * 0.9, 1.0)  # Reduce backoff on success
            elif is_captcha_page(resp.text) or resp.status_code == 403:
                captcha_count += 1
                results.append({"url": url, "status": "captcha"})
                if captcha_count >= 3:
                    # Too many CAPTCHAs — increase backoff significantly
                    backoff = min(backoff * 3, 60)
                    print(f"CAPTCHA streak: {captcha_count}. Backing off to {backoff:.0f}s")
                else:
                    backoff = min(backoff * 1.5, 30)
        except requests.RequestException as e:
            results.append({"url": url, "status": "error", "error": str(e)})
        time.sleep(backoff)
    return results

Para estrategias globales de límite de tarifas, véase Límites de la tasa de rachado Explicados.

Cuando usted debe manejar CAPTCHAs: Detección y Routing

Incluso con una prevención perfecta, algunos CAPTCHA son inevitables. Construya la detección en su oleoducto para que pueda trazar las páginas de CAPTCHA para un manejo especial:

import requests
from enum import Enum
PROXY = "http://USERNAME:PASSWORD@gate.proxyhat.com:8080"
class ResponseType(Enum):
    SUCCESS = "success"
    CAPTCHA = "captcha"
    BLOCKED = "blocked"
    ERROR = "error"
def classify_response(resp: requests.Response) -> ResponseType:
    """Classify a response to determine next action."""
    if resp.status_code == 403:
        return ResponseType.BLOCKED
    if resp.status_code == 429:
        return ResponseType.BLOCKED
    if resp.status_code == 200:
        html = resp.text.lower()
        captcha_signals = ["captcha", "recaptcha", "hcaptcha", "cf-challenge"]
        if any(s in html for s in captcha_signals):
            return ResponseType.CAPTCHA
        return ResponseType.SUCCESS
    return ResponseType.ERROR
def scrape_with_routing(urls: list[str]) -> dict:
    """Scrape URLs and route based on response classification."""
    session = requests.Session()
    session.proxies = {"http": PROXY, "https": PROXY}
    results = {"success": [], "captcha": [], "blocked": [], "error": []}
    for url in urls:
        try:
            resp = session.get(url, timeout=30)
            response_type = classify_response(resp)
            results[response_type.value].append(url)
            if response_type == ResponseType.CAPTCHA:
                # Route to CAPTCHA queue for manual or service-based solving
                print(f"CAPTCHA detected: {url}")
            elif response_type == ResponseType.BLOCKED:
                # Rotate IP and retry
                print(f"Blocked: {url}")
        except requests.RequestException:
            results["error"].append(url)
    print(f"Success: {len(results['success'])}, "
          f"CAPTCHAs: {len(results['captcha'])}, "
          f"Blocked: {len(results['blocked'])}")
    return results

Lista de verificación de prevención de CAPTCHA

  • Use proxies residenciales. Tienen los puntajes de confianza más altos y desencadenan los CAPTCHAs más pocos. ProxyHat proxies residenciales proporcionar millones de IPs limpias.
  • Establece encabezados realistas. Enviar siempre Usuario-Agent, Aceptar, Aceptar-Idioma y otros encabezados estándar del navegador.
  • Agregue retrasos como humanos. Random 1-5 segundos retrasos entre solicitudes con pausas ocasionales más largas.
  • Mantener las sesiones correctamente. Utilice cookies y IPs consistentes para solicitudes relacionadas a través de sesiones pegajosas.
  • Respetar robots.txt. Los sitios que detectan violaciones robots.txt aumentan a CAPTCHAs más rápido.
  • Supervisar las tasas de CAPTCHA. Si su tasa de CAPTCHA supera el 5%, algo en su enfoque necesita fijarse.
  • Evite raspar durante horas pico. Los sistemas antibots son más agresivos durante períodos de alto tráfico.
  • Rotar el usuario-agentes correctamente. Use cadenas de navegador recientes y realistas. No mezcle UAs móviles y de escritorio en la misma sesión.

Para la configuración proxy en su idioma preferido, vea Utilizando Proxies en Python, Utilizando Proxies en Node.jso Usando Proxies en Go. Explore ProxyHat for Web Scraping para empezar.

Preguntas frecuentes

¿Pueden los proxies ayudar a evitar CAPTCHAs?

Sí, significativamente. Los proxies residenciales de alta calidad tienen reputación IP limpia que rara vez desencadenan CAPTCHAs. Los IPs del centro de datos se marcan más a menudo porque son conocidos fuentes automatizadas. La combinación de proxies residenciales con patrones de solicitud adecuados elimina virtualmente CAPTCHAs para la mayoría de los objetivos.

¿Cuál es la forma más barata de manejar CAPTCHAs a escala?

Prevención. Invertir en proxies residenciales y patrones de raspado adecuados cuesta mucho menos que los servicios de resolución CAPTCHA a escala. Si usted debe resolver CAPTCHAs, los servicios de terceros cuestan $1-3 por 1.000 pero añadir 10-60 segundos de latencia por solicitud.

¿Los navegadores sin cabeza ayudan con CAPTCHAs?

Ayudan con CAPTCHAs invisibles (reCAPTCHA v3, Turnstile) proporcionando un entorno de navegador real con ejecución JavaScript. Sin embargo, son más lentos y más intensivos en recursos. Úsalos sólo para objetivos que requieren específicamente la verificación del nivel del navegador.

¿Cómo sé si estoy recibiendo páginas de CAPTCHA?

Compruebe la respuesta HTML para los indicadores de CAPTCHA: "captcha", "recaptcha", "hcaptcha", "challenge", o "verify you are human". También busque respuestas inesperadas 403 y redirige a desafiar URLs. Construya la detección automatizada en su tubería de desguace.

¿Por qué todavía tengo CAPTCHAs con proxies residenciales?

Por lo general debido a patrones de solicitud, no calidad IP. Causas comunes: demasiadas solicitudes por minuto, cabeceras faltantes del navegador, problemas de manejo de cookies o patrones de raspado que son demasiado sistemáticos. Despacio, añade jitter y usa sesiones pegajosas para solicitudes relacionadas.

¿Listo para empezar?

Accede a más de 50M de IPs residenciales en más de 148 países con filtrado impulsado por IA.

Ver preciosProxies residenciales
← Volver al Blog