Sur un portail de rendez-vous visa BLS — par exemple depuis Casablanca, Alger ou Tunis — le CAPTCHA n'est presque jamais le vrai obstacle : c'est l'horloge de session qui l'entoure. Tout se joue avant que le portail n'invalide vos cookies. L'API CaptchaAI prend en charge les BLS CAPTCHA avec un taux de réussite élevé et une résolution de l'ordre de la seconde, ce qui laisse une marge confortable pour boucler la démarche en Python ou Node.js, en trois temps :
- Chargez la page du portail et récupérez l'image du CAPTCHA dans la même session.
- Envoyez l'image à l'API CaptchaAI avec le bon code
instructions, puis interrogez le résultat. - Réinjectez la réponse dans le formulaire avant l'expiration de la session.
Périmètre : n'automatisez que votre propre démarche, sur un environnement autorisé. Côté données, gardez le réflexe RGPD et ne saisissez que les informations nécessaires à votre dossier.
Où et sous quelle forme apparaissent les BLS CAPTCHA
Les BLS CAPTCHA gardent les créneaux les plus disputés. Voici où ils surgissent, et sous quelles formes.
| Type de portail | Emplacement CAPTCHA | Objectif |
|---|---|---|
| Prise de rendez-vous pour visa | Avant la sélection du créneau | Empêcher la prise de rendez-vous automatisée |
| Formulaires de téléchargement de documents | Avant la soumission | Vérifier l'interaction humaine |
| Vérification de l'état du rendez-vous | Avant d'afficher l'état | Contrôles automatisés avec limite de débit |
| Formulaires de candidature | Avant la soumission du formulaire | Empêcher les soumissions automatisées |
| Variante du défi | Ce que vous transmettez à CaptchaAI |
|---|---|
| Texte déformé | L'image, à retranscrire caractère par caractère |
| Expression mathématique | L'image et un code instructions de calcul |
| Sélection d'images | L'image et les instructions de sélection |
| Puzzle textuel | L'image et la consigne associée |
Résoudre un BLS CAPTCHA avec l'API CaptchaAI
Gardez la même session du début à la fin : les trois étapes ci-dessous partagent les mêmes cookies, faute de quoi le portail rejette la soumission.
Étape 1 — récupérez l'image du CAPTCHA dans la session en cours, qu'elle soit inline en base64 ou référencée par une URL.
import requests
from bs4 import BeautifulSoup
import base64
session = requests.Session()
# Load the portal page
page = session.get("https://portal.example.gov/appointment")
soup = BeautifulSoup(page.text, "html.parser")
# Find the CAPTCHA image
captcha_img = soup.select_one("img#captcha-image, img.captcha")
captcha_url = captcha_img["src"]
# Download the CAPTCHA image
if captcha_url.startswith("data:"):
# Base64 encoded inline image
img_data = captcha_url.split(",")[1]
else:
# URL-referenced image
img_response = session.get(captcha_url)
img_data = base64.b64encode(img_response.content).decode()
Étape 2 — envoyez l'image à CaptchaAI avec le code instructions adapté, puis interrogez le résultat jusqu'à la réponse.
import time
def solve_bls_captcha(image_base64, instructions=""):
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "base64",
"body": image_base64,
"instructions": instructions,
"json": 1
})
task_id = resp.json()["request"]
for _ in range(30):
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"]
raise TimeoutError("BLS solve timed out")
# Solve
captcha_answer = solve_bls_captcha(img_data)
Étape 3 — réinjectez la réponse dans le formulaire, sur la même session pour conserver les cookies.
# Find form fields
form_data = {
"captcha_response": captcha_answer,
"appointment_type": "visa",
"location": "embassy-city",
# ... other form fields
}
# Submit with the same session (cookies preserved)
result = session.post(
"https://portal.example.gov/appointment/submit",
data=form_data
)
if "success" in result.text.lower():
print("Form submitted successfully")
Composer avec les particularités des portails gouvernementaux
Les habitudes des portails publics — pas le CAPTCHA — font échouer la plupart des scripts. Trois motifs à anticiper.
Formulaires multi-étapes : le CAPTCHA n'apparaît qu'à la dernière étape, après le choix du créneau.
# Step 1: Select service type
session.post(url, data={"service": "passport"})
# Step 2: Fill personal details
session.post(url, data={"name": "...", "dob": "..."})
# Step 3: Select appointment slot
session.post(url, data={"slot": "2026-04-10-09:00"})
# Step 4: Solve CAPTCHA and confirm
captcha_answer = solve_bls_captcha(get_captcha_image(session))
session.post(url, data={"captcha": captcha_answer, "confirm": "true"})
Régénération après erreur : récupérez un défi neuf à chaque réponse refusée, jamais l'ancien.
max_attempts = 3
for attempt in range(max_attempts):
# Get fresh CAPTCHA for each attempt
captcha_image = get_captcha_image(session)
answer = solve_bls_captcha(captcha_image)
result = session.post(submit_url, data={"captcha": answer})
if "incorrect" not in result.text.lower():
break
print(f"Attempt {attempt + 1} — CAPTCHA refreshed, retrying")
Sessions à durée limitée : surveillez le chrono et repartez d'une session propre avant l'expiration.
import time
session_start = time.time()
SESSION_TIMEOUT = 600 # 10 minutes typical
def check_session_valid():
elapsed = time.time() - session_start
if elapsed > SESSION_TIMEOUT - 60: # 1 min safety margin
print("Session expiring — refresh needed")
return False
return True
# Before CAPTCHA submission
if not check_session_valid():
# Start a fresh session
session = requests.Session()
session.get(portal_url)
session_start = time.time()
Automatiser un portail à rendu JavaScript avec Puppeteer
Certains portails ne rendent le formulaire qu'après exécution de JavaScript. Pilotez alors un navigateur headless et lisez l'image du CAPTCHA dans le DOM. Le script ci-dessous la capture depuis un canvas, la résout, saisit la réponse et valide.
const puppeteer = require('puppeteer');
async function handleBLSPortal() {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://portal.example.gov/appointment');
// Wait for CAPTCHA to load
await page.waitForSelector('img#captcha-image');
// Get CAPTCHA image as base64
const imgBase64 = await page.evaluate(() => {
const img = document.querySelector('img#captcha-image');
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
return canvas.toDataURL('image/png').split(',')[1];
});
// Solve with CaptchaAI
const answer = await solveBLSCaptcha(imgBase64);
// Type the answer
await page.type('#captcha-input', answer);
// Submit
await page.click('#submit-button');
// Wait for result
await page.waitForNavigation();
}
Préserver l'état de session
Les portails gouvernementaux sont intraitables sur la session : ces réflexes évitent l'essentiel des rejets.
| Exigence | Mise en œuvre |
|---|---|
| Conserver les cookies à l'identique | Utilisez requests.Session() ou le contexte persistant du navigateur |
| Rester sous les limites de débit | Ajoutez des délais entre les chargements de pages (2 à 5 secondes) |
| Gérer les jetons CSRF | Extrayez et réinjectez les jetons CSRF dans chaque POST |
| Respecter les délais d'expiration | Terminez chaque workflow dans la fenêtre de session |
| Suivre les chaînes de redirection | Autorisez les redirections automatiques dans votre client HTTP |
Dépannage
| Problème | Cause | Correctif |
|---|---|---|
| « Session expirée » après résolution | Trop de temps entre résolution et soumission | Résolvez le CAPTCHA juste avant d'envoyer le formulaire |
| L'image CAPTCHA ne se charge pas | En-tête Referer spécifique attendu | Positionnez le Referer sur l'URL de la page du portail |
| Réponse correcte mais formulaire rejeté | Jeton CSRF manquant ou champ masqué oublié | Extrayez toutes les entrées masquées du formulaire |
| Blocage après plusieurs tentatives | Limitation de débit | Espacez les tentatives et faites pivoter les IP si besoin |
| CAPTCHA différent à chaque appel | Le portail régénère le défi par requête | Récupérez une image neuve et résolvez à chaque fois |
FAQ
Pourquoi le formulaire est-il rejeté alors que la réponse CAPTCHA est correcte ?
Le plus souvent, il manque un jeton CSRF ou un champ masqué. Ces portails cachent des input type="hidden" exigés à la soumission : réinjectez chaque champ caché, pas seulement la réponse CAPTCHA.
Comment gérer le renouvellement du CAPTCHA après une réponse refusée ?
Ne rejouez jamais l'ancienne image : à chaque échec, le portail génère un nouveau défi. Récupérez une image fraîche à chaque itération, comme dans la boucle max_attempts montrée plus haut.
Quels types de défis BLS l'API CaptchaAI prend-elle en charge ?
Les quatre familles courantes : texte déformé, expressions mathématiques, sélection d'images et grilles. Le champ instructions oriente la résolution, qui reste de l'ordre de la seconde.
Articles connexes
- Résoudre un BLS CAPTCHA étape par étape
- Résoudre un BLS CAPTCHA en Node.js
- Comprendre la logique de grille des BLS CAPTCHA
Prochaines étapes
Intégrez la résolution des BLS CAPTCHA à vos portails de rendez-vous — récupérez votre clé API CaptchaAI et lancez votre premier appel en quelques minutes.