GeeTest v3 ne se valide pas avec un seul token. Le widget enchaîne trois échanges — enregistrement côté serveur, résolution dans le navigateur, validation finale — et chacun renvoie ses propres paramètres, à relier dans le bon ordre. Pour le résoudre avec CaptchaAI, il faut savoir quel paramètre extraire, quand, et lesquels réinjecter.
La différence avec reCAPTCHA tient là : GeeTest sépare l'identité du site (gt, stable) du jeton de session (challenge, à usage unique). D'où la plupart des échecs d'intégration : un challenge réutilisé ou expiré fait rejeter la soumission, même quand la résolution était correcte.
Où vous croisez GeeTest v3
Répandu sur les plateformes d'Asie de l'Est, GeeTest se rencontre aussi côté francophone : place de marché à surveiller, portail partenaire, tunnel de connexion à valider en recette. Une suite de tests QA qui rejoue une inscription en staging bute sur le curseur GeeTest v3 à chaque tentative. Réflexe RGPD : ne collectez que les données utiles au test.
Trois échanges, pas un seul token
Le protocole se joue en deux temps. D'abord, le backend contacte GeeTest pour ouvrir un défi et récupérer ses paramètres :
Site Backend → GeeTest Server: "Give me a challenge for this user"
GeeTest Server → Site Backend: { gt, challenge, new_captcha }
Site Backend → Browser: Passes gt and challenge to the page
Ensuite, le navigateur affiche le défi, le solveur le résout, puis le serveur valide le résultat :
Browser: Renders slider/puzzle using gt + challenge
User: Solves the challenge
Browser → Site Backend: { geetest_challenge, geetest_validate, geetest_seccode }
Site Backend → GeeTest Server: Verifies the three values
GeeTest Server → Site Backend: { result: "success" }
En résumé : gt et challenge entrent, trois valeurs geetest_* en ressortent pour le backend.
Le flux, étape par étape
Étape 1 — l'appel d'enregistrement
Le backend interroge l'endpoint d'enregistrement de GeeTest :
GET https://api.geetest.com/register.php?gt=GT_ID&json_format=1
Réponse :
{
"success": 1,
"gt": "81dc9bdb52d04dc20036dbd8313ed055",
"challenge": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"new_captcha": true
}
Trois champs comptent ici :
gt— le GeeTest ID, qui identifie le compte GeeTest du site ;challenge— le jeton de défi propre à cette session ;new_captcha— un indicateur du format à utiliser.
Surtout, challenge est à usage unique et limité dans le temps : chaque chargement de page en génère un nouveau.
Étape 2 — le rendu du widget et les types de défi
Le navigateur reçoit gt et challenge, puis initialise le widget :
initGeetest({
gt: "81dc9bdb52d04dc20036dbd8313ed055",
challenge: "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
offline: false,
new_captcha: true,
product: "float"
}, function(captchaObj) {
captchaObj.appendTo('#captcha-container');
captchaObj.onSuccess(function() {
var result = captchaObj.getValidate();
// result contains: geetest_challenge, geetest_validate, geetest_seccode
});
});
Le format affiché dépend de la configuration du site et du profil de risque de l'utilisateur.
| Type de défi | Action attendue | Description |
|---|---|---|
| Curseur (slider) | Glisser la pièce du puzzle | Déplacer la pièce pour reconstituer l'image |
| Clic sur icônes | Cliquer les icônes dans l'ordre | Sélectionner des icônes précises dans la séquence affichée |
| Clic sur caractères | Cliquer les caractères | Cliquer des caractères chinois dans le bon ordre |
| Spatial | Cliquer / sélectionner | Défi de raisonnement spatial |
Étape 3 — les trois valeurs de sortie et la vérification
Une fois le défi résolu, le widget produit trois valeurs :
{
"geetest_challenge": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6xy",
"geetest_validate": "abc123def456_validate",
"geetest_seccode": "abc123def456_validate|jordan"
}
Chacune a un rôle précis :
geetest_challenge— le jeton de défi modifié (original + 2 caractères) ;geetest_validate— le hachage de validation ;geetest_seccode— le code de sécurité (validate suivi du suffixe|jordan).
Le backend transmet ces trois valeurs à GeeTest pour validation :
POST https://api.geetest.com/validate.php
seccode=abc123def456_validate|jordan
&challenge=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6xy
&sdk=geetest-python-3.0.0
GeeTest répond :
{
"seccode": "abc123def456_validate",
"validate": "abc123def456_validate"
}
Récupérer gt et challenge depuis la page
Avant de déléguer la résolution à CaptchaAI, il vous faut gt et challenge extraits de la page. Trois approches, de la plus fiable à la plus opportuniste : intercepter la réponse d'enregistrement, lire le DOM, ou parser l'appel initGeetest.
Méthode 1 — intercepter la réponse d'enregistrement
Écoutez le réseau et captez les deux valeurs à la source :
from playwright.sync_api import sync_playwright
import json
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
geetest_params = {}
def handle_response(response):
if "register" in response.url and "geetest" in response.url:
data = response.json()
geetest_params["gt"] = data.get("gt")
geetest_params["challenge"] = data.get("challenge")
page.on("response", handle_response)
page.goto("https://example.com/login")
# Wait for GeeTest to load
page.wait_for_selector(".geetest_holder")
print(f"gt: {geetest_params.get('gt')}")
print(f"challenge: {geetest_params.get('challenge')}")
Méthode 2 — lire le DOM
Si les valeurs sont dans des attributs data-*, un evaluate suffit :
gt = page.evaluate("() => document.querySelector('[data-gt]')?.dataset.gt")
challenge = page.evaluate("() => document.querySelector('[data-challenge]')?.dataset.challenge")
Méthode 3 — parser l'appel initGeetest
Sinon, récupérez-les directement dans la source :
import re
source = page.content()
gt_match = re.search(r"gt['\"]?\s*[:=]\s*['\"]([a-f0-9]{32})['\"]", source)
challenge_match = re.search(r"challenge['\"]?\s*[:=]\s*['\"]([a-f0-9]{32})['\"]", source)
Résoudre le défi avec l'API CaptchaAI
Avec gt et challenge, envoyez-les à CaptchaAI :
POST https://ocr.captchaai.com/in.php
key=YOUR_API_KEY
&method=geetest
>=81dc9bdb52d04dc20036dbd8313ed055
&challenge=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
&pageurl=https://example.com/login
&json=1
Interrogez ensuite le résultat régulièrement (polling) :
GET https://ocr.captchaai.com/res.php?key=YOUR_API_KEY&action=get&id=TASK_ID&json=1
CaptchaAI renvoie les trois valeurs attendues, prêtes à injecter dans le formulaire :
{
"status": 1,
"request": {
"geetest_challenge": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6xy",
"geetest_validate": "abc123def456_validate",
"geetest_seccode": "abc123def456_validate|jordan"
}
}
Dépannage
| Problème | Cause | Correctif |
|---|---|---|
La valeur challenge est vide |
L'enregistrement a échoué | Vérifiez que le site charge bien GeeTest |
| Solution refusée | challenge expiré |
Extrayez un challenge frais et résolvez-le aussitôt |
Mauvaise valeur gt |
Plusieurs widgets GeeTest sur la page | Extrayez gt du bon widget |
| Trois valeurs reçues mais le formulaire ne part pas | Champs de formulaire manquants | Injectez les trois valeurs dans les bons champs |
Mode en ligne et mode hors ligne
GeeTest v3 embarque un mode de repli quand il ne joint pas ses serveurs ; le champ success de l'enregistrement indique lequel s'applique. En mode hors ligne, le défi est généré localement et la validation allégée, mais les sites de production restent en ligne.
| Mode | Valeur success |
Comportement |
|---|---|---|
| En ligne | 1 |
Défi-réponse normal avec les serveurs GeeTest |
| Hors ligne | 0 |
Vérification locale simplifiée |
Questions fréquentes
Quelle différence entre GeeTest v3 et v4 pour l'intégration ?
GeeTest v4 change le protocole et les paramètres échangés. CaptchaAI prend en charge GeeTest v3 (méthode geetest) ; GeeTest v4 est annoncé comme à venir, pas encore disponible. Ce guide se limite au v3.
Faut-il un proxy pour résoudre GeeTest v3 avec l'API ?
Pas systématiquement : gt, challenge et l'URL suffisent souvent. Si le site filtre par géographie ou par IP, un proxy résidentiel côté navigateur aide — mais cela relève de votre collecte, pas de l'appel API.
Combien de threads faut-il pour traiter GeeTest v3 en volume ?
CaptchaAI facture au thread concurrent, résolutions illimitées par thread : un thread traite un défi à la fois puis enchaîne. Le plan BASIC ($15/mois, 5 threads) suffit pour démarrer, puis montez selon votre débit.
Pourquoi le site refuse-t-il parfois une solution correcte ?
Presque toujours une question de temps. Le challenge expire vite : un délai trop long entre extraction et soumission fait échouer la validation. Extrayez au dernier moment, résolvez sans attendre, injectez aussitôt.
Articles connexes
- Résoudre GeeTest v3 avec Node.js
- Intégrer GeeTest v3 en Node.js avec CaptchaAI
- L'API d'évaluation reCAPTCHA Enterprise en détail
Prochaines étapes
Passez à la pratique : récupérez votre clé API CaptchaAI et branchez la réponse à trois valeurs dans votre workflow.