Solução de Problemas

A automação do navegador CAPTCHA falha, mas a API funciona: guia de depuração

Você resolveu o CAPTCHA via CaptchaAI e obteve um token válido, mas injetá-lo no navegador não funciona. Este guia cobre todos os motivos e como corrigir cada um deles.


Pontos de falha comuns

Problema Sintoma Causa Raiz
Token não injetado no elemento correto O formulário é enviado sem token Seletor de área de texto incorreto
O token expirou antes do envio Site mostra CAPTCHA novamente Muito lento entre resolver e enviar
Retorno de chamada não acionado O botão do formulário permanece desativado Retorno de chamada do grecaptcha ausente
URL de página errado enviado para API Token inválido para este domínio Incompatibilidade de URL
Detecção de bot além do CAPTCHA Bloqueado após token aceito sinal de navegador do navegador

Correção 1: injeção correta de token para reCAPTCHA v2

O token deve ir para a área de texto g-recaptcha-response E o retorno de chamada deve ser acionado:

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


def inject_recaptcha_token(driver, token):
    """Properly inject reCAPTCHA v2 token in browser."""

    # Step 1: Make the response textarea visible and set the value
    driver.execute_script("""
        // Find all response textareas (may be multiple on page)
        var textareas = document.querySelectorAll('[name="g-recaptcha-response"]');
        textareas.forEach(function(ta) {
            ta.style.display = 'block';
            ta.value = arguments[0];
        });

        // Also set via ID if present
        var byId = document.getElementById('g-recaptcha-response');
        if (byId) {
            byId.style.display = 'block';
            byId.value = arguments[0];
        }
    """, token)

    # Step 2: Trigger the callback
    driver.execute_script("""
        // Try standard callback
        if (typeof ___grecaptcha_cfg !== 'undefined') {
            var clients = ___grecaptcha_cfg.clients;
            for (var key in clients) {
                var client = clients[key];
                // Navigate nested structure to find callback
                for (var prop in client) {
                    var val = client[prop];
                    if (val && typeof val === 'object') {
                        for (var subprop in val) {
                            var subval = val[subprop];
                            if (subval && typeof subval === 'object' && subval.callback) {
                                subval.callback(arguments[0]);
                                return;
                            }
                        }
                    }
                }
            }
        }
        // Fallback: try common callback names
        if (typeof onCaptchaSuccess === 'function') onCaptchaSuccess(arguments[0]);
        else if (typeof captchaCallback === 'function') captchaCallback(arguments[0]);
    """, token)


# Usage
driver = webdriver.Chrome()
driver.get("https://example.com/form")
# ... solve CAPTCHA via CaptchaAI ...
inject_recaptcha_token(driver, token)
time.sleep(1)
driver.find_element(By.CSS_SELECTOR, "button[type=submit]").click()

Correção 2: lidar com formulários dependentes de retorno de chamada

Alguns formulários permanecem desativados até que o retorno de chamada CAPTCHA seja acionado:

def find_and_trigger_callback(driver, token):
    """Find the reCAPTCHA callback and trigger it."""

    # Method 1: Extract callback from data attribute
    callback_name = driver.execute_script("""
        var widget = document.querySelector('.g-recaptcha');
        if (widget) {
            return widget.getAttribute('data-callback');
        }
        return null;
    """)

    if callback_name:
        driver.execute_script(f"window['{callback_name}'](arguments[0]);", token)
        return True

    # Method 2: Extract from grecaptcha config
    triggered = driver.execute_script("""
        try {
            var widgetId = 0;
            var callback = ___grecaptcha_cfg.clients[widgetId].aa.l.callback;
            if (typeof callback === 'function') {
                callback(arguments[0]);
                return true;
            }
        } catch(e) {}
        return false;
    """, token)

    return triggered

Correção 3: Tempo – Resolva e use imediatamente

import requests
import time


def solve_and_inject_fast(driver, api_key, sitekey, page_url):
    """Solve CAPTCHA and inject token with minimal delay."""
    # Submit solve request
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": api_key,
        "method": "userrecaptcha",
        "googlekey": sitekey,
        "pageurl": page_url,
        "json": 1,
    }, timeout=30)
    task_id = resp.json()["request"]

    # Poll for result
    time.sleep(15)
    for _ in range(24):
        resp = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key, "action": "get",
            "id": task_id, "json": 1,
        }, timeout=15)
        data = resp.json()

        if data.get("status") == 1:
            token = data["request"]

            # IMMEDIATELY inject — don't wait
            inject_recaptcha_token(driver, token)

            # Submit form within 5 seconds
            time.sleep(0.5)
            return True

        if data["request"] != "CAPCHA_NOT_READY":
            raise RuntimeError(data["request"])
        time.sleep(5)

    raise TimeoutError("Solve timeout")

Correção 4: URL de página correto para SPAs e Iframes

def get_correct_pageurl(driver):
    """Get the URL that reCAPTCHA actually sees."""

    # Check if CAPTCHA is in an iframe
    iframes = driver.find_elements(By.TAG_NAME, "iframe")

    for iframe in iframes:
        src = iframe.get_attribute("src") or ""
        if "recaptcha" in src or "anchor" in src:
            # CAPTCHA is in iframe — use parent page URL
            return driver.current_url

    # For SPAs, use current URL (may differ from initial load)
    return driver.current_url


# WRONG — using the URL you navigated to
pageurl = "https://example.com/form"  # May have redirected

# CORRECT — using the URL the browser is actually on
pageurl = get_correct_pageurl(driver)

Correção 5: detecção anti-bot além do CAPTCHA

Mesmo com um token válido, o site pode bloquear navegadores automatizados:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service


def create_qa_browser_driver():
    """Create a browser that avoids basic bot detection."""
    options = Options()

    # Remove automation indicators
    options.add_argument("--disable-blink-features=AutomationControlled")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option("useAutomationExtension", False)

    # Set realistic window size
    options.add_argument("--window-size=1920,1080")

    driver = webdriver.Chrome(options=options)

    # Override sinal de navegador automatizado
    driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
        "source": "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
    })

    return driver


driver = create_qa_browser_driver()

Correção 6: envio controlado ao endpoint QA de catraca

Cloudflare Turnstile usa uma abordagem de injeção diferente:

def inject_turnstile_token(driver, token):
    """Inject Turnstile token into the page."""
    driver.execute_script("""
        // Find Turnstile response input
        var inputs = document.querySelectorAll(
            'input[name="cf-turnstile-response"], ' +
            'input[name="g-recaptcha-response"]'
        );

        inputs.forEach(function(input) {
            input.value = arguments[0];
        });

        // Trigger change event
        inputs.forEach(function(input) {
            input.dispatchEvent(new Event('change', { bubbles: true }));
            input.dispatchEvent(new Event('input', { bubbles: true }));
        });

        // Try Turnstile callback
        if (window.turnstile) {
            var widgets = document.querySelectorAll('[data-callback]');
            widgets.forEach(function(w) {
                var cb = w.getAttribute('data-callback');
                if (typeof window[cb] === 'function') {
                    window[cb](arguments[0]);
                }
            });
        }
    """, token)

Lista de verificação de depuração

def debug_captcha_injection(driver, token):
    """Print debug info to diagnose injection failures."""
    info = driver.execute_script("""
        var result = {};

        // Check textarea exists
        var ta = document.querySelector('[name="g-recaptcha-response"]');
        result.textarea_found = !!ta;
        result.textarea_value_set = ta ? ta.value.length > 0 : false;

        // Check reCAPTCHA loaded
        result.grecaptcha_loaded = typeof grecaptcha !== 'undefined';

        // Check for callback
        var widget = document.querySelector('.g-recaptcha');
        result.has_data_callback = widget ? !!widget.getAttribute('data-callback') : false;
        result.callback_name = widget ? widget.getAttribute('data-callback') : null;

        // Current URL
        result.current_url = window.location.href;

        // Check for errors in console (basic)
        result.has_submit_button = !!document.querySelector('button[type=submit], input[type=submit]');

        return result;
    """)

    for key, value in info.items():
        print(f"  {key}: {value}")

    return info

Solução de problemas

Sintoma Causa Correção
Token definido, mas formulário rejeitado Retorno de chamada não acionado Encontre e chame a função de retorno de chamada
O botão enviar permanece desativado O retorno de chamada permite Acionar retorno de chamada após envio controlado ao endpoint QA
"CAPTCHA inválido" após envio O token expirou Reduza o tempo entre a resolução e o envio
403 após envio do formulário Detecção de bot (não CAPTCHA) Use opções controle de QAs do navegador
Funciona em solicitações, falha no navegador URL da página diferente Use driver.current_url como pageurl

Perguntas frequentes

Por que o token funciona nas solicitações, mas não no navegador?

Geralmente porque a função de retorno de chamada não é acionada. Os formulários do navegador geralmente dependem do retorno de chamada para permitir o envio ou definir campos ocultos.

Preciso usar um navegador específico?

Chrome/Chromium é mais compatível. O Firefox funciona, mas pode precisar de abordagens diferentes para comandos CDP. Use undetected-chromedriver para sites com forte detecção de bot.

Devo usar o modo modo headless?

Alguns sites detectam navegadores headless e rejeitam tokens. Experimente primeiro o modo headful e depois mude para headless com sinalizadores adequados, se funcionar.


Guias Relacionados



Próximos passos

  • Início rápido do CaptchaAI: sua primeira resolução de CAPTCHA em 5 minutos
  • Como resolver reCAPTCHA v2 com a API: guia passo a passo
  • Como resolver Cloudflare Turnstile pela API
  • Como resolver GeeTest v3 usando API
Os comentários estão desativados para este artigo.