API Tutorials

Como resolver CAPTCHA de imagem de grade automaticamente

Para resolver um CAPTCHA de imagem de grade automaticamente, você não precisa do fluxo de token do reCAPTCHA: basta enviar a imagem completa da grade (3×3, 4×4 ou um layout fora do padrão) para o endpoint method=post da API da CaptchaAI e aplicar a resposta — índices de célula ou coordenadas de clique — de volta na página. É o caminho certo sempre que o site usa uma grade de imagens própria, fora do ecossistema do Google.

O reCAPTCHA também usa esse formato de grade, normalmente pedindo para marcar as células que contêm um determinado objeto — mas muitos sites implementam desafios de grade personalizados, sem relação nenhuma com o reCAPTCHA. Esses casos não respondem ao método de token (method=userrecaptcha), porque não existe um token do Google para gerar: o que existe é uma imagem estática, que precisa ser interpretada como um todo.

Este guia cobre o fluxo completo: capturar a imagem da grade, enviá-la para o endpoint method=post, consultar o resultado por polling e aplicar a resposta de volta no formulário, em Python e Node.js.


Requisitos para resolver CAPTCHA de grade via API

Antes de começar, você precisa de três coisas:

Item Detalhe
Chave de API da CaptchaAI Gerada no painel em captchaai.com
Imagem da grade completa Screenshot ou base64 da grade inteira — não recorte células individuais
Ambiente Python 3.7+ ou Node.js 14+

Passo 1: capture a imagem completa da grade

A CaptchaAI analisa a grade inteira como uma única imagem — seja 3×3, 4×4 ou um layout fora do padrão — então não recorte célula por célula antes de enviar. Duas abordagens cobrem a maioria dos casos reais.

Opção A: screenshot do elemento do CAPTCHA

Se o desafio estiver renderizado como um elemento visível na página, capture apenas o contêiner com Selenium:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com/protected-form")

# Screenshot just the captcha container
captcha_element = driver.find_element(By.CSS_SELECTOR, "#captcha-container")
captcha_element.screenshot("captcha_grid.png")

Opção B: extraia a imagem do atributo src

Quando a grade é uma única imagem (<img>) em vez de um elemento composto, pegue o src diretamente — ele já pode vir em base64 ou como uma URL para baixar:

import base64
import requests

captcha_img = driver.find_element(By.CSS_SELECTOR, ".grid-captcha img")
src = captcha_img.get_attribute("src")

if src.startswith("data:image"):
    image_b64 = src.split(",")[1]
else:
    image_data = requests.get(src).content
    image_b64 = base64.b64encode(image_data).decode()

Dica de conformidade: se você guardar essas capturas de tela para depuração, trate-as como dado técnico transitório e evite reter, junto com elas, outros dados pessoais do formulário protegido — um cuidado que vale a pena alinhar com a LGPD sempre que o formulário coleta informações de usuários reais.


Passo 2: envie a imagem para o endpoint method=post da CaptchaAI

Com a imagem em mãos, envie para in.php usando method=post junto com recaptcha=1 — esse parâmetro sinaliza que a resposta deve voltar no formato de grade (índices ou coordenadas), e não como texto solto.

Upload de arquivo (Python)

import requests
import time

API_KEY = "YOUR_API_KEY"

with open("captcha_grid.png", "rb") as f:
    response = requests.post("https://ocr.captchaai.com/in.php",
        data={
            "key": API_KEY,
            "method": "post",
            "recaptcha": 1,
            "json": 1
        },
        files={"file": f}
    )

data = response.json()
task_id = data["request"]
print(f"Task: {task_id}")

Envio em base64 (Python)

Se a imagem já estiver em memória, como no caso da Opção B do Passo 1, pule o upload de arquivo e envie o base64 direto no corpo da requisição:

response = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "post",
    "body": image_b64,
    "recaptcha": 1,
    "json": 1
})

task_id = response.json()["request"]

Envio em Node.js

A mesma chamada, agora com axios — a lógica de parâmetros é idêntica à versão em Python:

const axios = require('axios');
const fs = require('fs');

async function submitGridCaptcha(imagePath) {
  const imageB64 = fs.readFileSync(imagePath).toString('base64');

  const { data } = await axios.post('https://ocr.captchaai.com/in.php', null, {
    params: {
      key: 'YOUR_API_KEY',
      method: 'post',
      body: imageB64,
      recaptcha: 1,
      json: 1
    }
  });

  return data.request;
}

Passo 3: consulte o resultado (polling)

A resposta não vem no mesmo request do envio — a CaptchaAI processa a imagem de forma assíncrona. Consulte res.php a cada poucos segundos até receber status: 1:

def get_grid_solution(task_id):
    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,
            "json": 1
        }).json()

        if result.get("status") == 1:
            return result["request"]
        if result.get("request") != "CAPCHA_NOT_READY":
            raise Exception(f"Error: {result['request']}")

    raise Exception("Timeout")

solution = get_grid_solution(task_id)
print(f"Solution: {solution}")
# Returns click coordinates or cell indices

Segundo a métrica pública da CaptchaAI, uma imagem de grade resolve em menos de 1 segundo em condições normais, com alta taxa de sucesso — o laço de 30 tentativas de 5 segundos acima é apenas margem de segurança para picos de fila, não uma estimativa do tempo real de solve. Se os seus workers rodam em uma região como sa-east-1 (São Paulo) na AWS, o RTT até a CaptchaAI tende a ficar baixo; ajuste o intervalo de polling conforme a latência medida no seu próprio ambiente.


Passo 4: aplique a resposta na página

O formato da resposta depende de como o site implementa a grade: alguns esperam cliques por índice de célula, outros por coordenadas x/y. Trate os dois formatos no seu código.

Clique por índice de célula

# If solution returns cell indices (e.g., "2,5,6")
selected = [int(i) for i in solution.split(",")]
cells = driver.find_elements(By.CSS_SELECTOR, ".grid-cell")

for idx in selected:
    cells[idx - 1].click()
    time.sleep(0.2)

driver.find_element(By.CSS_SELECTOR, ".verify-button").click()

Clique por coordenadas

from selenium.webdriver.common.action_chains import ActionChains

# If solution returns coordinates (e.g., "x=120,y=80;x=250,y=200")
captcha_element = driver.find_element(By.CSS_SELECTOR, "#captcha-container")
actions = ActionChains(driver)

for coord in solution.split(";"):
    parts = dict(p.split("=") for p in coord.split(","))
    x, y = int(parts["x"]), int(parts["y"])
    actions.move_to_element_with_offset(captcha_element, x, y).click()

actions.perform()

Erros comuns ao resolver CAPTCHA de grade e como corrigir

Erro Causa Correção
ERROR_WRONG_FILE_EXTENSION Formato de imagem inválido Use PNG ou JPEG e confira se o base64 está bem formado
ERROR_CAPTCHA_UNSOLVABLE Imagem pequena demais ou borrada Capture em resolução máxima, sem downscale
Células erradas selecionadas A resposta chegou em um formato diferente do esperado Confirme se a resposta veio como índices ou como coordenadas antes de mapear os cliques
ERROR_TOO_BIG_CAPTCHA_FILESIZE A imagem passa do limite de tamanho Redimensione para menos de 600 KB antes de enviar

Exemplo completo pronto para rodar

Quer um projeto funcional completo, com setup de ambiente, polling, novas tentativas e tratamento de erro já implementados, em nove linguagens diferentes?

Veja o exemplo completo no GitHub →


Perguntas frequentes sobre resolução de CAPTCHA de grade

Quando usar resolução por grade em vez do método de token?

Use o método de token (method=userrecaptcha) para desafios reCAPTCHA padrão — é mais simples e mais confiável nesse caso específico. Use a resolução por grade (method=post com recaptcha=1) quando o desafio é uma grade de imagens própria do site, sem relação com o reCAPTCHA.

Quanto custa resolver CAPTCHA de grade com a CaptchaAI?

O preço não muda por tipo de CAPTCHA. Você paga por thread simultânea, com solves ilimitados por thread: o plano BASIC (US$ 15/mês, 5 threads) já cobre a maioria dos testes e integrações pequenas; para volume maior, os planos sobem até o ENTERPRISE (US$ 300/mês, 200 threads). A tabela completa de preços fica no site da CaptchaAI.

Preciso de um navegador headless para usar esse endpoint?

Não necessariamente. O endpoint method=post só precisa da imagem — como base64 ou arquivo. Um navegador (Selenium, Playwright ou Puppeteer) entra em cena apenas se você também precisar capturar a imagem na página e, depois, aplicar o clique da resposta; se a grade já chega isolada, por exemplo de um scraper de API, dá para pular o navegador inteiramente.

Dá para resolver grades dinâmicas, onde as células mudam a cada clique?

Para grades dinâmicas do reCAPTCHA, onde os blocos clicados são substituídos por novos, use o método de token (method=userrecaptcha). O método de grade resolve uma imagem estática única — não acompanha atualizações em tempo real dentro da mesma sessão de desafio.

Esse fluxo funciona em outras linguagens além de Python?

Sim. A lógica é a mesma em qualquer linguagem que consiga fazer uma requisição HTTP: os exemplos deste guia cobrem Python e Node.js, e o projeto completo no GitHub traz variações também em PHP, Go, Java, C#, Ruby, Rust e Kotlin.


Guias relacionados

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