Périmètre sûr : Ce guide s'applique à vos propres applications et environnements (QA, préproduction, production) ou à des systèmes pour lesquels vous disposez d'une autorisation écrite. Il ne couvre ni l'automatisation de sites tiers, ni les techniques d'anti-détection.
Stagehand sait cliquer, remplir un formulaire et extraire des données à partir d'instructions en langage naturel — mais il ne franchit pas un défi CAPTCHA, parce qu'un CAPTCHA n'est pas une action d'interface : c'est un token à obtenir ailleurs. La réponse tient en une ligne d'architecture : l'agent met le scénario en pause, un composant serveur appelle l'API CaptchaAI, récupère le token, le réinjecte dans la même session navigateur, puis l'agent reprend la main.
Pourquoi un agent Stagehand se bloque sur un défi CAPTCHA
Stagehand s'appuie sur Playwright : vous décrivez l'intention, l'agent la traduit en actions sur la page. Ce modèle fonctionne tant que l'élément visé est manipulable. Un widget reCAPTCHA v2 ou Cloudflare Turnstile ne l'est pas : il vit dans une iframe, son état réel est un champ caché (g-recaptcha-response, cf-turnstile-response), et c'est ce champ que le backend vérifie — pas le pixel cliqué.
La règle pratique : sortez la résolution du périmètre de l'agent et traitez-la comme un appel de service.
Architecture : où insérer CaptchaAI dans la boucle
Trois composants, une seule responsabilité chacun :
- L'agent Stagehand détecte le widget et relève les deux paramètres utiles : le sitekey et l'URL de la page.
- Un service interne reçoit ces paramètres, appelle CaptchaAI en HTTPS et renvoie le token. C'est lui qui porte la clé API, le retry et le timeout.
- L'agent injecte le token dans le champ caché, dans la même session que celle qui a déclenché le défi, puis soumet le formulaire.
Cette séparation évite d'exposer la clé API au contexte navigateur : le service se teste sans navigateur, l'agent avec un token factice.
Appeler l'API CaptchaAI depuis votre service
Exemple d'appel HTTP côté serveur dans votre propre service :
import fetch from 'node-fetch';
const API_KEY = process.env.CAPTCHAAI_KEY;
export async function createTurnstileTask(siteKey, pageUrl) {
const res = await fetch('https://api.captchaai.com/createTask', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
clientKey: API_KEY,
task: {
type: 'TurnstileTaskProxyless',
websiteURL: pageUrl,
websiteKey: siteKey,
},
}),
});
const data = await res.json();
return data.taskId;
}
L'appel renvoie un identifiant de tâche ; le polling démarre après une quinzaine de secondes, puis toutes les 5 s. Bornez le polling à 120 s par tâche : une boucle infinie masque les erreurs de paramètre.
Réinjecter le token dans la même session
Le rejet le plus fréquent après une résolution réussie ne vient pas du solveur, mais de la session : si l'agent a ouvert un nouveau contexte navigateur entre-temps, les cookies ne correspondent plus et le backend refuse le token.
Gardez donc le même contexte Playwright du début à la fin, injectez la valeur dans le champ caché, puis déclenchez l'événement attendu par le widget. Si la page utilise un callback JavaScript, appelez-le explicitement : beaucoup de formulaires n'activent le bouton de soumission qu'à ce moment-là.
Gestion de la clé API et des secrets
La clé CaptchaAI vit dans un coffre — HashiCorp Vault, AWS Secrets Manager, Azure Key Vault — ou dans un secret CI, monté en variable d'environnement au runtime. Elle n'apparaît jamais dans le dépôt, ni dans un .env versionné, ni dans le contexte navigateur.
Observabilité, journalisation et RGPD
Instrumentez chaque appel : durée d'obtention du token, code retour HTTP, identifiant de tâche et profondeur de la file d'attente. Ces quatre signaux distinguent une lenteur réseau d'une erreur de paramètre, surtout corrélés à votre traçage distribué (OpenTelemetry).
Sur le tableau de bord, affichez la latence médiane et p95, le taux de réussite par type de CAPTCHA, et l'écart entre « token obtenu » et « formulaire accepté » — le seul indicateur qui signale un problème de session avant vos utilisateurs.
Côté conformité, appliquez le principe de minimisation du RGPD : journalisez le sitekey, l'URL de la page et l'identifiant de tâche, jamais le contenu des formulaires.
Scénario : un parc d'agents hébergé en Europe
Une équipe QA basée à Lyon fait tourner ses scénarios Stagehand sur deux instances OVHcloud, avec une troisième sur Scaleway pour les tests de bascule. Le service de résolution est déployé dans la même région : la co-localisation simplifie les règles de pare-feu.
Le parc exécute une centaine de scénarios nocturnes, dont une quinzaine traversent un formulaire protégé par Turnstile. Au pic, deux à trois résolutions seulement sont en vol simultanément : le dimensionnement se joue sur la concurrence, pas sur le volume mensuel.
Coûts et dimensionnement des threads
CaptchaAI facture au thread simultané, avec un nombre de résolutions illimité par thread sur le mois. Un thread correspond à un défi en cours de traitement : dès qu'il se termine, il reprend le suivant.
La suite nocturne décrite plus haut tient donc sur le plan BASIC ($15/mois, 5 threads) ; un parc continu avec des pics de plusieurs dizaines de scénarios parallèles se dimensionne plutôt sur ADVANCE ($90/mois, 50 threads).
Types couverts sans changer une ligne de plomberie : reCAPTCHA v2, reCAPTCHA v3, Cloudflare Turnstile, Cloudflare Challenge, GeeTest v3, CAPTCHA image, OCR et grilles d'images. CaptchaFox (bêta), Friendly Captcha (bêta) et Lemin (bêta) restent en bêta.
Liste de contrôle avant mise en production
- Le périmètre reste limité à vos propres applications ou à des sources autorisées.
- La clé CaptchaAI est stockée dans un coffre ou un secret CI, jamais dans le code source.
- Le token est injecté dans le contexte Playwright qui a déclenché le défi.
- Le polling est borné : premier appel à 15 s, intervalle de 5 s, plafond de 120 s.
- Une stratégie de retry idempotent avec backoff exponentiel borné couvre les erreurs transitoires.
- Latence, taux de réussite et taux d'acceptation en aval sont tracés séparément, sans donnée personnelle.
FAQ
Stagehand peut-il résoudre un CAPTCHA avec une simple instruction en langage naturel ?
Non. L'agent localise le widget et lit son sitekey, mais la validation repose sur un token vérifié côté serveur, obtenu par un appel d'API externe.
Où exactement injecter le token quand Stagehand pilote la page ?
Dans le champ caché attendu par le widget — g-recaptcha-response pour reCAPTCHA, cf-turnstile-response pour Turnstile — puis déclenchez le callback avant de soumettre. Un token injecté dans une autre session sera refusé.
CaptchaAI prend-il en charge hCaptcha ou FunCaptcha dans ce type d'agent ?
Non — ces deux familles ne sont pas prises en charge. GeeTest v4 est annoncé comme à venir et ne doit pas figurer dans votre plan d'intégration aujourd'hui. Si un formulaire interne utilise ces protections, prévoyez un chemin de test alternatif.
Combien de threads faut-il pour un parc de plusieurs agents ?
Comptez les défis simultanés au pic, pas le total mensuel : chaque scénario en attente de token occupe un thread. Une suite nocturne modeste tient sur 5 threads ; un parc continu demande un palier supérieur.
Guides connexes
- Le démarrage rapide CaptchaAI
- Tester les CAPTCHA en environnement autorisé
- Valider l'endpoint API sur vos formulaires
- Intégrer la résolution CAPTCHA à votre CI
- Résoudre reCAPTCHA v2 via l'API
Votre agent Stagehand mérite une étape CAPTCHA aussi prévisible que le reste du scénario. – Obtenez votre clé CaptchaAI.