Deux paramètres optionnels décident de la fiabilité d'un BLS CAPTCHA résolu par API : instructions et code. Bien renseignés, ils font la différence entre une réponse acceptée du premier coup et une solution rejetée — un écart qui compte sur les portails de rendez-vous BLS, où chaque soumission de formulaire est précieuse. Ce guide détaille chaque champ de soumission, l'extraction du sitekey depuis la page, puis un flux complet en Python avec Selenium autour de l'API CaptchaAI.
Périmètre sûr : les exemples ci-dessous s'appliquent à votre propre démarche, sur un environnement que vous êtes autorisé à automatiser. L'automatisation de portails gouvernementaux est un domaine sensible ; restez dans le cadre de vos droits et de vos obligations RGPD.
Les paramètres de soumission BLS CAPTCHA
L'API CaptchaAI reçoit un BLS CAPTCHA via la méthode bls. Trois champs sont obligatoires — method, sitekey et pageurl — et trois sont facultatifs, mais souvent déterminants pour la précision. Le tableau ci-dessous récapitule chaque paramètre.
| Paramètre | Obligatoire | Type | Description |
|---|---|---|---|
method |
Oui | Chaîne | Doit valoir bls |
sitekey |
Oui | Chaîne | La clé BLS CAPTCHA du site |
pageurl |
Oui | Chaîne | URL de la page affichant le CAPTCHA |
instructions |
Non | Chaîne | Consigne textuelle issue de l'image du défi |
code |
Non | Chaîne | Identifiant ou type de la variante BLS CAPTCHA |
json |
Non | Entier | Défini sur 1 pour des réponses JSON |
Les trois premiers champs sont obligatoires ; les trois suivants sont facultatifs mais affinent la résolution.
Extraire les paramètres depuis la page
Avant toute soumission, récupérez le sitekey — et si possible la consigne — directement dans le DOM. Le script suivant ouvre la page avec Selenium, lit l'attribut data-sitekey, capte les instructions visibles, puis cherche un éventuel code dans le source de la page.
# extract_bls.py
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
def extract_bls_params(url):
"""Extract BLS CAPTCHA parameters from a page."""
driver = webdriver.Chrome()
driver.get(url)
params = {"pageurl": url}
# Extract sitekey
captcha_el = driver.find_element(By.CSS_SELECTOR, "[data-sitekey], .bls-captcha")
sitekey = captcha_el.get_attribute("data-sitekey")
if sitekey:
params["sitekey"] = sitekey
# Extract instructions if visible
try:
instructions_el = driver.find_element(
By.CSS_SELECTOR, ".captcha-instructions, .captcha-text"
)
params["instructions"] = instructions_el.text.strip()
except Exception:
pass
# Extract code from hidden input or script
page_source = driver.page_source
code_match = re.search(r'captcha_code["\']?\s*[:=]\s*["\']([^"\']+)', page_source)
if code_match:
params["code"] = code_match.group(1)
driver.quit()
return params
# Usage
params = extract_bls_params("https://bls-example.com/appointment")
print(params)
Adaptez les sélecteurs CSS à la structure réelle du portail : les classes varient d'une implémentation BLS à l'autre.
Envoyer le BLS CAPTCHA à l'API CaptchaAI
Soumission de base
La soumission suit le schéma en deux temps de l'API CaptchaAI : un POST vers in.php crée la tâche, puis une interrogation régulière de res.php récupère la réponse. Ajoutez instructions et code uniquement lorsque vous les avez extraits.
# solve_bls_basic.py
import requests
import time
import os
def solve_bls(sitekey, pageurl, instructions=None, code=None):
"""Solve BLS CAPTCHA via CaptchaAI API."""
api_key = os.environ["CAPTCHAAI_API_KEY"]
payload = {
"key": api_key,
"method": "bls",
"sitekey": sitekey,
"pageurl": pageurl,
"json": 1,
}
# Add optional parameters for higher accuracy
if instructions:
payload["instructions"] = instructions
if code:
payload["code"] = code
resp = requests.post(
"https://ocr.captchaai.com/in.php",
data=payload,
timeout=30,
)
result = resp.json()
if result.get("status") != 1:
raise RuntimeError(f"Submit failed: {result.get('request')}")
task_id = result["request"]
# Poll for result
time.sleep(10)
for _ in range(30):
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": api_key,
"action": "get",
"id": task_id,
"json": 1,
}, timeout=15)
data = resp.json()
if data.get("status") == 1:
return data["request"]
if data["request"] != "CAPCHA_NOT_READY":
raise RuntimeError(data["request"])
time.sleep(5)
raise TimeoutError("BLS solve timeout")
# Usage
solution = solve_bls(
sitekey="your-bls-sitekey",
pageurl="https://bls-example.com/appointment",
instructions="Select images in the correct order",
)
print(f"Solution: {solution}")
Le premier time.sleep(10) laisse le temps de traiter le défi ; le code interroge ensuite le résultat toutes les 5 secondes. Comptez de l'ordre de 10 à 20 secondes par résolution, selon l'environnement et la charge.
Interpréter la réponse
Tant que la tâche n'est pas terminée, res.php renvoie CAPCHA_NOT_READY : c'est un statut d'attente, pas une erreur. Dès que status passe à 1, le champ request contient la réponse à injecter. Toute autre valeur est un échec définitif à remonter.
Le paramètre instructions : quand le renseigner
Le champ instructions indique à CaptchaAI ce que le défi attend — l'ordre des images, le sens de lecture, le critère de sélection. Il est utile quand la consigne s'affiche en dehors de l'image et échappe à l'OCR. Renseignez-le en priorité dans ces cas :
- la consigne apparaît en texte HTML, à côté de l'image plutôt qu'à l'intérieur ;
- le défi impose un ordre précis (« de gauche à droite », « par numéro croissant ») ;
- une même page enchaîne plusieurs variantes de consigne.
Les formulations reviennent souvent à l'identique d'un portail à l'autre ; voici les motifs les plus courants, accompagnés d'un extracteur qui teste plusieurs sélecteurs.
# Common BLS instruction patterns:
instructions_examples = [
"Select images in the correct order",
"Click the images in order from left to right",
"Arrange the images by number",
"Select the matching image",
"Click in the order shown",
]
# Extract instructions from the CAPTCHA image area
def get_instructions_from_page(driver):
"""Try multiple selectors to find instruction text."""
selectors = [
".captcha-instructions",
".bls-captcha-text",
"#captcha-prompt",
".challenge-text",
]
for sel in selectors:
try:
el = driver.find_element(By.CSS_SELECTOR, sel)
text = el.text.strip()
if text:
return text
except Exception:
continue
return None
Le paramètre code : identifier la variante du défi
Certaines implémentations BLS déclinent plusieurs types de défis, distingués par un code. Quand il est présent, transmettez-le : il oriente la résolution vers la bonne variante. Le code peut apparaître dans un attribut de données, une variable JavaScript ou un champ caché — d'où l'intérêt de tester plusieurs motifs.
# Detect BLS CAPTCHA code from page
def detect_bls_code(page_source):
"""Detect which BLS CAPTCHA code/type is being used."""
patterns = [
(r'captchaType["\']?\s*[:=]\s*["\'](\w+)', "captchaType"),
(r'data-captcha-code["\']?\s*=\s*["\'](\w+)', "data attribute"),
(r'bls_code["\']?\s*[:=]\s*["\'](\w+)', "bls_code"),
]
for pattern, source in patterns:
match = re.search(pattern, page_source)
if match:
return match.group(1)
return None
Ne mettez pas ce code en cache : il peut changer selon la session ou la zone géographique. Réextrayez-le à chaque nouvelle page.
Flux BLS de bout en bout avec Selenium
Réunis, ces éléments donnent un flux complet : remplir le formulaire, extraire les paramètres, résoudre via l'API, injecter la réponse, puis soumettre. Le script suivant enchaîne ces étapes et attend un changement d'URL comme signal de succès.
# full_bls_flow.py
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 os
import re
def solve_bls_with_selenium(url, form_data=None):
"""Complete BLS CAPTCHA flow using Selenium."""
driver = webdriver.Chrome()
driver.get(url)
wait = WebDriverWait(driver, 15)
# Fill any form fields before CAPTCHA
if form_data:
for field_id, value in form_data.items():
el = wait.until(EC.presence_of_element_located((By.ID, field_id)))
el.clear()
el.send_keys(value)
# Extract CAPTCHA parameters
captcha_container = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey], .bls-captcha"))
)
sitekey = captcha_container.get_attribute("data-sitekey")
# Get instructions
instructions = None
try:
inst_el = driver.find_element(By.CSS_SELECTOR, ".captcha-instructions")
instructions = inst_el.text.strip()
except Exception:
pass
# Solve via API
solution = solve_bls(
sitekey=sitekey,
pageurl=driver.current_url,
instructions=instructions,
)
# Inject solution
driver.execute_script("""
var input = document.querySelector('input[name="captcha-response"], #captcha-response');
if (input) {
input.value = arguments[0];
} else {
var hidden = document.createElement('input');
hidden.type = 'hidden';
hidden.name = 'captcha-response';
hidden.value = arguments[0];
document.forms[0].appendChild(hidden);
}
""", solution)
# Submit form
submit_btn = driver.find_element(By.CSS_SELECTOR, "button[type='submit'], #submit")
submit_btn.click()
# Wait for confirmation
wait.until(EC.url_changes(url))
result_url = driver.current_url
driver.quit()
return result_url
Un point d'attention : l'injection cible input[name="captcha-response"]. Vérifiez le nom réel du champ de réponse sur votre portail et ajustez le sélecteur en conséquence.
Portails de rendez-vous BLS : le contexte francophone
Les portails BLS servent notamment à la prise de rendez-vous pour les demandes de visa, un usage très présent en Afrique du Nord et de l'Ouest francophones. Si vous outillez votre propre démarche, deux réflexes valent d'être rappelés :
- Conformité : minimisez les données personnelles manipulées ou journalisées et vérifiez vos obligations RGPD.
- Robustesse : ces portails changent souvent de structure HTML. Isolez vos sélecteurs CSS dans la configuration et prévoyez un backoff exponentiel en cas de
CAPCHA_NOT_READYprolongé.
Ce guide décrit une mécanique technique, pas un moyen de forcer un accès non autorisé : restez dans le périmètre que vous êtes en droit d'automatiser.
Dépannage
La plupart des échecs BLS viennent de paramètres manquants ou d'un mauvais diagnostic du type.
| Problème | Cause | Correctif |
|---|---|---|
ERROR_BAD_PARAMETERS |
sitekey ou pageurl manquant |
Vérifiez que les deux sont extraits correctement |
| Solution rejetée | Consigne non transmise | Ajoutez le paramètre instructions pour les défis ambigus |
| Mauvais type de CAPTCHA | Ce n'est pas un BLS CAPTCHA | Vérifiez s'il s'agit en réalité d'un reCAPTCHA ou d'un type personnalisé |
sitekey introuvable |
Chargement dynamique | Attendez l'affichage de l'élément CAPTCHA avant de l'extraire |
CAPCHA_NOT_READY en boucle |
File d'attente chargée | Allongez la fenêtre de polling et ajoutez un backoff exponentiel |
FAQ
Comment récupérer le sitekey quand le BLS CAPTCHA se charge dynamiquement ?
Attendez que l'élément soit présent avant de lire son attribut. Avec Selenium, WebDriverWait associé à presence_of_element_located évite de lire un data-sitekey encore vide au premier rendu.
Faut-il toujours envoyer les paramètres instructions et code ?
Non. La méthode bls fonctionne avec les seuls champs obligatoires. Renseignez instructions quand la consigne est ambiguë ou hors image, et code quand le portail expose une variante ; les deux améliorent la précision sans être requis.
Peut-on automatiser un portail de rendez-vous BLS en toute légalité ?
Uniquement dans le cadre de votre propre démarche et d'un environnement autorisé. Vérifiez les conditions d'utilisation du portail et vos obligations RGPD ; ce guide couvre la technique, pas l'autorisation d'accès.
Que faire si l'API renvoie CAPCHA_NOT_READY en continu ?
C'est le statut normal tant que la tâche n'est pas terminée. S'il persiste au-delà de votre fenêtre d'interrogation, augmentez le nombre d'itérations et ajoutez un backoff exponentiel plutôt que d'interroger de façon agressive.
Guides connexes
Passez de la théorie à la pratique — créez votre compte CaptchaAI.