Análises Técnicas

Como lidar com o reCAPTCHA v2 em fluxos de trabalho de coleta autorizada

Quando seu raspador atinge um desafio reCAPTCHA v2, o fluxo de trabalho é interrompido. A página espera que um humano resolva a caixa de seleção ou grade de imagem antes de fornecer os dados necessários. A maneira com menor latência de retomar a raspagem é rotear o CAPTCHA para uma API do solucionador: extrair a chave do site e o URL da página, enviá-los paraCaptchaAI, receba um token válido e injete-o de volta na página.

Este guia mostra o fluxo completo com código funcional para Python (Selenium + solicitações) e Node.js (Puppeteer).


Como funciona o fluxo de trabalho

Cada widget reCAPTCHA v2 tem dois parâmetros que seu raspador precisa:

  1. googlekey — a chave pública do site incorporada na página HTML
  2. pageurl — a URL onde o CAPTCHA aparece

Seu raspador os envia para a API CaptchaAI, espera por um token resolvido e injeta o token de volta no campo g-recaptcha-response da página (ou chama a função de retorno de chamada). O back-end do site de destino verifica o token no Google e permite a solicitação.


Python: Selênio + CaptchaAI

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

# Step 1: Open the page with Selenium
driver = webdriver.Chrome()
driver.get("https://example.com/protected-page")

# Step 2: Extract the sitekey
sitekey = driver.find_element(By.CSS_SELECTOR, ".g-recaptcha").get_attribute("data-sitekey")
page_url = driver.current_url

# Step 3: Submit to CaptchaAI
response = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "googlekey": sitekey,
    "pageurl": page_url,
    "json": 1
}).json()

task_id = response["request"]

# Step 4: Poll for result
token = None
for _ in range(40):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY",
        "action": "get",
        "id": task_id,
        "json": 1
    }).json()

    if result.get("status") == 1:
        token = result["request"]
        break
    if result.get("request") != "CAPCHA_NOT_READY":
        raise RuntimeError(f"Solve failed: {result['request']}")

# Step 5: Inject the token and submit
driver.execute_script(
    f'document.getElementById("g-recaptcha-response").innerHTML = "{token}";'
)

# Check for callback
callback = driver.execute_script(
    'var el = document.querySelector(".g-recaptcha"); '
    'return el ? el.getAttribute("data-callback") : null;'
)
if callback:
    driver.execute_script(f'{callback}("{token}");')
else:
    driver.find_element(By.CSS_SELECTOR, "form").submit()

# Step 6: Scrape the data
print(driver.page_source[:500])
driver.quit()

Node.js: Titereiro + CaptchaAI

const puppeteer = require("puppeteer");

async function scrapeWithCaptcha(url) {
  const browser = await puppeteer.launch({ headless: "new" });
  const page = await browser.newPage();
  await page.goto(url, { waitUntil: "networkidle2" });

  // Extract sitekey
  const sitekey = await page.$eval(".g-recaptcha", (el) => el.dataset.sitekey);

  // Submit to CaptchaAI
  const submitRes = await fetch(
    `https://ocr.captchaai.com/in.php?${new URLSearchParams({
      key: "YOUR_API_KEY",
      method: "userrecaptcha",
      googlekey: sitekey,
      pageurl: url,
      json: 1,
    })}`
  );
  const { request: taskId } = await submitRes.json();

  // Poll for result
  let token;
  for (let i = 0; i < 40; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const res = await fetch(
      `https://ocr.captchaai.com/res.php?${new URLSearchParams({
        key: "YOUR_API_KEY",
        action: "get",
        id: taskId,
        json: 1,
      })}`
    );
    const data = await res.json();
    if (data.status === 1) {
      token = data.request;
      break;
    }
    if (data.request !== "CAPCHA_NOT_READY")
      throw new Error(`Solve failed: ${data.request}`);
  }

  // Inject token
  await page.evaluate((t) => {
    document.getElementById("g-recaptcha-response").innerHTML = t;
    const cb = document.querySelector(".g-recaptcha")?.dataset.callback;
    if (cb && window[cb]) window[cb](t);
  }, token);

  // Wait for navigation after form submit
  await page.waitForNavigation({ waitUntil: "networkidle2" });
  const content = await page.content();
  await browser.close();
  return content;
}

scrapeWithCaptcha("https://example.com/protected-page").then(console.log);

Modo modo headless vs com cabeça

Alguns sites detectam navegadores headless e os bloqueiam antes mesmo de o CAPTCHA aparecer. Se você for bloqueado antes de ver o reCAPTCHA:

  • Use headless: "new" no Puppeteer (modo controle de QA mais recente)
  • Adicionar --disable-blink-features=AutomationControlled aos sinalizadores do Chromium
  • Use uma string User-Agent real
  • Considere usar a rotação de proxy com suas soluções CaptchaAI

Abordagem somente HTTP (sem navegador)

Se o site de destino enviar o CAPTCHA em um fluxo de envio de formulário, você poderá ignorar totalmente o navegador:

import requests
import time

session = requests.Session()
session.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0"

# Load the page to get cookies
session.get("https://example.com/protected-page")

# Solve the CAPTCHA
sitekey = "6Le-wvkSAAAAAN..."  # extracted from page HTML
solve_resp = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY", "method": "userrecaptcha",
    "googlekey": sitekey, "pageurl": "https://example.com/protected-page",
    "json": 1
}).json()

task_id = solve_resp["request"]
time.sleep(15)

# Poll
for _ in range(30):
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY", "action": "get", "id": task_id, "json": 1
    }).json()
    if result.get("status") == 1:
        token = result["request"]
        break
    time.sleep(5)

# Submit with token
resp = session.post("https://example.com/protected-page", data={
    "g-recaptcha-response": token,
    "other_field": "value"
})
print(resp.text[:500])

Perguntas frequentes

Resolver reCAPTCHA v2 desacelera meu raspador?

Cada resolução leva de 15 a 60 segundos. Para raspagem de alto volume, execute várias soluções em paralelo (CaptchaAI suporta tarefas simultâneas por thread).

Posso armazenar tokens reCAPTCHA em cache?

Não. Cada token é de uso único e expira após aproximadamente 2 minutos. Você precisa de uma nova solução para cada solicitação de página protegida.

Preciso de um navegador para lidar com reCAPTCHA v2?

Nem sempre. Se o site aceitar g-recaptcha-response como um campo POST, você poderá usar uma abordagem somente HTTP. Se o site exigir envio controlado ao endpoint QA baseada em JavaScript, você precisará de um navegador.

Como lidar com proxies rotativos com CaptchaAI?

CaptchaAI resolve CAPTCHAs em sua própria infraestrutura — você não precisa passar seu proxy para o reCAPTCHA v2 padrão. Use seus proxies para as solicitações de scraping a seguir.

E se o site usar Enterprise reCAPTCHA?

Adicione enterprise=1 à sua solicitação CaptchaAI. VerComo resolver reCAPTCHA v2 Enterprise usando API.


Comece a raspar reCAPTCHA v2

  1. Obtenha sua chave API emcaptchaai.com/api.php
  2. Extraia a chave do site da página de destino
  3. Use os exemplos de código acima para resolver e injetar
  4. Dimensione com soluções simultâneas para fluxos de trabalho de alto volume

Guias relacionados

  • Como resolver reCAPTCHA v2 usando API
  • Manipulação de Selênio CAPTCHA com Python
  • Puppeteer Captcha Resolvendo Node.js
  • Erros comuns de solução de reCAPTCHA v2
Os comentários estão desativados para este artigo.