Le vrai obstacle, quand vous automatisez une connexion protégée par CAPTCHA, n'est pas le défi lui-même : c'est de garder la session vivante autour de lui. Vous devez résoudre le CAPTCHA, réinjecter le token, puis soumettre le formulaire sans perdre au passage les cookies ni le token CSRF. CaptchaAI prend en charge la résolution du défi ; votre script orchestre le reste — chargement de la page, saisie des identifiants, envoi et maintien de la session authentifiée.
Un exemple concret : une équipe QA à Lyon doit rejouer chaque nuit le parcours de connexion d'une application interne pour vérifier qu'une mise à jour n'a rien cassé. Le formulaire est protégé par Cloudflare Turnstile. Plutôt que de désactiver la protection en préproduction — ce qui rendrait le test infidèle à la production — l'équipe laisse CaptchaAI résoudre le widget. Côté RGPD, la règle est simple : réservez les identifiants de test à des comptes dédiés et ne journalisez jamais de mot de passe réel.
Périmètre sûr : n'automatisez que des comptes et des environnements que vous êtes autorisé à tester. CaptchaAI résout le défi ; l'autorisation d'accès, elle, reste votre responsabilité.
Garder la session et le token CSRF intacts
Résoudre le CAPTCHA ne sert à rien si la session se perd juste après. Trois réflexes évitent la plupart des échecs de connexion automatisée :
- Réutilisez un seul objet session —
requests.Session()ou l'instance de navigateur — du chargement de la page jusqu'à la dernière requête authentifiée. - Relevez et rejouez tous les champs cachés du formulaire, token CSRF compris : ils sont souvent régénérés à chaque affichage de la page.
- Enchaînez résolution et soumission sans latence inutile ; un token laissé de côté quelques minutes est déjà périmé côté serveur.
Méthode 1 : connexion via requêtes HTTP, sans navigateur
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_recaptcha(site_key, page_url):
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY, "method": "userrecaptcha",
"googlekey": site_key, "pageurl": page_url
})
task_id = resp.text.split("|")[1]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id
})
if result.text == "CAPCHA_NOT_READY": continue
if result.text.startswith("OK|"): return result.text.split("|")[1]
raise Exception(result.text)
raise TimeoutError()
# Login flow
session = requests.Session()
login_url = "https://example.com/login"
# Load login page to get cookies and site key
page = session.get(login_url)
# Extract site_key from the page HTML...
site_key = "6Le-wvkS..."
# Solve CAPTCHA
token = solve_recaptcha(site_key, login_url)
# Submit login form
resp = session.post(login_url, data={
"username": "user@example.com",
"password": "your_password",
"g-recaptcha-response": token
})
if resp.url != login_url:
print("Login successful!")
# session now has auth cookies for subsequent requests
Le point clé : c'est la même requests.Session() qui charge la page, résout le défi et poste le formulaire. Les cookies posés à l'arrivée restent disponibles pour toutes les requêtes authentifiées qui suivent.
Méthode 2 : connexion pilotée par Selenium en 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
import requests
import time
API_KEY = "YOUR_API_KEY"
options = webdriver.ChromeOptions()
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(options=options)
# Navigate to login page
driver.get("https://example.com/login")
wait = WebDriverWait(driver, 10)
# Fill in credentials
username_field = wait.until(EC.presence_of_element_located((By.NAME, "username")))
username_field.send_keys("user@example.com")
driver.find_element(By.NAME, "password").send_keys("your_password")
# Extract site key and solve
recaptcha = driver.find_element(By.CLASS_NAME, "g-recaptcha")
site_key = recaptcha.get_attribute("data-sitekey")
token = solve_recaptcha(site_key, driver.current_url)
# Inject token
driver.execute_script(
f"document.getElementById('g-recaptcha-response').innerHTML = '{token}';"
)
# Submit
driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click()
wait.until(EC.url_changes(driver.current_url))
print(f"Logged in! Now at: {driver.current_url}")
Ici, le navigateur relève le sitekey directement dans le DOM, puis réinjecte le token dans le champ g-recaptcha-response avant de cliquer sur le bouton d'envoi. C'est la voie la plus robuste dès que la page dépend fortement de JavaScript : rendu dynamique, champs injectés à la volée ou widget chargé après coup.
Méthode 3 : connexion automatisée avec Puppeteer en Node.js
const puppeteer = require("puppeteer");
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
async function solveRecaptcha(siteKey, pageUrl) {
const submit = await axios.get("https://ocr.captchaai.com/in.php", {
params: {
key: API_KEY,
method: "userrecaptcha",
googlekey: siteKey,
pageurl: pageUrl,
},
});
const taskId = submit.data.split("|")[1];
while (true) {
await new Promise((r) => setTimeout(r, 5000));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId },
});
if (result.data === "CAPCHA_NOT_READY") continue;
if (result.data.startsWith("OK|")) return result.data.split("|")[1];
throw new Error(result.data);
}
}
(async () => {
const browser = await puppeteer.launch({ headless: "new" });
const page = await browser.newPage();
await page.goto("https://example.com/login");
// Fill credentials
await page.type("#username", "user@example.com");
await page.type("#password", "your_password");
// Get site key and solve
const siteKey = await page.$eval(".g-recaptcha", (el) =>
el.getAttribute("data-sitekey")
);
const token = await solveRecaptcha(siteKey, page.url());
// Inject and submit
await page.evaluate(
(t) => (document.getElementById("g-recaptcha-response").innerHTML = t),
token
);
await page.click('button[type="submit"]');
await page.waitForNavigation();
console.log("Logged in:", page.url());
await browser.close();
})();
Enchaîner CAPTCHA et MFA dans un même parcours
# Step 1: Solve CAPTCHA and submit login
token = solve_recaptcha(site_key, login_url)
resp = session.post(login_url, data={
"username": "user@example.com",
"password": "your_password",
"g-recaptcha-response": token
})
# Step 2: Handle MFA page (if redirected)
if "verify" in resp.url or "mfa" in resp.url:
# Your MFA code logic here
mfa_code = get_mfa_code()
resp = session.post(resp.url, data={"code": mfa_code})
# Step 3: Verify logged in
assert "dashboard" in resp.url
Beaucoup de pages affichent d'abord le CAPTCHA, puis redirigent vers une vérification en deux facteurs. Traitez chaque redirection comme une étape du même parcours : détectez la page MFA, récupérez le code depuis votre source de test et renvoyez-le sur la session déjà authentifiée, sans repartir de zéro.
Dépannage
| Problème | Cause probable | Correctif |
|---|---|---|
| Retour à l'écran de connexion avec un nouveau CAPTCHA | Token expiré avant la soumission | Résolvez puis envoyez le formulaire dans la foulée, sans étape lente entre les deux |
| « Identifiants invalides » alors qu'ils sont corrects | Champ caché ou token CSRF absent du POST | Relevez tous les champs cachés de la page et rejouez-les à l'identique |
| Session perdue juste après la connexion | Cookies non conservés entre les requêtes | Réutilisez la même requests.Session() ou l'instance de navigateur |
| reCAPTCHA v3 bloque encore la connexion | Score trop faible ou mauvais paramètre action |
Vérifiez le paramètre action et le contexte exact de la soumission |
Quelle méthode CaptchaAI pour quel type de CAPTCHA
Pour choisir rapidement l'appel API selon le défi rencontré sur l'écran de connexion :
| Type de CAPTCHA | À quoi il ressemble sur l'écran de connexion | Méthode CaptchaAI |
|---|---|---|
| reCAPTCHA v2 | Case à cocher ou défi visuel avant l'envoi | method=userrecaptcha |
| reCAPTCHA v3 | Score invisible, bloque les sessions à faible score | method=userrecaptcha&version=v3 |
| Cloudflare Turnstile | Widget affiché avant le formulaire de connexion | method=turnstile |
| Image CAPTCHA | Image de texte à recopier | method=base64 |
FAQ
reCAPTCHA v3 bloque toujours la connexion malgré un token valide, que faire ?
Le token est valide, mais son score reste sous le seuil exigé côté serveur. Deux points sont à vérifier en priorité :
- Le paramètre
action: il doit correspondre exactement à celui que la page attend au moment de la connexion. - Le contexte de soumission : reCAPTCHA v3 note le comportement de la session, pas seulement la validité technique du token.
Combien de temps ai-je pour soumettre le token après la résolution ?
Peu de temps : un token reCAPTCHA reste généralement valide moins de deux minutes. Résolvez le CAPTCHA juste avant d'envoyer le formulaire et évitez toute étape lente entre la résolution et la soumission, sinon le serveur régénère un défi et la connexion échoue.
Comment gérer une étape MFA qui suit le CAPTCHA ?
Traitez-la comme une étape de plus du parcours, jamais comme un cas à part. Le chaînage tient en trois temps :
- Soumettez le login avec le token, puis détectez la redirection vers la page MFA.
- Récupérez le code depuis votre source : application TOTP ou boîte mail de test.
- Postez-le sur la session déjà authentifiée, sans repartir de zéro.
Automatiser une connexion protégée par CAPTCHA, est-ce autorisé ?
Cela dépend de votre autorisation d'accès au compte et au service visés. CaptchaAI résout uniquement le défi ; la responsabilité de l'usage reste la vôtre. Limitez-vous aux comptes et environnements que vous êtes habilité à tester, et vérifiez vos obligations RGPD dès que des données personnelles entrent en jeu.
Guides connexes
- Résoudre les CAPTCHA avec le Chrome DevTools Protocol
- Automatiser un navigateur avec Puppeteer et CaptchaAI
- Gérer les CAPTCHA avec Playwright