Casos de Uso

Rotación de proxies para scraping con menos CAPTCHA

¿Tu scraper se topa con un CAPTCHA cada pocas páginas? Casi nunca es culpa del código: envías todo el tráfico desde una sola IP y el sitio lo detecta enseguida. Rotar proxies reparte esas solicitudes entre muchas direcciones para que ningún patrón por IP resulte sospechoso, y cuando aun así aparece un CAPTCHA, CaptchaAI lo resuelve por API sin frenar el flujo.

Un caso real: monitorear precios en marketplaces regionales

Imagina una agencia en Ciudad de México que sigue los precios de miles de productos en varios marketplaces de la región. Desde una sola IP, el sitio responde con CAPTCHA en minutos. Con un grupo de proxies cuya geografía coincide con cada dominio nacional, el tráfico parece de usuarios locales, la frecuencia de CAPTCHA cae y los pocos que se cuelan los resuelve CaptchaAI por API, con un costo mensual predecible en USD en vez de pagar por resolución.

Trabaja siempre sobre objetivos propios o autorizados y respeta los términos de servicio y la normativa de protección de datos aplicable (GDPR y LOPDGDD en España, LFPDPPP en México).

Qué dispara un CAPTCHA cuando usas una sola IP

Los sitios no bloquean al azar. Vigilan un puñado de señales por dirección y, cuando una IP se sale de lo normal, muestran el desafío:

  • Solicitudes por minuto: pasar de 10 seguidas desde la misma IP suele bastar para disparar el CAPTCHA.
  • Reputación de la IP: se degrada a medida que la dirección acumula actividad automatizada.
  • Patrones de sesión: un comportamiento repetitivo y sin pausas delata al bot.
  • Coherencia geográfica: todo el tráfico saliendo de una única ubicación resulta poco natural.

Cómo la rotación reparte esa carga

Al distribuir las solicitudes entre varias IP, cada dirección se mantiene por debajo de esos umbrales: menos solicitudes por minuto, reputación fresca en cada IP del grupo, patrones diluidos y una diversidad geográfica que se parece más al tráfico humano. El resultado es una frecuencia de CAPTCHA mucho más baja sin tocar la lógica del scraper.

Qué tipo de proxy elegir según el objetivo

No todos los proxies cuestan ni rinden igual; la elección depende de lo agresivo que sea el sistema anti-bot del sitio:

Tipo Mejor para Frecuencia de CAPTCHA Costo
Residencial Objetivos exigentes (Google, Amazon) Más baja $$$
Móvil Detección mínima Más baja $$$$
ISP/estático Sesiones prolongadas Baja $$
Centro de datos Sitios tolerantes y de gran volumen Más alta $

Recomendación: para sitios con disparadores de CAPTCHA agresivos, usa proxies residenciales autorizados. Los de centro de datos rinden bien en sitios menos protegidos y salen mucho más baratos.

Rotación básica de proxies en Python

El patrón mínimo elige un proxy al azar en cada solicitud y, si detecta un CAPTCHA en la respuesta, lo envía a CaptchaAI para obtener el token:

import requests
import random
import time

PROXIES = [
    "http://user:pass@proxy1.example.com:8080",
    "http://user:pass@proxy2.example.com:8080",
    "http://user:pass@proxy3.example.com:8080",
]

API_KEY = "YOUR_API_KEY"

def get_random_proxy():
    proxy = random.choice(PROXIES)
    return {"http": proxy, "https": proxy}

def scrape_with_rotation(url):
    proxy = get_random_proxy()
    session = requests.Session()
    session.proxies = proxy
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
    })

    resp = session.get(url)

    # If CAPTCHA appears, solve it
    if "g-recaptcha" in resp.text or "captcha" in resp.text.lower():
        from bs4 import BeautifulSoup
        soup = BeautifulSoup(resp.text, "html.parser")
        rc = soup.find("div", class_="g-recaptcha")
        if rc:
            site_key = rc["data-sitekey"]
            token = solve_captcha(site_key, url)
            resp = session.post(url, data={"g-recaptcha-response": token})

    return resp.text

def solve_captcha(site_key, page_url):
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY, "method": "userrecaptcha",
        "googlekey": site_key, "pageurl": page_url
    })
    task_id = resp.text.split("|")[1]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id
        })
        if result.text == "CAPCHA_NOT_READY": continue
        if result.text.startswith("OK|"): return result.text.split("|")[1]
        raise Exception(result.text)
    raise TimeoutError()

Rotación inteligente: prioriza las IP limpias

No todos los proxies rinden igual dentro del mismo grupo. Conviene un rotador que aprenda cuáles funcionan:

  • Cuenta cuántos CAPTCHA recibe cada proxy.
  • Calcula una tasa de éxito por IP.
  • Da preferencia a la mitad mejor valorada al elegir la siguiente dirección.
from collections import defaultdict
import random

class SmartProxyRotator:
    def __init__(self, proxies):
        self.proxies = proxies
        self.captcha_count = defaultdict(int)
        self.success_count = defaultdict(int)

    def get_proxy(self):
        # Prefer proxies with lower CAPTCHA rates
        scored = []
        for proxy in self.proxies:
            total = self.captcha_count[proxy] + self.success_count[proxy]
            if total == 0:
                score = 0.5  # Unknown proxy, neutral score
            else:
                score = self.success_count[proxy] / total
            scored.append((proxy, score))

        # Weight selection by score
        scored.sort(key=lambda x: x[1], reverse=True)
        top_proxies = scored[:max(len(scored) // 2, 1)]
        proxy = random.choice(top_proxies)[0]
        return proxy

    def report_success(self, proxy):
        self.success_count[proxy] += 1

    def report_captcha(self, proxy):
        self.captcha_count[proxy] += 1

# Usage
rotator = SmartProxyRotator(PROXIES)

def scrape(url):
    proxy = rotator.get_proxy()
    resp = requests.get(url, proxies={"http": proxy, "https": proxy})

    if "captcha" in resp.text.lower():
        rotator.report_captcha(proxy)
        # Solve CAPTCHA...
    else:
        rotator.report_success(proxy)

    return resp.text

Rotación de proxies con Selenium

Cuando necesitas un navegador real, asigna un proxy distinto a cada sesión al crear el driver:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def create_driver_with_proxy(proxy_url):
    options = Options()
    options.add_argument(f"--proxy-server={proxy_url}")
    return webdriver.Chrome(options=options)

# Rotate proxy per session
proxy = random.choice(PROXIES)
driver = create_driver_with_proxy(proxy)
driver.get("https://example.com")

Proxy + resolución de CAPTCHA para Cloudflare Challenge

Cloudflare Challenge es el caso especial: el resultado queda ligado a la IP, así que hay que pasarle a CaptchaAI el mismo proxy con el que navegarás después:

proxy = "http://user:pass@proxy.example.com:8080"

resp = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": API_KEY,
    "method": "cloudflare_challenge",
    "pageurl": "https://example.com",
    "proxy": proxy,
    "proxytype": "HTTP"
})
task_id = resp.text.split("|")[1]

# Poll for qa_validation_cookie cookie
# Use the same proxy for subsequent requests

Problemas frecuentes y cómo resolverlos

Estos son los tropiezos más habituales al montar la rotación y su solución directa:

Problema Solución
Todos los proxies reciben CAPTCHA Cambia a proxies residenciales autorizados; baja la frecuencia
Errores de tiempo de espera del proxy Quita del grupo los proxies lentos; sube el tiempo de espera
Contenido distinto según el proxy Algunos sitios sirven contenido geolocalizado; normaliza la salida
El token de CAPTCHA no funciona con el proxy Asegúrate de usar el token desde la misma sesión/IP

Buenas prácticas que evitan bloqueos

  • Haz coincidir la geografía: usa IP del mismo país que el sitio objetivo.
  • Una sesión por proxy: no reutilices una misma sesión entre proxies distintos.
  • Limita la frecuencia por IP: entre 5 y 10 solicitudes por minuto como máximo.
  • Vigila la tasa de CAPTCHA: registra qué proxies disparan más desafíos y descártalos.
  • Mantén sesiones fijas: conserva el mismo proxy en flujos de varios pasos.
  • Gestiona los fallos: reintenta con otro proxy ante errores de conexión.

Preguntas frecuentes

¿La rotación de proxies elimina los CAPTCHA por completo?

No. Reduce mucho la frecuencia con la que aparecen, pero algunos sitios los muestran de todas formas. Por eso conviene combinar la rotación con CaptchaAI, que resuelve por API los que se cuelan.

¿Qué tipo de proxy genera menos CAPTCHA?

Los proxies residenciales y móviles disparan menos CAPTCHA porque las IP parecen de usuarios reales; los de centro de datos son más baratos, pero levantan más sospechas en sitios muy protegidos.

¿Debo usar la misma IP para resolver el CAPTCHA y para el scraping?

Depende del tipo. Para la mayoría, el token vale sin importar la IP. Para Cloudflare Challenge sí: la cookie qa_validation_cookie queda ligada a la IP, así que usa el mismo proxy en toda la sesión.

¿Cuánto cuesta resolver los CAPTCHA que aún aparecen?

CaptchaAI cobra por threads en paralelo, no por resolución. El plan BASIC ($15/mes, 5 threads) cubre un scraping moderado con solves ilimitados; escala los threads cuando crezca el volumen.

Guías relacionadas

Los comentarios están deshabilitados para este artículo.