Tutoriels API

Ordre des images BLS CAPTCHA et gestion des réponses de la grille

Les BLS CAPTCHA affichent des grilles d'images dans lesquelles les utilisateurs doivent sélectionner ou réorganiser les images. Ce guide couvre la disposition des grilles, les formats de réponse et comment soumettre correctement les solutions.


Types de défis de grille BLS

Ordre des images

L'utilisateur doit organiser les images dans un ordre spécifique (par exemple, nombres croissants, ordre alphabétique).

Sélection d'images

L'utilisateur doit cliquer sur des images spécifiques correspondant à une description (par exemple, "sélectionner toutes les images avec du texte").

Correspondance de motif

L'utilisateur doit identifier les images qui correspondent à un motif ou un échantillon présenté.


Cartographie de la disposition de la grille

# 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

Résolution des CAPTCHA de la grille BLS

# 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")

Analyse des réponses de la grille

# 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),
    }

Injection de solutions de grille avec Selenium

# 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))

Flux de grille BLS complet

# 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

Dépannage

Problème Parce que Corriger
Clics sur les mauvaises cellules Incompatibilité du sélecteur de cellule de grille Inspectez la grille HTML et mettez à jour les sélecteurs CSS
Commande rejetée Cliquer trop vite Ajoutez des délais de 300 à 500 ms entre les clics
Incompatibilité du format de la solution Le site attend un masque de bits et a obtenu des indices Utilisez format_for_submission() pour convertir
Grille pas complètement chargée Les images se chargent lentement Attendez que toutes les images de la grille se chargent avant de résoudre

FAQ

Comment CaptchaAI connaît-il la disposition de la grille ?

CaptchaAI reçoit le défi CAPTCHA des serveurs de BLS et le résout à distance. Vous fournissez la clé du site et l'URL de la page ; l'API gère l'analyse de la grille.

Que se passe-t-il si la grille change après ma soumission ?

Certains formulaires BLS affichent un deuxième défi après la réussite du premier. Gérez cela en recherchant un nouvel élément CAPTCHA après la soumission.

Puis-je réutiliser une solution de réseau BLS ?

Non. Chaque solution est liée à une session de défi spécifique. Résolvez toujours frais.


Guides connexes


Les commentaires sont désactivés pour cet article.