Tutoriels

Injection de jetons GeeTest dans les cadres d'automatisation du navigateur

GeeTest v3 renvoie trois valeurs après résolution : geetest_challenge, geetest_validate et geetest_seccode. Pour les injecter correctement dans une session d'automatisation de navigateur, il faut comprendre où le site les attend : champs de formulaire cachés, rappels JavaScript ou charges utiles XHR. Voici comment procéder dans chaque framework majeur.

Ce que vous injectez

CaptchaAI renvoie un résultat en trois parties :

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

Les trois valeurs doivent être injectées. L’absence d’un élément entraîne un échec de vérification.

Étape 1 : Extraire les paramètres et résoudre

Commun à tous les frameworks – extrayez gt et challenge, puis résolvez avec 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")

Étape 2 : Injecter dans Playwright (Python)

Extraire les paramètres

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://example.com/login")
    page.wait_for_selector(".geetest_holder")

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

Injecter la solution

# 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éthode 2 : déclencher le rappel GeeTest

Certains sites utilisent le rappel JavaScript de GeeTest au lieu des champs de formulaire :

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

Étape 3 : Injecter dans 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://example.com/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');
}

Étape 4 : Injecter du sélénium (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://example.com/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()

Gestion des soumissions basées sur XHR

Certains sites soumettent les résultats du GeeTest via XHR au lieu du formulaire POST. Intercepter et modifier la requête :

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

Dépannage

Problème Parce que Corriger
"La validation du GeeTest a échoué" Il manque une des trois valeurs Vérifiez que les trois valeurs sont injectées
Challenge expiré avant l’injection Trop de temps entre l'extraction et la résolution Extraire et résoudre rapidement
Le formulaire est soumis mais les valeurs ne sont pas incluses Noms de champs ou sélecteur de formulaire incorrects Inspectez le formulaire réel pour trouver les noms corrects
Rappel non déclenché Le site utilise un nom de rappel personnalisé Trouver le rappel dans les options initGeetest
Valeurs injectées mais le widget s'affiche toujours État du widget non mis à jour Déclenchez le rappel de réussite par programmation

FAQ

Dois-je masquer visuellement le widget GeeTest après injection ?

Non. L'état visuel du widget n'affecte pas la soumission du formulaire. Tant que les trois valeurs sont dans les données du formulaire, le serveur les valide quelle que soit l'apparence du widget.

Puis-je injecter des valeurs GeeTest sans navigateur ?

Oui, si le site accepte un HTTP POST direct avec les trois valeurs. Interceptez le point de terminaison de soumission du formulaire et envoyez les valeurs via requests ou n'importe quel client HTTP.

Pourquoi GeeTest utilise-t-il trois valeurs distinctes au lieu d'un jeton ?

Les trois valeurs servent à des fins différentes : geetest_challenge suit la session, geetest_validate prouve que le défi a été résolu et geetest_seccode fournit un hachage pour la détection de falsification.

Articles connexes

Prochaines étapes

Injectez les solutions GeeTest dans n'importe quel framework -récupérez votre clé API CaptchaAIet commencez à résoudre.

Les commentaires sont désactivés pour cet article.