Pour résoudre un CAPTCHA BLS, vous extrayez les images de la grille et le texte de la consigne depuis la page, vous les envoyez à l'API CaptchaAI, puis vous cliquez sur les vignettes que le solveur vous renvoie. Ce sont ces quatre étapes que détaille ce tutoriel, avec du code Python et Node.js prêt à réutiliser.
Le CAPTCHA BLS équipe les portails de prise de rendez-vous de BLS International, l'opérateur qui gère les demandes de visa pour de nombreux consulats — un contexte bien connu des développeurs du Maghreb et d'Afrique francophone. Contrairement à une grille reCAPTCHA classique, il affiche un jeu d'images propriétaires accompagné d'une consigne rédigée (« Sélectionnez toutes les images contenant une voiture »), ce qui oblige à traiter à la fois le texte et les vignettes. Gardez un cadre strict : n'automatisez que votre propre démarche, sur un environnement que vous êtes autorisé à utiliser.
En bref
Le flux tient en quatre gestes, que le reste du tutoriel détaille :
- Extraire la consigne et les images de la page, avec Selenium ou Puppeteer.
- Envoyer le tout à l'API CaptchaAI via
method=bls. - Interroger le résultat jusqu'à recevoir les indices des bonnes images.
- Cliquer sur les vignettes correspondantes, puis valider le formulaire.
Prérequis
Réunissez ces quatre éléments : l'API BLS n'a besoin ni de sitekey ni de cookie, seulement des images et de la consigne.
| Élément | Détail |
|---|---|
| Clé API CaptchaAI | Depuis votre tableau de bord CaptchaAI |
| Images du CAPTCHA BLS | Encodées en base64 depuis la page |
| Texte de la consigne | La phrase qui indique quelles images sélectionner |
| Environnement | Python 3.7+ ou Node.js 14+ |
Étape 1 : extraire les images et la consigne de la page
Le CAPTCHA BLS affiche généralement de 3 à 9 images accompagnées d'une consigne du type « Sélectionnez toutes les images contenant une voiture ». Deux informations sont à récupérer :
- le texte de la consigne, qui indique quoi chercher ;
- chaque image, encodée en base64.
Les images arrivent soit en data-URI déjà encodée, soit via une URL à télécharger puis encoder vous-même.
Avec Selenium
Selenium pilote un vrai navigateur, ce qui reste le moyen le plus simple quand la grille est rendue côté client :
from selenium import webdriver
from selenium.webdriver.common.by import By
import base64
import requests as req
driver = webdriver.Chrome()
driver.get("https://blsitalypakistan.com/appointment")
# Get instruction text
instruction = driver.find_element(By.CSS_SELECTOR, ".captcha-instruction").text
print(f"Instruction: {instruction}")
# Get all captcha images as base64
images = {}
captcha_imgs = driver.find_elements(By.CSS_SELECTOR, ".captcha-image img")
for i, img in enumerate(captcha_imgs, 1):
src = img.get_attribute("src")
if src.startswith("data:image"):
# Already base64
images[f"image_base64_{i}"] = src.split(",")[1]
else:
# Download and encode
img_data = req.get(src).content
images[f"image_base64_{i}"] = base64.b64encode(img_data).decode()
Avec Puppeteer
Si votre pile est en Node.js, Puppeteer récupère exactement les mêmes éléments avec une API asynchrone :
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({ headless: 'new' });
const page = await browser.newPage();
await page.goto('https://blsitalypakistan.com/appointment');
// Get instruction
const instruction = await page.$eval('.captcha-instruction', el => el.textContent);
// Get images as base64
const images = await page.$$eval('.captcha-image img', imgs =>
imgs.map((img, i) => ({
key: `image_base64_${i + 1}`,
value: img.src.startsWith('data:') ? img.src.split(',')[1] : null
}))
);
Étape 2 : envoyer les données à CaptchaAI
Une fois la consigne et les images en main, envoyez le tout au solveur BLS via le paramètre method=bls. Chaque image occupe un champ numéroté (image_base64_1, image_base64_2, etc.), dans le même ordre que son affichage à l'écran. Cet ordre est essentiel : le solveur renvoie des indices qui s'y rapportent directement.
Python
import requests
import time
API_KEY = "YOUR_API_KEY"
payload = {
"key": API_KEY,
"method": "bls",
"instructions": instruction,
"json": 1
}
# Add each image (up to 9)
for key, value in images.items():
payload[key] = value
response = requests.post("https://ocr.captchaai.com/in.php", data=payload)
data = response.json()
if data.get("status") != 1:
raise Exception(f"Submit error: {data.get('request')}")
task_id = data["request"]
print(f"Task submitted: {task_id}")
Node.js
Le même appel côté Node.js, avec Axios :
const axios = require('axios');
const FormData = require('form-data');
async function submitBLS(instruction, images) {
const params = {
key: 'YOUR_API_KEY',
method: 'bls',
instructions: instruction,
json: 1,
...Object.fromEntries(images.map(img => [img.key, img.value]))
};
const { data } = await axios.post('https://ocr.captchaai.com/in.php', null, { params });
if (data.status !== 1) throw new Error(data.request);
return data.request;
}
Étape 3 : interroger le résultat
L'API BLS travaille de façon asynchrone : la première requête renvoie un identifiant de tâche, que vous interrogez ensuite toutes les 5 secondes. Tant que la réponse vaut CAPCHA_NOT_READY, continuez ; dès que status passe à 1, vous recevez les indices des bonnes images (par exemple 1,3,5).
Python
def get_bls_solution(task_id):
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,
"json": 1
}).json()
if result.get("status") == 1:
return result["request"] # e.g., "1,3,5" (image indices)
if result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {result.get('request')}")
raise Exception("Timeout")
solution = get_bls_solution(task_id)
print(f"Select images: {solution}") # e.g., "1,3,5"
Étape 4 : cliquer sur les bonnes images
Il ne reste plus qu'à traduire ces indices en clics. Les indices renvoyés sont en base 1, alors que Selenium indexe ses éléments à partir de 0 — d'où le idx - 1. Un court délai entre chaque clic reproduit un rythme d'interaction naturel avant l'envoi du formulaire.
# Parse the solution indices
selected = [int(i) for i in solution.split(",")]
# Click each correct image
captcha_imgs = driver.find_elements(By.CSS_SELECTOR, ".captcha-image img")
for idx in selected:
captcha_imgs[idx - 1].click() # Convert 1-based to 0-based
time.sleep(0.3) # Small delay between clicks
# Submit the form
driver.find_element(By.CSS_SELECTOR, ".captcha-submit").click()
Exemple Python complet
Voici les quatre étapes réunies dans un seul script de bout en bout :
import requests
import time
import base64
from selenium import webdriver
from selenium.webdriver.common.by import By
API_KEY = "YOUR_API_KEY"
driver = webdriver.Chrome()
driver.get("https://blsitalypakistan.com/appointment")
# 1. Extract instruction and images
instruction = driver.find_element(By.CSS_SELECTOR, ".captcha-instruction").text
captcha_imgs = driver.find_elements(By.CSS_SELECTOR, ".captcha-image img")
payload = {"key": API_KEY, "method": "bls", "instructions": instruction, "json": 1}
for i, img in enumerate(captcha_imgs, 1):
src = img.get_attribute("src")
if src.startswith("data:image"):
payload[f"image_base64_{i}"] = src.split(",")[1]
# 2. Submit to CaptchaAI
resp = requests.post("https://ocr.captchaai.com/in.php", data=payload).json()
task_id = resp["request"]
# 3. Poll for solution
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, "json": 1
}).json()
if result.get("status") == 1:
selected = [int(i) for i in result["request"].split(",")]
break
# 4. Click correct images and submit
for idx in selected:
captcha_imgs[idx - 1].click()
time.sleep(0.3)
driver.find_element(By.CSS_SELECTOR, ".captcha-submit").click()
print("CAPTCHA solved!")
driver.quit()
Scénario : suivre vos propres créneaux de rendez-vous BLS
Prenons un cas concret et légitime. Vous préparez une demande de visa et surveillez l'ouverture de créneaux sur le portail BLS de votre pays ; à chaque vérification, la page vous oppose un CAPTCHA BLS. Plutôt que de le résoudre à la main des dizaines de fois par jour, vous branchez le flux ci-dessus sur votre script de suivi.
Deux points de vigilance pour rester dans les clous :
- Périmètre : n'automatisez que votre propre démarche, sur un compte et un portail que vous êtes autorisé à utiliser — l'automatisation de portails gouvernementaux est un domaine sensible.
- Conformité : si votre script journalise des données (captures d'écran, identifiants de session), minimisez les données personnelles conservées et vérifiez vos obligations RGPD, surtout si vous opérez depuis l'Union européenne.
Côté coût, la résolution d'images reste économique à ce rythme. L'offre d'entrée BASIC ($15/mois, 5 threads) suffit largement pour un suivi individuel : chaque thread traite un CAPTCHA à la fois, avec un nombre de résolutions illimité sur le mois.
Dépannage
Quand la résolution échoue, l'erreur vient presque toujours de l'extraction ou de l'ordre des images. Voici les cas les plus fréquents :
| Erreur | Cause probable | Correctif |
|---|---|---|
ERROR_BAD_PARAMETERS |
Consigne ou images absentes de la requête | Envoyez à la fois le texte de la consigne et au moins une image |
ERROR_CAPTCHA_UNSOLVABLE |
Images trop floues ou illisibles | Capturez des images de meilleure qualité et vérifiez l'encodage base64 |
| Mauvaises vignettes sélectionnées | Ordre des images incorrect | Numérotez les images dans leur ordre d'affichage réel |
| Solution refusée par le portail | Images renouvelées après extraction | Extrayez et envoyez les images sans attendre |
Exemple entièrement exécutable
Besoin d'un projet complet, avec configuration de l'environnement, interrogation du résultat, nouvelles tentatives et gestion des erreurs ?
Voir l'exemple exécutable complet sur GitHub →
FAQ
Le solveur BLS de CaptchaAI convient-il aux portails de rendez-vous visa ?
Oui, c'est précisément le type d'images pour lequel la méthode bls est conçue. Réservez-le à votre propre démarche, sur un portail que vous êtes autorisé à utiliser.
Que faire si la consigne change à chaque rechargement de la page ?
C'est normal. Extrayez la consigne et les images à chaque tentative, juste avant l'envoi. Ne réutilisez jamais une consigne ni des images d'une session précédente, sinon le portail rejette la solution.
Puis-je résoudre un CAPTCHA BLS sans Selenium ?
Oui, si vous parvenez à récupérer les images et la consigne via de simples requêtes HTTP. L'API CaptchaAI n'a besoin que des images en base64 et du texte de la consigne, quel que soit l'outil qui les extrait.
Combien coûte la résolution de CAPTCHA BLS à volume élevé ?
La facturation se fait par thread, pas par résolution. L'offre BASIC ($15/mois, 5 threads) autorise un nombre illimité de résolutions sur le mois ; pour davantage de tâches simultanées, passez à STANDARD ($30/mois, 15 threads).
Comment gérer la conformité RGPD en automatisant un portail BLS ?
Ne conservez que le strict nécessaire : évitez de stocker les images, les captures ou les identifiants de session au-delà de la tâche en cours, et vérifiez vos obligations RGPD si vous traitez des données personnelles depuis l'UE.