Wer über ein BLS-Visazentrum einen Termin buchen oder ein Antragsportal automatisiert testen will, stößt fast immer an derselben Stelle an: einem 3×3-Bildraster mit einem dreistelligen Zahlencode darüber. Genau das ist ein BLS CAPTCHA. Die kurze Antwort vorweg: Sie lesen die neun Rasterbilder und den Anweisungscode aus, senden beides an CaptchaAI und klicken anschließend die zurückgegebenen Zellen an. CaptchaAI löst BLS CAPTCHAs mit hoher Erfolgsquote auf unterstützten Typen – die folgenden Schritte zeigen den kompletten Ablauf mit Python (Selenium) und Node.js (Puppeteer).
Hinweis zur Nutzung: BLS International betreibt Visa-Antragszentren für zahlreiche Länder, weshalb dieses CAPTCHA-Format im DACH-Raum vor allem bei der Terminvergabe begegnet. Setzen Sie die gezeigten Abläufe nur auf Portalen ein, für die Sie berechtigt sind, und beachten Sie die jeweiligen Nutzungsbedingungen.
Was Sie für dieses Tutorial brauchen
Bevor Sie starten, sollten drei Dinge bereitstehen:
- Ein API-Schlüssel von CaptchaAI (
YOUR_API_KEYin den Beispielen) - Python 3 mit Selenium oder Node.js mit Puppeteer als Browser-Automatisierung
- Zugriff auf die Zielseite, auf der das BLS-Raster erscheint
Der Einstieg gelingt am schnellsten mit dem CaptchaAI-Schnellstart-Guide; die Integration entspricht dem Muster, das Sie auch vom Lösen von reCAPTCHA v2 oder Cloudflare Turnstile per API kennen.
So ist ein BLS CAPTCHA aufgebaut
Ein BLS CAPTCHA besteht aus drei Bestandteilen:
- Ein 3×3-Raster mit 9 Bildzellen
- Ein numerischer Anweisungscode (z. B. 664, 123, 546), der angibt, welche Zellen ausgewählt werden sollen
- Die Zellen werden von links nach rechts und von oben nach unten nummeriert:
1 2 3
4 5 6
7 8 9
Warum der Anweisungscode entscheidend ist
Der Anweisungscode gibt vor, nach welchem Muster der Löser suchen soll. Die Antwort ist ein Array übereinstimmender Zellindizes (1–9). Sie müssen den Code nicht selbst deuten – diese Zuordnung übernimmt die API. Ihre Automatisierung hat nur zwei Aufgaben: die Rohdaten sauber auslesen und die zurückgegebenen Zellen anklicken.
Schritt 1: Rasterbilder und Anweisungscode auslesen
Zuerst holen Sie die neun Bildzellen und den Zahlencode aus dem DOM. Liegen die Bilder als externe URLs vor, laden Sie sie serverseitig herunter und wandeln sie in Base64 um; bei data:image-Quellen übernehmen Sie den Wert direkt.
Python (Selenium)
import base64
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com/bls-protected-page")
# Find the grid container
grid_cells = driver.find_elements(By.CSS_SELECTOR, ".captcha-grid img")
images = []
for cell in grid_cells:
src = cell.get_attribute("src")
if src.startswith("data:image"):
images.append(src)
else:
# Download and convert to base64
import requests
img_data = requests.get(src).content
b64 = base64.b64encode(img_data).decode()
images.append(f"data:image/png;base64,{b64}")
# Extract the instruction code
instruction_el = driver.find_element(By.CSS_SELECTOR, ".captcha-instruction")
instruction_code = instruction_el.text.strip()
# e.g., "664" or parsed from "Select all boxes with number 664"
import re
code_match = re.search(r'(\d{3,})', instruction_code)
instruction = code_match.group(1) if code_match else instruction_code
print(f"Instruction: {instruction}")
print(f"Images extracted: {len(images)}")
JavaScript (Puppeteer)
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com/bls-protected-page');
// Extract grid images as base64
const images = await page.evaluate(() => {
const cells = document.querySelectorAll('.captcha-grid img');
return Array.from(cells).map(img => {
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
canvas.getContext('2d').drawImage(img, 0, 0);
return canvas.toDataURL('image/png');
});
});
// Extract instruction code
const instruction = await page.evaluate(() => {
const el = document.querySelector('.captcha-instruction');
const match = el.textContent.match(/(\d{3,})/);
return match ? match[1] : el.textContent.trim();
});
console.log(`Instruction: ${instruction}, Images: ${images.length}`);
Der reguläre Ausdruck (\d{3,}) zieht den dreistelligen Code auch dann heraus, wenn er in einem längeren Satz wie „Select all boxes with number 664" eingebettet ist.
Schritt 2: Raster und Code an CaptchaAI übermitteln
Der BLS-Solver erwartet method=bls, den instructions-Code sowie alle 9 Bilder als image_base64_1 bis image_base64_9. Nach dem Absenden erhalten Sie eine Task-ID, deren Ergebnis Sie über res.php abfragen (Polling), bis der Status auf 1 steht.
Python
import requests
import time
import json
API_KEY = "YOUR_API_KEY"
# Prepare submission data
data = {
"key": API_KEY,
"method": "bls",
"instructions": instruction,
"json": "1",
}
# Add all 9 images
files = {}
for i, img in enumerate(images):
files[f"image_base64_{i+1}"] = (None, img)
# Submit
resp = requests.post(
"https://ocr.captchaai.com/in.php",
data=data,
files=files
).json()
if resp["status"] != 1:
raise Exception(f"Submit error: {resp['request']}")
task_id = resp["request"]
print(f"Task ID: {task_id}")
# Poll for result
for _ in range(20):
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["status"] == 1:
solution = json.loads(result["request"])
print(f"Selected cells: {solution}") # e.g., [1, 4, 7, 8]
break
if result["request"] != "CAPCHA_NOT_READY":
raise Exception(f"Error: {result['request']}")
JavaScript
const axios = require('axios');
const FormData = require('form-data');
const form = new FormData();
form.append('key', 'YOUR_API_KEY');
form.append('method', 'bls');
form.append('instructions', instruction);
form.append('json', '1');
images.forEach((img, i) => {
form.append(`image_base64_${i + 1}`, img);
});
const submit = await axios.post('https://ocr.captchaai.com/in.php', form, {
headers: form.getHeaders(),
});
const taskId = submit.data.request;
// Poll
let solution = null;
for (let i = 0; i < 20; i++) {
await new Promise(r => setTimeout(r, 5000));
const poll = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: 'YOUR_API_KEY', action: 'get', id: taskId, json: 1 }
});
if (poll.data.status === 1) {
solution = JSON.parse(poll.data.request);
break;
}
}
console.log('Selected cells:', solution); // e.g., [2, 4, 7]
Die zurückgegebene Lösung ist ein Array der anzuklickenden Zellindizes, etwa [1, 4, 7, 8].
Schritt 3: Die gelösten Zellen anklicken
Jetzt setzen Sie die Antwort im Browser um: Für jeden zurückgegebenen Index klicken Sie die passende Zelle an (die Indizes sind 1-basiert, Arrays 0-basiert – daher index - 1) und senden anschließend das Formular ab.
# Selenium — click the cells returned by CaptchaAI
grid_cells = driver.find_elements(By.CSS_SELECTOR, ".captcha-grid .cell")
for cell_index in solution:
# cell_index is 1-based
grid_cells[cell_index - 1].click()
# Submit the form
submit_btn = driver.find_element(By.CSS_SELECTOR, ".captcha-submit")
submit_btn.click()
// Puppeteer
const cells = await page.$$('.captcha-grid .cell');
for (const idx of solution) {
await cells[idx - 1].click();
}
await page.click('.captcha-submit');
Der komplette Ablauf in einer Funktion
Auslesen, Übermitteln, Abfragen und Anklicken lassen sich zu einer wiederverwendbaren Funktion zusammenfassen, die Sie in Ihre Test- oder Automatisierungs-Pipeline einhängen:
def solve_bls_captcha(driver, api_key):
"""Extract, solve, and submit a BLS CAPTCHA."""
import base64, requests, time, json, re
# 1. Extract images
grid_cells = driver.find_elements(By.CSS_SELECTOR, ".captcha-grid img")
images = []
for cell in grid_cells:
src = cell.get_attribute("src")
if src.startswith("data:image"):
images.append(src)
else:
img_data = requests.get(src).content
b64 = base64.b64encode(img_data).decode()
images.append(f"data:image/png;base64,{b64}")
# 2. Extract instruction
el = driver.find_element(By.CSS_SELECTOR, ".captcha-instruction")
match = re.search(r'(\d{3,})', el.text)
instruction = match.group(1)
# 3. Submit to CaptchaAI
data = {"key": api_key, "method": "bls", "instructions": instruction, "json": "1"}
files = {f"image_base64_{i+1}": (None, img) for i, img in enumerate(images)}
resp = requests.post("https://ocr.captchaai.com/in.php", data=data, files=files).json()
task_id = resp["request"]
# 4. Poll
for _ in range(20):
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["status"] == 1:
solution = json.loads(result["request"])
break
# 5. Click cells
clickable = driver.find_elements(By.CSS_SELECTOR, ".captcha-grid .cell")
for idx in solution:
clickable[idx - 1].click()
return solution
Das Beispielpaket zum Artikel enthält denselben Ablauf zusätzlich in Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin und als reines cURL-Skript. Die Feldnamen – method, instructions, image_base64_1 bis image_base64_9 – bleiben in allen Sprachen identisch.
Einsatz und Kosten im Überblick
BLS-Raster tauchen im DACH-Raum vor allem bei der Visa-Terminvergabe auf; typische Anwendungsfälle sind das automatisierte Testen eigener Antragsprozesse oder das strukturierte Erfassen freigegebener Termindaten. In allen Fällen gilt: nur berechtigte Portale, klare Zweckbindung.
CaptchaAI rechnet Thread-basiert ab – nicht pro Lösung. Ein Thread ist ein gleichzeitig laufendes CAPTCHA; sobald eine Lösung fertig ist, nimmt der Thread die nächste Aufgabe. Der Einstieg ist BASIC (15 $/Monat, 5 Threads) mit unbegrenzten Lösungen pro Thread. Preise werden in US-Dollar ausgewiesen.
DSGVO-Hinweis: IP-Adressen und personenbezogene Termindaten fallen unter die DSGVO. Prüfen Sie vor produktiven Läufen Ihre Rechtsgrundlage und Ihre Datenflüsse – das ist Ihre Sorgfaltspflicht als Betreiber, keine Zusicherung durch CaptchaAI.
Fehler beheben
| Problem | Ursache | Lösung |
|---|---|---|
ERROR_BAD_PARAMETERS |
Fehlende Bilder oder kein Anweisungscode | Prüfen Sie, dass alle 9 Bilder gültige Base64-Daten-URIs sind und instructions gesetzt ist |
| Falsche Zellen ausgewählt | Fehlerhafte Zuordnung von Zelle zu Index | Stellen Sie sicher, dass die Zellen von 1 bis 9 links nach rechts und oben nach unten nummeriert sind |
| Bilder werden nicht geladen | Cross-Origin-Einschränkung | Laden Sie die Bilder serverseitig herunter und wandeln Sie sie in Base64 um |
| Leerer Anweisungscode | Code steckt im Bild statt im Text | Extrahieren Sie den Anweisungstext, oder wenden Sie OCR auf das Anweisungsbild an |
CAPCHA_NOT_READY bleibt bestehen |
Ergebnis wird zu früh abgefragt | Halten Sie das Polling-Intervall bei ~5 Sekunden und erhöhen Sie die Anzahl der Versuche |
Häufige Fragen
Wofür werden BLS CAPTCHAs eingesetzt?
Vor allem auf den Portalen der BLS-Visa-Antragszentren, um automatisierte Terminbuchungen auszubremsen. Technisch handelt es sich um ein Rasterbild-CAPTCHA mit numerischem Anweisungscode – das Format kann aber auch außerhalb des Visa-Kontexts erscheinen.
Muss ich alle neun Rasterbilder übermitteln?
Ja. Der bls-Solver erwartet image_base64_1 bis image_base64_9 zusammen mit dem instructions-Code. Fehlt ein Bild oder ist es kein gültiger Base64-Daten-URI, antwortet die API mit ERROR_BAD_PARAMETERS.
Funktioniert das mit Selenium und Puppeteer gleichermaßen?
Ja. Der Ablauf ist in beiden Frameworks identisch: Raster und Code auslesen, an CaptchaAI senden, das Ergebnis abfragen und die zurückgegebenen Zellen anklicken. Nur die DOM-Zugriffe unterscheiden sich – die API-Aufrufe bleiben gleich.
Wie zuverlässig löst CaptchaAI BLS CAPTCHAs?
CaptchaAI erreicht eine hohe Erfolgsquote auf unterstützten CAPTCHA-Typen und interpretiert den Anweisungscode automatisch. Sie müssen die Zuordnung von Code zu Rasterinhalt nicht selbst vornehmen – die API liefert direkt die anzuklickenden Zellindizes zurück.
Was passiert, wenn das Polling in eine Zeitüberschreitung läuft?
Solange res.php CAPCHA_NOT_READY zurückgibt, ist die Lösung noch nicht fertig. Fragen Sie in Intervallen von etwa 5 Sekunden weiter ab; bricht die Schleife nach 20 Versuchen ohne Ergebnis ab, senden Sie die Aufgabe erneut, statt einen veralteten Task weiter abzufragen.
Jetzt BLS CAPTCHAs mit CaptchaAI lösen
Holen Sie sich Ihren API-Schlüssel unter captchaai.com und lösen Sie Ihr erstes BLS-Raster in wenigen Minuten – Rasterbilder auslesen, Code übermitteln, Zellen anklicken.