Eine BLS-Rasterabfrage lösen Sie im Kern in drei Schritten:
- Die Abfrage mit
sitekeyundpageurlan CaptchaAI übergeben. - Die zurückgelieferten Zell-Indizes in ein sauberes, weiterverarbeitbares Format parsen.
- Die passenden Rasterzellen per Selenium anklicken – oder den Lösungswert in ein verstecktes Formularfeld eintragen.
Der eigentliche Aufwand steckt nicht im Lösen selbst, sondern in der sauberen Zuordnung zwischen dem Antwortformat der API und dem, was das Formular tatsächlich erwartet. Genau hier scheitern die meisten Integrationen.
BLS-CAPTCHAs begegnen deutschsprachigen Entwicklern vor allem auf Termin- und Antragsportalen von BLS International, die Visa-Anträge für zahlreiche Konsulate abwickeln. Wer solche Abläufe in eigenen oder ausdrücklich autorisierten Umgebungen automatisiert, muss zuerst wissen, ob das Portal eine Bitmaske, eine Indexliste oder eine Klickreihenfolge zurückerwartet.
Antwortformate im Überblick
Bevor Sie Code schreiben, klären Sie das Zielformat. BLS-Raster verlangen je nach Aufgabe eine von drei Antwortarten – die Wahl entscheidet, welche der weiter unten gezeigten Funktionen Sie brauchen.
| Antwortformat | Wann es auftritt | So reichen Sie es ein |
|---|---|---|
| Indexliste | Auswahl- und Mustervergleichsaufgaben | Zellen per click_grid_cells() anklicken |
| Bitmaske | Formulare mit verstecktem 0/1-Feld | mit format_for_submission() erzeugen und eintragen |
| Klickreihenfolge | Reihenfolge-Aufgaben | Zellen in Sequenz per set_order_sequence() anklicken |
Welche Aufgaben ein BLS-Raster stellt
BLS-CAPTCHAs zeigen ein Bildraster, in dem der Nutzer Zellen auswählen oder neu anordnen muss. In der Praxis treten drei Varianten auf, und jede verlangt ein anderes Antwortformat:
- Bilder in die richtige Reihenfolge bringen – der Nutzer ordnet Bilder in einer festgelegten Sequenz an, etwa nach aufsteigenden Zahlen oder alphabetisch. Hier zählt nicht nur, welche Zellen angeklickt werden, sondern in welcher Reihenfolge.
- Passende Bilder auswählen – der Nutzer klickt alle Bilder an, die einer Beschreibung entsprechen (zum Beispiel „Alle Bilder mit Text auswählen"). Die Reihenfolge ist hier meist egal, die Vollständigkeit der Auswahl dagegen entscheidend.
- Mustervergleich – der Nutzer erkennt, welche Bilder zu einem vorgegebenen Referenzbild passen. Technisch verhält sich das wie eine Auswahlaufgabe.
Wie das Rasterlayout auf Indizes abgebildet wird
Bevor Sie Zellen anklicken, brauchen Sie eine verlässliche Umrechnung zwischen Zeilen-/Spaltenposition und flachem Index. BLS-Raster nutzen typischerweise ein 3×3- oder 4×4-Layout, das von links oben nach rechts unten durchnummeriert ist.
# grid_mapping.py
# BLS grids typically use 3x3 or 4x4 layouts
# Each cell maps to an index:
# 3x3 grid:
# [0] [1] [2]
# [3] [4] [5]
# [6] [7] [8]
# 4x4 grid:
# [0] [1] [2] [3]
# [4] [5] [6] [7]
# [8] [9] [10] [11]
# [12] [13] [14] [15]
def grid_position(index, cols=3):
"""Convert flat index to row, column."""
return index // cols, index % cols
def index_from_position(row, col, cols=3):
"""Convert row, column to flat index."""
return row * cols + col
# Example: For a 3x3 grid, position (1, 2) = index 5
print(grid_position(5, cols=3)) # (1, 2)
print(index_from_position(1, 2)) # 5
Diese beiden Helfer sind die gemeinsame Sprache für alle folgenden Schritte: Egal ob die API Indizes oder Koordinaten liefert, Sie können jederzeit in das jeweils andere Format umrechnen.
Die BLS-Rasterabfrage an CaptchaAI übergeben
Sie übermitteln sitekey und pageurl an den Endpunkt in.php, optional ergänzt um die Anweisungen aus dem Raster. CaptchaAI löst die Abfrage entfernt und liefert die Zell-Indizes zurück. Der Ablauf ist das klassische Muster aus Übermittlung und anschließendem Polling über res.php.
# solve_bls_grid.py
import requests
import time
import os
import json
def solve_bls_grid(sitekey, pageurl, instructions=None):
"""Solve a BLS grid CAPTCHA and get response indices."""
api_key = os.environ["CAPTCHAAI_API_KEY"]
payload = {
"key": api_key,
"method": "bls",
"sitekey": sitekey,
"pageurl": pageurl,
"json": 1,
}
if instructions:
payload["instructions"] = instructions
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"]
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 grid solve timeout")
Die Methode heißt bls – reichen Sie die Anweisungen aus dem .captcha-instructions-Element mit ein, wenn das Raster welche anzeigt, denn sie verbessern die Zuordnung.
Die Rasterantwort auswerten
CaptchaAI gibt die Lösung mal als JSON, mal als kommagetrennte Indexliste zurück. Statt sich auf ein Format festzulegen, prüfen Sie beide Fälle und normalisieren auf eine saubere Python-Liste. Für Formulare, die eine Bitmaske erwarten, wandeln Sie die Indizes anschließend in einen 0/1-String um.
# parse_response.py
import json
def parse_grid_response(solution):
"""Parse CaptchaAI BLS response into actionable grid data."""
# Solution may be JSON or comma-separated indices
if isinstance(solution, str):
try:
parsed = json.loads(solution)
return parsed
except json.JSONDecodeError:
pass
# Try comma-separated indices
if "," in solution:
return [int(x.strip()) for x in solution.split(",")]
# Single value
return [solution]
return solution
def format_for_submission(indices, grid_size=9):
"""Format indices for form submission."""
# Some sites expect a bitmask
bitmask = ["0"] * grid_size
for idx in indices:
if isinstance(idx, int) and 0 <= idx < grid_size:
bitmask[idx] = "1"
return {
"indices": indices,
"bitmask": "".join(bitmask),
"count": len(indices),
}
Welches Format Ihr Ziel erwartet, verrät ein Blick in das versteckte Antwortfeld des Rasters: Eine kommagetrennte Zahlenfolge deutet auf Indizes hin, ein reiner 0/1-String auf eine Bitmaske.
Rasterzellen mit Selenium anklicken und eintragen
Jetzt bringen Sie die Lösung ins Formular. Für Klick-basierte Raster steuern Sie die Zellen per CSS-Selektor an; für Auswahlaufgaben genügen kurze Verzögerungen, für Reihenfolgeaufgaben brauchen Sie größere Pausen zwischen den Klicks. Erwartet die Seite die Lösung in einem versteckten Feld, tragen Sie den Wert direkt dort ein.
# inject_grid.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
def click_grid_cells(driver, indices):
"""Click specific grid cells based on solution indices."""
wait = WebDriverWait(driver, 10)
# Find all grid cells
cells = wait.until(
EC.presence_of_all_elements_located(
(By.CSS_SELECTOR, ".captcha-grid .cell, .bls-grid img, .grid-item")
)
)
for idx in indices:
if isinstance(idx, int) and idx < len(cells):
cells[idx].click()
time.sleep(0.3) # Brief delay between clicks
def set_order_sequence(driver, ordered_indices):
"""Click grid cells in the correct order for ordering challenges."""
wait = WebDriverWait(driver, 10)
cells = wait.until(
EC.presence_of_all_elements_located(
(By.CSS_SELECTOR, ".captcha-grid .cell, .bls-grid img")
)
)
for idx in ordered_indices:
if isinstance(idx, int) and idx < len(cells):
cells[idx].click()
time.sleep(0.5) # Ordering needs pauses between clicks
def inject_hidden_response(driver, solution_value):
"""Set the solution in a hidden input field."""
driver.execute_script("""
var inputs = document.querySelectorAll(
'input[name*="captcha"], input[name*="response"], #captcha-answer'
);
for (var i = 0; i < inputs.length; i++) {
inputs[i].value = arguments[0];
}
""", str(solution_value))
Wichtig ist die Unterscheidung: click_grid_cells reicht für Auswahlaufgaben, set_order_sequence mit den größeren Pausen ist für Reihenfolgeaufgaben gedacht – bei diesen wertet das Portal die Klickreihenfolge aus.
Der vollständige BLS-Raster-Ablauf
Zum Schluss fügen sich die Bausteine zu einem einzigen Ablauf zusammen: auf das CAPTCHA warten, sitekey und Anweisungen auslesen, über CaptchaAI lösen, die Antwort parsen und je nach Formularaufbau anklicken oder eintragen, dann absenden. Die Fallunterscheidung am Ende macht den Code robust gegenüber beiden Antwortmethoden.
# full_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
def handle_bls_grid(driver, pageurl):
"""Complete BLS grid CAPTCHA handling."""
wait = WebDriverWait(driver, 15)
# Wait for CAPTCHA to load
captcha = wait.until(
EC.presence_of_element_located(
(By.CSS_SELECTOR, "[data-sitekey], .bls-captcha")
)
)
sitekey = captcha.get_attribute("data-sitekey")
# Get instructions
instructions = None
try:
inst = driver.find_element(By.CSS_SELECTOR, ".captcha-instructions")
instructions = inst.text.strip()
except Exception:
pass
# Solve via CaptchaAI
solution = solve_bls_grid(sitekey, pageurl, instructions)
parsed = parse_grid_response(solution)
# Determine response method
grid_cells = driver.find_elements(
By.CSS_SELECTOR, ".captcha-grid .cell, .bls-grid img"
)
if grid_cells:
# Click-based response
if isinstance(parsed, list) and all(isinstance(x, int) for x in parsed):
click_grid_cells(driver, parsed)
else:
inject_hidden_response(driver, solution)
else:
# Hidden input response
inject_hidden_response(driver, solution)
# Submit
submit = driver.find_element(
By.CSS_SELECTOR, "button[type='submit'], .submit-btn, #verify"
)
submit.click()
return True
Derselbe Aufbau – Übermittlung, Polling, Einbau der Lösung – trägt auch bei anderen CAPTCHA-Typen wie reCAPTCHA v2, Cloudflare Turnstile oder GeeTest v3. Wer das Muster einmal verinnerlicht hat, überträgt es mit minimalem Aufwand auf den nächsten Solver.
Hinweis zur Nutzung: Automatisieren Sie BLS-Abläufe nur in eigenen oder ausdrücklich autorisierten Umgebungen. Personenbezogene Daten – auch IP-Adressen – fallen unter die DSGVO; prüfen Sie Rechtsgrundlage und die Nutzungsbedingungen des jeweiligen Portals vorab.
Typische Probleme und Lösungen
| Problem | Ursache | Lösung |
|---|---|---|
| Klicks landen auf den falschen Zellen | CSS-Selektor passt nicht zum Raster-HTML | Raster-HTML prüfen und die CSS-Selektoren anpassen |
| Reihenfolge wird abgelehnt | Zu schnelle Klicks | Zwischen den Klicks 300–500 ms Verzögerung einfügen |
| Antwortformat passt nicht | Site erwartet eine Bitmaske, erhält aber Indizes | Mit format_for_submission() in eine Bitmaske umwandeln |
| Raster noch nicht vollständig geladen | Bilder laden verzögert | Warten, bis alle Rasterbilder geladen sind, bevor Sie lösen |
Häufige Fragen
Welche CaptchaAI-Methode löst BLS-Raster?
Die Methode bls. Sie übergeben sitekey und pageurl an den Endpunkt in.php; die API übernimmt die Rasteranalyse und liefert die Zell-Indizes zurück, die Sie anschließend anklicken oder eintragen.
Woran erkenne ich, ob das Formular Indizes oder eine Bitmaske erwartet?
Ein Blick in das versteckte Antwortfeld genügt: Eine kommagetrennte Zahlenfolge (2,4,7) steht für Indizes, ein reiner 0/1-String (001010010) für eine Bitmaske. Zwischen beiden wandelt format_for_submission() verlustfrei um.
Wie lange ist eine BLS-Rasterlösung gültig?
Nur für die aktuelle Challenge-Sitzung. Jede Lösung ist an eine bestimmte Abfrage gebunden und lässt sich nicht wiederverwenden – lösen Sie pro Versuch frisch. Zeigt das Formular nach dem Absenden ein zweites Raster, behandeln Sie es als neue Abfrage.
Ist das automatische Lösen von BLS-Rastern auf Terminportalen erlaubt?
Das hängt von den Nutzungsbedingungen des jeweiligen Portals und der geltenden Rechtslage ab. Prüfen Sie diese vorab und beachten Sie, dass personenbezogene Daten (auch IP-Adressen) unter die DSGVO fallen. Setzen Sie die hier gezeigten Abläufe nur in eigenen oder ausdrücklich autorisierten Umgebungen ein.
Wie viele BLS-Abfragen kann ich parallel lösen?
So viele, wie Ihr Tarif Threads bereitstellt. CaptchaAI rechnet pro gleichzeitigem Thread ab, nicht pro Lösung: Der BASIC-Tarif (15 $/Monat, 5 Threads) erlaubt fünf parallele Abfragen, jede mit unbegrenzten Lösungen im Abrechnungsmonat.
Verwandte Leitfäden
Bringen Sie BLS-Raster zuverlässig durch Ihre Automatisierung – jetzt mit CaptchaAI starten.