Use Cases

CAPTCHA em bots de automação: como resolver com a CaptchaAI

Um bot de automação trava, e o log não mostra erro nenhum — só um formulário que nunca confirma o envio. Na maioria das vezes, a causa é um CAPTCHA que apareceu no meio do fluxo e o script não sabia responder. Bots de automação existem justamente para tarefas repetíveis — enviar formulários, criar contas, alimentar sistemas, monitorar páginas —, e é esse padrão repetitivo que faz reCAPTCHA, Cloudflare Turnstile e desafios parecidos entrarem em ação. A CaptchaAI resolve esses desafios via API: o bot envia a tarefa, recebe o token de volta e segue o fluxo sem precisar de um humano clicando em nada.

Onde os bots esbarram no CAPTCHA

Antes de programar qualquer coisa, vale mapear em qual etapa do fluxo o CAPTCHA costuma aparecer — isso decide qual method da API chamar:

Cenário CAPTCHA típico Método CaptchaAI
Envio de formulário reCAPTCHA v2 method=userrecaptcha
Cadastro de conta reCAPTCHA v2/v3 method=userrecaptcha
Portais de entrada de dados CAPTCHA de imagem method=base64
Reserva ou agendamento Cloudflare Turnstile method=turnstile
Acesso a gateway de API Página de verificação da Cloudflare method=cloudflare_challenge

O framework abaixo cobre os cinco casos com a mesma classe — o que muda é o method e os parâmetros (sitekey, googlekey, pageurl) de acordo com o tipo detectado na página.

Framework de bot para resolver CAPTCHA automaticamente

A classe CaptchaBot a seguir faz o trabalho pesado: envia a tarefa para in.php, consulta res.php em intervalos até o token voltar (ou até estourar o tempo limite) e devolve o valor pronto para preencher o formulário.

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)

Bot de envio de formulário com reCAPTCHA

O uso mais direto é resolver o CAPTCHA e enviar o formulário na sequência, como em um formulário de contato protegido por reCAPTCHA v2:

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}")

Bot de agendamento com várias etapas

Fluxos de agendamento normalmente têm mais de uma requisição antes do CAPTCHA aparecer: selecionar data, escolher horário e só então confirmar com os dados da pessoa. O exemplo abaixo encadeia as três etapas:

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"}
)

Dados pessoais e a LGPD nesse fluxo

Repare que o passo 3 envia nome, e-mail e telefone junto com a confirmação — dados pessoais de verdade, não fictícios, se o bot estiver rodando contra um formulário em produção. Antes de colocar um bot desses no ar contra um site próprio ou de um cliente, vale revisar as obrigações da LGPD para esse fluxo: grave só o que o processo de agendamento realmente precisa, defina por quanto tempo esses dados ficam armazenados e evite logar o payload completo — token do CAPTCHA incluído — em texto plano. Isso não é aconselhamento jurídico, é o mínimo de higiene de dados que qualquer pipeline de automação com dados de clientes deveria ter.

Bot de entrada de dados com CAPTCHA de imagem

Portais de entrada de dados mais antigos costumam usar CAPTCHA de imagem simples em vez de reCAPTCHA. Nesse caso, o caminho é baixar a imagem, converter para base64 e enviar pelo método base64:

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))

Versão em Node.js do mesmo framework

A mesma lógica de enviar e consultar o resultado funciona em Node.js com axios, para times que já rodam a automação em JavaScript:

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..."
);

Quanto custa manter um bot rodando o dia todo

A CaptchaAI cobra por thread simultânea, não por CAPTCHA resolvido — cada plano inclui solves ilimitados dentro do número de threads contratado. Para dimensionar, pense em quantos CAPTCHAs os bots podem encontrar por mês no pior caso:

Volume do bot CAPTCHAs/mês (pior caso) Plano recomendado
1 bot, 1 requisição a cada 10 min, 24/7 ~4.320 BASIC (US$ 15/mês, 5 threads)
30 bots em paralelo, mesmo ritmo ~129.600 STANDARD (US$ 30/mês, 15 threads)
100 bots em paralelo, mesmo ritmo ~432.000 ADVANCE (US$ 90/mês, 50 threads)

Esses números assumem que todo ciclo do bot esbarra em um CAPTCHA, o que raramente acontece na prática — muitos fluxos só exigem o desafio na primeira visita ou a cada N requisições. Comece pelo plano mais barato que cobre o pior caso e suba de tier apenas quando o uso real de threads pedir.

Erros comuns e como corrigir

  • Token do CAPTCHA rejeitado — use o token dentro de 120 segundos após a resolução; depois disso, o site de destino costuma descartá-lo como expirado.
  • Bot detectado mesmo com token válido — envie cabeçalhos de navegador realistas (User-Agent, Accept-Language) e adicione atrasos entre requisições.
  • Formulário exige campos adicionais — inspecione o HTML do formulário em busca de campos ocultos, como tokens CSRF.
  • Taxa limitada em envios repetidos — adicione atrasos maiores entre tentativas e faça rotação de proxies.

Perguntas frequentes

Quais tipos de CAPTCHA um bot de automação consegue resolver com a CaptchaAI?

A maior parte dos que aparecem em fluxos de automação: reCAPTCHA v2/v3, Cloudflare Turnstile e a página de verificação da Cloudflare (method=cloudflare_challenge), GeeTest v3, CAPTCHA de imagem e de grade, além de CaptchaFox, Friendly Captcha e Lemin em beta. hCaptcha e FunCaptcha ainda não são suportados — se o formulário do seu fluxo depender de um desses dois, a CaptchaAI não resolve hoje. Fora essa exceção, o bot só precisa identificar o tipo na página e chamar o method correto.

Quanto custa rodar um bot de automação o dia inteiro?

Depende de quantas threads simultâneas os bots usam, não de quantas horas ficam ligados — o plano BASIC (US$ 15/mês, 5 threads) já cobre um bot único rodando o dia inteiro na maioria dos fluxos, porque o custo é por concorrência, não por tempo de execução.

O token que a CaptchaAI devolve expira?

Sim — use o token em até 120 segundos após recebê-lo. Se o bot demorar mais do que isso entre resolver o CAPTCHA e enviar o formulário, por exemplo esperando outra etapa terminar, o site de destino costuma rejeitar o token como expirado. A solução mais simples é resolver o CAPTCHA como último passo antes do envio.

Dá para rodar vários bots em paralelo sem estourar o limite de threads?

Dá, desde que o número de bots resolvendo CAPTCHA ao mesmo tempo não passe do total de threads do plano. Se 20 bots tentam resolver CAPTCHA simultaneamente em um plano BASIC de 5 threads, as tarefas excedentes ficam na fila até uma thread liberar. O ajuste é subir de plano ou escalonar o disparo dos bots para não bater todos no mesmo minuto.

Guias relacionados

Os comentários estão desativados para este artigo.