Casos de Uso

Manejo de CAPTCHA de Bot de automatización con CaptchaAI

Cuando un bot de automatización se topa con un CAPTCHA, el flujo se detiene y hay que resolverlo a mano. La solución es delegar el desafío a una API: envías el CAPTCHA a CaptchaAI, recuperas el token resuelto y tu bot continúa solo. En esta guía montamos un framework reutilizable —en Python y Node.js— que resuelve reCAPTCHA, Cloudflare Turnstile e imagen CAPTCHA dentro de tareas repetitivas: envío de formularios, registro de cuentas, reservas y captura de datos.

Cómo delega un bot la resolución del CAPTCHA

El patrón es siempre el mismo, sin importar el tipo de CAPTCHA:

  1. Detectas el CAPTCHA en la página y extraes su sitekey.
  2. Envías el sitekey y la URL a CaptchaAI con el método adecuado.
  3. Sondeas el resultado hasta que la API devuelve el token resuelto.
  4. Inyectas el token en el formulario y completas el envío.

Ese ciclo —detectar, enviar, sondear, inyectar— es lo que vamos a encapsular en una sola clase.

Dónde aparecen los CAPTCHA en un bot de automatización

El método de la API depende del tipo de CAPTCHA que aparezca en cada flujo:

Escenario CAPTCHA habitual Método de CaptchaAI
Envío de formularios reCAPTCHA v2 method=userrecaptcha
Registro de cuentas reCAPTCHA v2/v3 method=userrecaptcha
Portales de captura de datos CAPTCHA de imagen method=base64
Reservas y citas Cloudflare Turnstile method=turnstile
Acceso a una API protegida Cloudflare Challenge method=cloudflare_challenge

Cambia el método según la fila; el resto del flujo —enviar y sondear— es idéntico en todos los casos.

Un framework de bot reutilizable en Python

Encapsula el ciclo completo en una sola clase que todas tus tareas reutilicen:

import requests
import time
import logging

logger = logging.getLogger(__name__)

class CaptchaBot:
    def __init__(self, api_key):
        self.api_key = api_key
        self.session = requests.Session()
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        })

    def solve(self, method, **params):
        """Solve any CAPTCHA type."""
        params["key"] = self.api_key
        params["method"] = method

        resp = requests.get("https://ocr.captchaai.com/in.php", params=params)
        if not resp.text.startswith("OK|"):
            raise Exception(f"Submit error: {resp.text}")

        task_id = resp.text.split("|")[1]
        logger.info(f"Task submitted: {task_id}")

        for _ in range(60):
            time.sleep(5)
            result = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": self.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"Error: {result.text}")

        raise TimeoutError("CAPTCHA solve timed out")

    def submit_form(self, url, form_data, captcha_field="g-recaptcha-response",
                    site_key=None, captcha_method="userrecaptcha"):
        """Submit a form with CAPTCHA solving."""
        if site_key:
            if captcha_method == "userrecaptcha":
                token = self.solve(captcha_method, googlekey=site_key, pageurl=url)
            elif captcha_method == "turnstile":
                token = self.solve(captcha_method, sitekey=site_key, pageurl=url)
            form_data[captcha_field] = token

        return self.session.post(url, data=form_data)

La clase resume tres piezas que reutilizarás en cualquier bot:

  • solve envía el desafío a in.php y sondea res.php cada cinco segundos hasta obtener el token.
  • submit_form inserta el token en el campo correcto antes de hacer el POST.
  • La session reutiliza cookies y encabezados entre los pasos de un mismo flujo.

Ejemplo: bot que envía un formulario con reCAPTCHA

El caso más común es un formulario de contacto con reCAPTCHA v2. Le pasas la URL, los datos y el sitekey, y el bot resuelve el CAPTCHA justo antes de enviar:

bot = CaptchaBot("YOUR_API_KEY")

# Submit a contact form protected by reCAPTCHA
result = bot.submit_form(
    url="https://example.com/contact",
    form_data={
        "name": "John Doe",
        "email": "john@example.com",
        "message": "Inquiry about your service"
    },
    site_key="6Le-wvkS...",
    captcha_method="userrecaptcha"
)

print(f"Form submitted: {result.status_code}")

Ejemplo: bot de reserva de citas paso a paso

Muchos trámites —una cita previa en un portal público, una reserva en línea— reparten el proceso en varias pantallas y solo piden el CAPTCHA al final. El bot recorre cada paso y lo resuelve antes de confirmar. Automatiza únicamente flujos que tengas autorización para usar, respetando los términos de servicio del sitio:

def appointment_booking_bot(date, time_slot, user_info):
    bot = CaptchaBot("YOUR_API_KEY")

    # Step 1: Load booking page
    page = bot.session.get("https://example.com/book")

    # Step 2: Select date and time
    resp = bot.session.post("https://example.com/book/select", data={
        "date": date,
        "time": time_slot
    })

    # Step 3: Fill personal info with CAPTCHA
    result = bot.submit_form(
        url="https://example.com/book/confirm",
        form_data={
            "name": user_info["name"],
            "email": user_info["email"],
            "phone": user_info["phone"],
            "date": date,
            "time": time_slot
        },
        site_key="6Le-wvkS...",
        captcha_method="userrecaptcha"
    )

    return result.status_code == 200

# Run
success = appointment_booking_bot(
    date="2025-02-15",
    time_slot="10:00",
    user_info={"name": "John Doe", "email": "john@example.com", "phone": "555-0100"}
)

Ejemplo: bot de captura de datos con CAPTCHA de imagen

En la captura masiva de datos el desafío suele ser un CAPTCHA de imagen: descargas la imagen, la codificas en base64 y la envías con method=base64. CaptchaAI devuelve el texto y el bot lo escribe en el campo:

import base64

def data_entry_bot(entries, captcha_image_url):
    bot = CaptchaBot("YOUR_API_KEY")

    for entry in entries:
        # Load the form page
        page = bot.session.get("https://portal.example.com/entry")

        # Download and solve image CAPTCHA
        img = bot.session.get(captcha_image_url)
        img_b64 = base64.b64encode(img.content).decode()
        captcha_text = bot.solve("base64", body=img_b64)

        # Submit entry
        resp = bot.session.post("https://portal.example.com/entry", data={
            **entry,
            "captcha": captcha_text
        })

        logger.info(f"Entry submitted: {resp.status_code}")
        time.sleep(random.uniform(2, 5))

El mismo framework en Node.js

Si tu stack es JavaScript, el mismo patrón —enviar, sondear, devolver el token— se traslada directamente a Node.js con axios:

const axios = require("axios");

class CaptchaBot {
  constructor(apiKey) {
    this.apiKey = apiKey;
  }

  async solve(method, params) {
    params.key = this.apiKey;
    params.method = method;

    const submit = await axios.get("https://ocr.captchaai.com/in.php", {
      params,
    });
    const taskId = submit.data.split("|")[1];

    while (true) {
      await new Promise((r) => setTimeout(r, 5000));
      const result = await axios.get("https://ocr.captchaai.com/res.php", {
        params: { key: this.apiKey, action: "get", id: taskId },
      });
      if (result.data === "CAPCHA_NOT_READY") continue;
      if (result.data.startsWith("OK|")) return result.data.split("|")[1];
      throw new Error(result.data);
    }
  }

  async submitForm(url, formData, siteKey, method = "userrecaptcha") {
    const token = await this.solve(method, {
      googlekey: siteKey,
      pageurl: url,
    });
    formData["g-recaptcha-response"] = token;

    return axios.post(url, new URLSearchParams(formData));
  }
}

// Usage
const bot = new CaptchaBot("YOUR_API_KEY");
const result = await bot.submitForm(
  "https://example.com/submit",
  { name: "John", email: "john@example.com" },
  "6Le-wvkS..."
);

Buenas prácticas para que el bot no acabe bloqueado

Resolver el CAPTCHA es solo una parte del problema; el resto del tráfico también cuenta para que el bot funcione de forma estable:

  • Usa el token antes de que caduque: envíalo dentro de los 120 segundos siguientes a la resolución.
  • Espacia las solicitudes con pausas cortas entre acciones en lugar de dispararlas todas de golpe.
  • Reparte el tráfico por salidas de red autorizadas cuando trabajes muchas veces sobre el mismo dominio.
  • Revisa el HTML en busca de campos ocultos (tokens CSRF) que el formulario espera junto al token del CAPTCHA.

Cuántos threads necesita tu automatización

CaptchaAI factura por thread concurrente, no por resolución: el coste depende de cuántos CAPTCHA resuelvas en paralelo, no del total. Un bot secuencial que resuelve de uno en uno funciona de sobra con el plan BASIC ($15/mes, 5 threads); si lanzas varios bots a la vez o procesas colas grandes, ADVANCE ($90/mes, 50 threads) da margen para paralelizar. Como el precio mensual en USD es fijo, el coste resulta predecible para agencias y freelancers que facturan en monedas locales volátiles.

Problemas frecuentes y cómo resolverlos

Síntoma Qué revisar
El token es rechazado Envíalo dentro de los 120 segundos; después caduca
El bot se bloquea con un token válido Usa encabezados de navegador realistas y espacia las solicitudes con pausas
El formulario pide campos que no envías Inspecciona el HTML en busca de campos ocultos (tokens CSRF)
Bloqueo por exceso de solicitudes Añade pausas entre envíos y reparte el tráfico por salidas de red autorizadas

Preguntas frecuentes

¿Necesito proxies para que mi bot no acabe bloqueado?

Depende del volumen. Para tareas puntuales no suele hacer falta; con muchas solicitudes al mismo sitio, reparte el tráfico por salidas de red autorizadas y añade pausas. CaptchaAI resuelve la capa del CAPTCHA, no gestiona tu red de salida.

¿Cuántos threads necesito para automatizar a gran volumen?

Tantos como CAPTCHA quieras resolver a la vez. Un thread procesa uno y queda libre al terminar: BASIC ($15/mes, 5 threads) cubre bots ligeros y ADVANCE ($90/mes, 50 threads) encaja mejor en cargas paralelas.

¿Durante cuánto tiempo es válido el token de CaptchaAI?

Poco: úsalo dentro de los 120 segundos siguientes a la resolución. Si tu bot tarda más entre resolver y enviar, el sitio lo rechazará y tendrás que resolver otro.

¿Puedo usar el mismo framework para varios tipos de CAPTCHA?

Sí. Cambias el método (userrecaptcha, turnstile, base64) y sus parámetros; el ciclo de enviar y sondear no cambia. Por eso conviene una sola clase reutilizable en lugar de un script por tipo.

¿Qué tipos de CAPTCHA puede resolver este framework?

Los que admite la API: reCAPTCHA v2 y v3, Cloudflare Turnstile y Cloudflare Challenge, GeeTest v3 e imagen/OCR y grid. hCaptcha y FunCaptcha no son compatibles hoy.

Guías relacionadas

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