Vous cherchez un script prêt à copier pour résoudre un CAPTCHA sans réécrire toute la logique d'appel à l'API à chaque projet ? Cette page rassemble cinq scripts d'automatisation CAPTCHA complets — reCAPTCHA v2, Cloudflare Turnstile, CAPTCHA image, résolution par lots et un solveur universel Node.js — plus un utilitaire pour vérifier votre solde. Chacun suit le même schéma face à l'API CaptchaAI : vous soumettez le défi, vous interrogez le résultat, puis vous récupérez le token à injecter dans votre formulaire.
Le schéma commun des scripts d'automatisation CAPTCHA
Tous les scripts reposent sur deux endpoints. Vous envoyez d'abord la tâche à in.php, qui répond OK|<task_id> si la soumission est acceptée. Vous interrogez ensuite res.php avec cet identifiant : tant que la réponse vaut CAPCHA_NOT_READY, la résolution est en cours ; dès qu'elle bascule sur OK|<token>, vous tenez votre token.
Deux détails comptent. Le premier est l'intervalle de polling : cinq secondes entre chaque interrogation évitent de marteler l'API tout en restant réactif. Le second est le plafond de la boucle — for _ in range(60) fixe un timeout implicite de cinq minutes, après quoi le script abandonne proprement plutôt que d'attendre indéfiniment. Retenez aussi que le nom du paramètre de clé change selon le type : googlekey pour reCAPTCHA, sitekey pour Turnstile. Le reste du flux est identique.
Script 1 — résoudre reCAPTCHA v2 en Python
Le script le plus courant. Il prend le site_key et l'URL de la page, soumet la tâche, affiche l'avancement du polling avec des points, puis renvoie le token g-recaptcha-response prêt à injecter.
#!/usr/bin/env python3
"""Solve reCAPTCHA v2 and print the token."""
import requests
import time
import sys
API_KEY = "YOUR_API_KEY"
def solve_recaptcha_v2(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
})
if not resp.text.startswith("OK|"):
print(f"Error: {resp.text}", file=sys.stderr)
sys.exit(1)
task_id = resp.text.split("|")[1]
print(f"Task ID: {task_id}")
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":
print(".", end="", flush=True)
continue
if result.text.startswith("OK|"):
print()
return result.text.split("|")[1]
print(f"\nError: {result.text}", file=sys.stderr)
sys.exit(1)
print("\nTimeout", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <site_key> <page_url>")
sys.exit(1)
token = solve_recaptcha_v2(sys.argv[1], sys.argv[2])
print(token)
Lancez-le en ligne de commande avec le sitekey et l'URL cible :
python solve_recaptcha.py "6Le-wvkS..." "https://example.com/form"
Script 2 — résoudre Cloudflare Turnstile
Même logique, avec method="turnstile" et le paramètre sitekey. La version ci-dessous est volontairement compacte : elle lève une exception en cas d'erreur plutôt que d'écrire sur la sortie standard, ce qui la rend facile à appeler depuis un autre module.
#!/usr/bin/env python3
"""Solve Cloudflare Turnstile and print the token."""
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_turnstile(site_key, page_url):
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "turnstile",
"sitekey": 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()
token = solve_turnstile("0x4AAAAA...", "https://example.com")
print(token)
Script 3 — résoudre un CAPTCHA image (OCR)
Pour les CAPTCHA image et texte, la tâche part en method="base64". Le script accepte indifféremment un fichier local ou une URL, encode l'image en base64, puis interroge le résultat. La boucle est plus courte ici (range(30)) car l'OCR répond généralement plus vite qu'un défi interactif.
#!/usr/bin/env python3
"""Solve an image CAPTCHA from a file or URL."""
import requests
import base64
import time
import sys
API_KEY = "YOUR_API_KEY"
def solve_image(image_source):
# Load image
if image_source.startswith("http"):
img_data = requests.get(image_source).content
else:
with open(image_source, "rb") as f:
img_data = f.read()
img_b64 = base64.b64encode(img_data).decode()
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "base64",
"body": img_b64
})
task_id = resp.text.split("|")[1]
for _ in range(30):
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()
if __name__ == "__main__":
text = solve_image(sys.argv[1])
print(text)
Le script fonctionne aussi bien sur un fichier que sur une URL distante :
python solve_image.py captcha.png
python solve_image.py "https://example.com/captcha.jpg"
Script 4 — résolution par lots avec des threads
Quand vous devez traiter des dizaines de CAPTCHA d'affilée, résolvez-les en parallèle plutôt qu'en série. Le ThreadPoolExecutor lance plusieurs résolutions concurrentes ; chaque tâche récupère son propre token et, en cas d'échec, l'erreur est capturée par tâche sans interrompre le lot. Réglez max_workers sur le nombre de threads de votre offre — nous y revenons plus bas.
#!/usr/bin/env python3
"""Solve multiple CAPTCHAs concurrently."""
import requests
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
API_KEY = "YOUR_API_KEY"
def solve_one(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()
def solve_batch(tasks, max_workers=5):
"""
tasks: list of (site_key, page_url) tuples
Returns: list of tokens
"""
results = []
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {
executor.submit(solve_one, sk, url): (sk, url)
for sk, url in tasks
}
for future in as_completed(futures):
sk, url = futures[future]
try:
token = future.result()
results.append({"url": url, "token": token, "status": "ok"})
except Exception as e:
results.append({"url": url, "error": str(e), "status": "failed"})
return results
# Example
tasks = [
("6Le-wvkS...", "https://example.com/page1"),
("6Le-wvkS...", "https://example.com/page2"),
("6Le-wvkS...", "https://example.com/page3"),
]
results = solve_batch(tasks)
for r in results:
print(f"{r['url']}: {r['status']}")
Script 5 — solveur universel en Node.js
Si votre stack est en JavaScript, ce solveur unique gère n'importe quel type de CAPTCHA : vous lui passez les params (dont method), il s'occupe de la soumission et du polling. Comme il exporte solve via module.exports, vous l'importez directement dans votre code. Les commentaires montrent comment basculer entre reCAPTCHA v2 et Turnstile en changeant simplement les paramètres.
#!/usr/bin/env node
// Solve any CAPTCHA type from the command line
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
async function solve(params) {
params.key = API_KEY;
const submit = await axios.get("https://ocr.captchaai.com/in.php", {
params,
});
if (!submit.data.startsWith("OK|")) throw new Error(submit.data);
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);
}
}
// Usage examples:
// Solve reCAPTCHA v2
// solve({ method: "userrecaptcha", googlekey: "SITE_KEY", pageurl: "URL" })
// Solve Turnstile
// solve({ method: "turnstile", sitekey: "SITE_KEY", pageurl: "URL" })
module.exports = { solve };
Vérifier votre solde CaptchaAI
Un utilitaire d'une ligne utile à intégrer dans vos scripts de supervision. L'action getbalance renvoie votre solde en dollars US ; appelez-le avant un gros lot pour éviter une interruption en cours de route.
#!/usr/bin/env python3
"""Check CaptchaAI account balance."""
import requests
API_KEY = "YOUR_API_KEY"
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "getbalance"
})
print(f"Balance: ${resp.text}")
Dimensionner vos threads et votre budget
Le paramètre max_workers du script par lots ne doit jamais dépasser le nombre de threads de votre offre. CaptchaAI facture au thread concurrent, pas à la résolution : un thread correspond à un CAPTCHA en cours, et dès qu'une résolution se termine, ce thread enchaîne la suivante. L'offre BASIC ($15/mois, 5 threads) autorise donc cinq résolutions simultanées, STANDARD ($30/mois, 15 threads) en autorise quinze, et ENTERPRISE ($300/mois, 200 threads) deux cents. Les résolutions restent illimitées dans le mois quel que soit le plan, sans plafond quotidien ni frais par CAPTCHA — seul le nombre de threads borne votre débit. Commencez avec max_workers=5 sur BASIC, puis montez en fonction de votre offre en surveillant votre solde.
Prenons une équipe QA à Lyon qui rejoue chaque nuit plusieurs centaines de formulaires de connexion en staging : elle déploie ses workers sur une instance OVHcloud ou Scaleway proche de ses cibles, aligne max_workers sur les threads de son offre, et journalise chaque échec renvoyé par solve_batch. Côté conformité, si vos scripts collectent des données au passage, limitez-les au strict nécessaire et vérifiez vos obligations RGPD ; le token renvoyé par l'API ne contient, lui, aucune donnée personnelle.
Quels CAPTCHA ces scripts d'automatisation couvrent-ils ?
Ces scripts ciblent les types que CaptchaAI prend en charge en disponibilité générale : reCAPTCHA v2 (ainsi que v2 Invisible, v2 Enterprise et v3), Cloudflare Turnstile, Cloudflare Challenge, GeeTest v3, et les CAPTCHA image/OCR comme les grilles d'images. Il suffit de changer le method et les paramètres pour passer d'un type à l'autre — c'est exactement ce que fait le solveur universel Node.js.
En revanche, hCaptcha et FunCaptcha (Arkose Labs) ne sont pas pris en charge : n'attendez pas de ces scripts qu'ils les résolvent. GeeTest v4 est annoncé comme à venir, pas encore disponible. Enfin, CaptchaFox (bêta), Friendly Captcha (bêta) et Lemin (bêta) existent en version bêta — à réserver à des tests, sans en attendre les mêmes garanties que les types en disponibilité générale.
FAQ
Pourquoi le résultat reste-t-il bloqué sur CAPCHA_NOT_READY ?
C'est normal au démarrage : la réponse signifie simplement que la résolution est encore en cours. Les scripts interrogent res.php toutes les 5 secondes jusqu'à recevoir OK|token. Si le message persiste au-delà d'une minute, vérifiez votre googlekey/sitekey et l'URL de la page soumise.
Combien de threads faut-il pour le solveur par lots ?
Autant que votre offre en autorise, pas davantage. Fixez max_workers sur le nombre de threads de votre plan — 5 sur BASIC ($15/mois, 5 threads), 200 sur ENTERPRISE ($300/mois, 200 threads). Au-delà, les tâches excédentaires attendent simplement qu'un thread se libère.
Puis-je importer ces fonctions comme modules ?
Oui. Chaque fonction (solve_recaptcha_v2, solve_turnstile, solve_batch…) sert aussi bien d'outil autonome que de bibliothèque importée dans votre propre base de code. Le solveur Node.js exporte déjà solve via module.exports.
Ces scripts gèrent-ils hCaptcha ou GeeTest v4 ?
Non. hCaptcha et FunCaptcha ne sont pas pris en charge, et GeeTest v4 est annoncé comme à venir. Les scripts couvrent reCAPTCHA v2/v3, Cloudflare Turnstile, GeeTest v3 et les CAPTCHA image.
Comment ajuster le délai avant timeout ?
Modifiez le nombre d'itérations de la boucle for _ in range(60) : à 5 secondes par tour, 60 tours donnent 5 minutes. Réduisez-le pour échouer plus vite sur les types rapides, augmentez-le pour laisser du temps aux défis plus lents.