Tutoriais

envio controlado ao endpoint QA GeeTest em estruturas de automação de navegador

GeeTest v3 retorna três valores após a resolução: geetest_challenge, geetest_validate e geetest_seccode. Injetá-los corretamente em uma sessão de automação do navegador requer a compreensão de onde o site os espera: campos de formulário ocultos, retornos de chamada JavaScript ou cargas úteis XHR. Veja como fazer isso em cada estrutura principal.

O que você está injetando

CaptchaAI retorna um resultado de três partes:

{
  "geetest_challenge": "a1b2c3d4e5...modified_challenge",
  "geetest_validate": "abc123def456_validate",
  "geetest_seccode": "abc123def456_validate|jordan"
}

Todos os três valores devem ser injetados. A falta de qualquer um causa falha na verificação.

Etapa 1: extrair parâmetros e resolver

Comum a todos os frameworks - extraia gt e challenge e resolva com CaptchaAI:

import requests
import time

def solve_geetest(gt, challenge, page_url):
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": "YOUR_API_KEY",
        "method": "geetest",
        "gt": gt,
        "challenge": challenge,
        "pageurl": page_url,
        "json": 1
    })
    task_id = resp.json()["request"]

    for _ in range(60):
        time.sleep(3)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": "YOUR_API_KEY",
            "action": "get",
            "id": task_id,
            "json": 1
        })
        data = result.json()
        if data["status"] == 1:
            return data["request"]  # Returns dict with three values
    raise TimeoutError("GeeTest solve timed out")

Etapa 2: injetar no Playwright (Python)

Extrair parâmetros

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()

    # Capture GeeTest registration response
    geetest_data = {}
    def capture_geetest(response):
        if "register" in response.url and response.status == 200:
            try:
                data = response.json()
                if "gt" in data and "challenge" in data:
                    geetest_data.update(data)
            except Exception:
                pass

    page.on("response", capture_geetest)
    page.goto("https://staging.example.com/qa-login")
    page.wait_for_selector(".geetest_holder")

    gt = geetest_data["gt"]
    challenge = geetest_data["challenge"]

Injetar solução

# Solve with CaptchaAI
solution = solve_geetest(gt, challenge, page.url)

# Method 1: Set hidden form fields
page.evaluate(f"""
    const fields = {{
        'geetest_challenge': '{solution["geetest_challenge"]}',
        'geetest_validate': '{solution["geetest_validate"]}',
        'geetest_seccode': '{solution["geetest_seccode"]}'
    }};
    for (const [name, value] of Object.entries(fields)) {{
        let input = document.querySelector(`input[name="${{name}}"]`);
        if (!input) {{
            input = document.createElement('input');
            input.type = 'hidden';
            input.name = name;
            document.querySelector('form').appendChild(input);
        }}
        input.value = value;
    }}
""")

# Submit the form
page.click("#submit-button")

Método 2: acionar o retorno de chamada GeeTest

Alguns sites usam o retorno de chamada JavaScript do GeeTest em vez de campos de formulário:

page.evaluate(f"""
    // Find the GeeTest captcha object
    if (window.captchaObj) {{
        // Simulate a successful solve
        const result = {{
            geetest_challenge: '{solution["geetest_challenge"]}',
            geetest_validate: '{solution["geetest_validate"]}',
            geetest_seccode: '{solution["geetest_seccode"]}'
        }};

        // Override getValidate to return our solution
        window.captchaObj.getValidate = function() {{ return result; }};

        // Trigger the success callback
        const successEvent = new Event('geetest_success');
        document.dispatchEvent(successEvent);
    }}
""")

Etapa 3: injetar no Puppeteer (JavaScript)

const puppeteer = require('puppeteer');

async function solveAndInject() {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();

  // Capture GeeTest params
  let gt, challenge;
  page.on('response', async (response) => {
    if (response.url().includes('register') && response.status() === 200) {
      try {
        const data = await response.json();
        if (data.gt && data.challenge) {
          gt = data.gt;
          challenge = data.challenge;
        }
      } catch (e) {}
    }
  });

  await page.goto('https://staging.example.com/qa-login');
  await page.waitForSelector('.geetest_holder');

  // Solve with CaptchaAI (implementation from earlier)
  const solution = await solveCaptcha(gt, challenge, page.url());

  // Inject the three values
  await page.evaluate((sol) => {
    // Set hidden inputs
    const form = document.querySelector('form');
    ['geetest_challenge', 'geetest_validate', 'geetest_seccode'].forEach(name => {
      let input = document.querySelector(`input[name="${name}"]`);
      if (!input) {
        input = document.createElement('input');
        input.type = 'hidden';
        input.name = name;
        form.appendChild(input);
      }
      input.value = sol[name];
    });
  }, solution);

  await page.click('#submit-button');
}

Etapa 4: injetar selênio (Python)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")

# Wait for GeeTest widget
WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.CLASS_NAME, "geetest_holder"))
)

# Extract gt and challenge from the page
gt = driver.execute_script(
    "return document.querySelector('[data-gt]')?.dataset.gt"
)
challenge = driver.execute_script(
    "return document.querySelector('[data-challenge]')?.dataset.challenge"
)

# Solve with CaptchaAI
solution = solve_geetest(gt, challenge, driver.current_url)

# Inject via JavaScript
driver.execute_script(f"""
    var fields = {{
        'geetest_challenge': '{solution["geetest_challenge"]}',
        'geetest_validate': '{solution["geetest_validate"]}',
        'geetest_seccode': '{solution["geetest_seccode"]}'
    }};
    var form = document.querySelector('form');
    for (var name in fields) {{
        var input = document.querySelector('input[name="' + name + '"]');
        if (!input) {{
            input = document.createElement('input');
            input.type = 'hidden';
            input.name = name;
            form.appendChild(input);
        }}
        input.value = fields[name];
    }}
""")

driver.find_element(By.ID, "submit-button").click()

Lidando com envios baseados em XHR

Alguns sites enviam resultados do GeeTest via XHR em vez do formulário POST. Intercepte e modifique a solicitação:

# Playwright: Intercept the XHR and inject values
def handle_route(route):
    if "login" in route.request.url and route.request.method == "POST":
        # Modify the POST data to include our solution
        post_data = route.request.post_data
        # Add GeeTest values to the request
        route.continue_(post_data=modified_data)
    else:
        route.continue_()

page.route("**/api/login**", handle_route)

Solução de problemas

Problema Causa Correção
"Falha na validação do GeeTest" Faltando um dos três valores Verifique se todos os três valores foram injetados
O desafio expirou antes da injeção Muito tempo entre a extração e a resolução Extraia e resolva em rápida sucessão
O formulário é enviado, mas os valores não estão incluídos Nomes de campo ou seletor de formulário incorretos Inspecione o formulário real para encontrar os nomes corretos
Retorno de chamada não acionado O site usa um nome de retorno de chamada personalizado Encontre o retorno de chamada nas opções initGeetest
Valores injetados, mas o widget ainda é exibido Estado do widget não atualizado Acione o retorno de chamada de sucesso programaticamente

Perguntas frequentes

Preciso ocultar visualmente o widget GeeTest após a injeção?

Não. O estado visual do widget não afeta o envio do formulário. Contanto que os três valores estejam nos dados do formulário, o servidor os valida independentemente da aparência do widget.

Posso injetar valores GeeTest sem um navegador?

Sim, se o site aceitar HTTP POST direto com os três valores. Intercepte o endpoint de envio do formulário e envie os valores via requests ou qualquer cliente HTTP.

Por que o GeeTest usa três valores separados em vez de um token?

Os três valores têm finalidades diferentes: geetest_challenge rastreia a sessão, geetest_validate prova que o desafio foi resolvido e geetest_seccode fornece um hash para detecção de violação.

Artigos relacionados

Próximas etapas

Injete soluções GeeTest em qualquer estrutura -obtenha sua chave API CaptchaAIe comece a resolver.

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