Casos de Uso

Recopilación de datos del sitio minorista con manejo de CAPTCHA

Si extraes precios o stock de Amazon, tarde o temprano tu scraper recibirá una imagen de texto distorsionado en lugar de la página del producto: es el CAPTCHA de imagen de Amazon. Para no frenar el pipeline, el flujo se reduce a tres pasos:

  • Detectar la página de CAPTCHA dentro de la respuesta HTML.
  • Resolver la imagen con la resolución OCR de CaptchaAI (method=base64).
  • Reenviar el formulario en la misma sesión y seguir extrayendo datos.

Qué necesitas antes de empezar

Requisito Detalles
Clave API de CaptchaAI Desde captchaai.com
Python 3.7+ Con requests y beautifulsoup4
Proxies con buena reputación Recomendados para scraping sostenido

Con la clave API y las dependencias instaladas, solo queda entender cuándo salta el CAPTCHA y automatizar su resolución.

Cuándo aparece el CAPTCHA de Amazon

Amazon no muestra el CAPTCHA al azar: lo activa cuando tu tráfico se parece al de un bot. Estas son las señales que más pesan:

Señal Descripción
Volumen de solicitudes Demasiadas solicitudes desde una misma IP en poco tiempo
Cookies ausentes Sin cookies de sesión de Amazon
Encabezados sospechosos User-Agent tipo bot o encabezados incompletos
Reputación de la IP Rangos de IP de proxies o centros de datos conocidos

Cuando alguna se dispara, Amazon te redirige a una página con una imagen de texto distorsionado y un campo de entrada; para continuar, tienes que leer la imagen y enviar el texto correcto.

Resolver el CAPTCHA de imagen de Amazon paso a paso

Paso 1: detectar la página de CAPTCHA

Distingue un producto de un muro de CAPTCHA con una comprobación sobre el HTML:

import requests
from bs4 import BeautifulSoup

session = requests.Session()
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
})

def is_captcha_page(html):
    return "Type the characters you see in this image" in html or \
           "captcha" in html.lower()

url = "https://www.amazon.com/dp/B0EXAMPLE"
resp = session.get(url)

if is_captcha_page(resp.text):
    print("CAPTCHA detected!")
else:
    print("Page loaded successfully")

Paso 2: extraer y resolver la imagen

Codificas la imagen en base64, la envías al endpoint in.php y consultas el resultado en res.php hasta que esté listo:

import base64

API_KEY = "YOUR_API_KEY"

def solve_amazon_captcha(session, captcha_page_html, captcha_page_url):
    soup = BeautifulSoup(captcha_page_html, "html.parser")

    # Find the CAPTCHA image
    img_tag = soup.find("img", src=lambda s: s and "captcha" in s.lower())
    if not img_tag:
        raise Exception("CAPTCHA image not found")

    img_url = img_tag["src"]

    # Download the image
    img_resp = session.get(img_url)
    img_base64 = base64.b64encode(img_resp.content).decode()

    # Submit to CaptchaAI
    submit_resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY,
        "method": "base64",
        "body": img_base64
    })
    task_id = submit_resp.text.split("|")[1]

    # Poll for result
    import time
    for _ in range(30):
        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(f"Solve error: {result.text}")

    raise TimeoutError("Solve timed out")

Paso 3: enviar la solución

Con el texto resuelto, reconstruyes el formulario y haces POST en la misma sesión para conservar las cookies:

def submit_captcha_solution(session, captcha_page_html, solution, captcha_page_url):
    soup = BeautifulSoup(captcha_page_html, "html.parser")
    form = soup.find("form")

    # Build form data
    form_data = {}
    for inp in form.find_all("input"):
        name = inp.get("name")
        if name:
            form_data[name] = inp.get("value", "")

    # Set the CAPTCHA answer
    form_data["field-keywords"] = solution

    # Submit
    action = form.get("action", captcha_page_url)
    if action.startswith("/"):
        from urllib.parse import urljoin
        action = urljoin(captcha_page_url, action)

    resp = session.post(action, data=form_data)
    return resp

Ejemplo completo de scraping con manejo de CAPTCHA

Las tres piezas juntas, de punta a punta: el código pide la página, resuelve el CAPTCHA cuando aparece y devuelve el título y el precio del producto.

import requests
import base64
import time
from bs4 import BeautifulSoup

API_KEY = "YOUR_API_KEY"

def scrape_amazon_product(url):
    session = requests.Session()
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        "Accept-Language": "en-US,en;q=0.9"
    })

    resp = session.get(url)

    # Handle CAPTCHA if present
    if "captcha" in resp.text.lower():
        soup = BeautifulSoup(resp.text, "html.parser")
        img = soup.find("img", src=lambda s: s and "captcha" in s.lower())

        if img:
            # Download and solve
            img_data = session.get(img["src"]).content
            img_b64 = base64.b64encode(img_data).decode()

            submit = requests.get("https://ocr.captchaai.com/in.php", params={
                "key": API_KEY, "method": "base64", "body": img_b64
            })
            task_id = submit.text.split("|")[1]

            for _ in range(30):
                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|"):
                    solution = result.text.split("|")[1]
                    break

            # Submit solution
            form = soup.find("form")
            form_data = {inp.get("name"): inp.get("value", "")
                        for inp in form.find_all("input") if inp.get("name")}
            form_data["field-keywords"] = solution

            action = form.get("action", url)
            resp = session.post(action, data=form_data)

    # Parse product data
    soup = BeautifulSoup(resp.text, "html.parser")
    title = soup.find("span", {"id": "productTitle"})
    price = soup.find("span", class_="a-price-whole")

    return {
        "title": title.text.strip() if title else None,
        "price": price.text.strip() if price else None
    }

product = scrape_amazon_product("https://www.amazon.com/dp/B0EXAMPLE")
print(product)

Buenas prácticas para hacer scraping de Amazon

  • Usa proxies con buena reputación: Amazon bloquea de forma agresiva las IP de centros de datos.
  • Rota los User-Agent: usa cadenas de navegador realistas.
  • Conserva la sesión: reutiliza las cookies entre solicitudes.
  • Añade pausas: de 3 a 10 segundos entre solicitudes.
  • Envía Accept-Language: incluye los encabezados de idioma y región.
  • No hagas scraping con sesión iniciada: las páginas de producto son accesibles sin login.

Errores frecuentes y cómo resolverlos

La mayoría de los bloqueos se evitan con disciplina de ritmo: mantén una sola sesión por hilo, reutiliza sus cookies y deja pausas variables entre solicitudes. Cuando aun así aparece el CAPTCHA, esta tabla cubre los tropiezos más comunes.

Problema Solución
CAPTCHA en cada solicitud Usa proxies con buena reputación; baja la frecuencia de solicitudes
Solución de CAPTCHA rechazada Verifica que la imagen se descargó bien; reintenta
Bucles de redirección Revisa el manejo de cookies; usa allow_redirects=True
Datos de producto vacíos Amazon puede servir diseños distintos; revisa tus selectores

Escenario: monitoreo de precios para una agencia

Una agencia de Ciudad de México vigila precios de vendedores en Amazon para sus clientes: factura en pesos pero paga sus herramientas en USD, así que le conviene un costo mensual predecible frente al pago por resolución. Con un plan como BASIC ($15/mes, 5 threads) resuelve los CAPTCHA sin pagar por cada imagen y escala threads cuando suma tiendas.

Preguntas frecuentes

¿Puedo resolver el CAPTCHA de imagen de Amazon sin abrir un navegador?

Sí. Todo el flujo funciona con requests y la API OCR (method=base64): descargas la imagen y envías el texto resuelto al formulario, sin Selenium ni Puppeteer.

¿Con qué plan de CaptchaAI conviene empezar para monitorear precios?

Depende de tu volumen. BASIC ($15/mes, 5 threads) cubre un scraper pequeño con resoluciones ilimitadas por thread; sube de plan si corres varias tiendas en paralelo.

¿Por qué me aparece un CAPTCHA en casi todas las solicitudes?

Suele ser reputación de la IP o falta de cookies de sesión. Reduce la frecuencia, reutiliza la sesión con sus cookies y mejora tus proxies.

Extraer datos de productos públicos suele ser legal, pero revisa los términos de servicio de Amazon y la normativa de protección de datos de tu jurisdicción.

Guías relacionadas

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