Tutorials

BLS CAPTCHA: понимание кодов инструкций и их решение

BLS CAPTCHA — это не текст для распознавания, а сетка 3×3 из девяти картинок и числовой код инструкции под ней: нужно кликнуть ровно те ячейки, которые коду соответствуют. Чаще всего с этим типом сталкиваются разработчики, которые пишут QA-тесты и интеграционную автоматизацию для порталов бронирования и подачи документов на инфраструктуре BLS International — код инструкции там всегда подписан прямым текстом рядом с сеткой. Ниже — рабочий процесс целиком: как вытащить девять изображений и код со страницы, передать их в CaptchaAI методом bls и кликнуть по возвращённым индексам ячеек.


Как устроена сетка и код инструкции BLS CAPTCHA

BLS CAPTCHA показывает два элемента:

  1. Сетку 3×3 — девять пронумерованных ячеек с изображениями.
  2. Числовой код инструкции (например, 664, 123, 546), который определяет, какие ячейки нужно выбрать.

Ячейки нумеруются слева направо, сверху вниз:

1  2  3
4  5  6
7  8  9

Код инструкции — не подпись для OCR, а идентификатор шаблона: решатель сопоставляет его с нужным набором ячеек и возвращает массив индексов от 1 до 9, которые совпали. Вручную разбирать логику кода не нужно — этим занимается CaptchaAI на стороне API.


Шаг 1. Извлеките изображения сетки и код инструкции

Сначала соберите со страницы девять изображений ячеек и текст кода инструкции. Ниже — два рабочих варианта: Selenium для Python и Puppeteer для Node.js.

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}`);

Если картинки грузятся напрямую по src, достаточно варианта на Selenium. Если они отрисованы через <canvas> без прямой ссылки — берите вариант на Puppeteer с canvas.toDataURL(), как в примере выше.


Шаг 2. Передайте изображения и код в CaptchaAI

Решатель BLS ожидает три вещи: method=bls, поле instructions с кодом и все девять изображений в параметрах от image_base64_1 до image_base64_9. Отправка и опрос результата идут через стандартные in.php/res.php, как и у остальных типов CAPTCHA в API CaptchaAI.

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]

solution — это массив индексов от 1 до 9 в порядке, в котором CaptchaAI нашёл совпадения с кодом инструкции. Дальше остаётся только кликнуть по этим ячейкам.


Шаг 3. Нажмите на решённые ячейки

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

Готовый пример: весь цикл одной функцией

Та же логика, собранная в одну переиспользуемую функцию — удобно вставить в существующий пайплайн Selenium:

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

Сколько потоков нужно для BLS CAPTCHA

BLS CAPTCHA решается быстро — менее чем за секунду на задачу, — так что один занятый поток теоретически прокачивает миллионы задач в месяц при непрерывной нагрузке. На практике узкое место обычно не в решателе, а в числе параллельных сессий Selenium/Puppeteer. Для точечного QA и разовых прогонов хватает тарифа BASIC ($15/мес, 5 потоков); если нужно гонять десятки браузерных сессий одновременно и не хочется, чтобы задачи вставали в очередь, берите ADVANCE ($90/мес, 50 потоков) или выше — тарифная сетка CaptchaAI считается по потокам, а не по числу решённых CAPTCHA, поэтому рост нагрузки не увеличивает стоимость одной задачи.


Диагностика типичных ошибок

Проблема Причина Решение
ERROR_BAD_PARAMETERS Отсутствуют изображения или не передан код инструкции Проверьте, что все 9 изображений — валидные base64 data URI, а instructions не пустой
Выбраны неправильные ячейки Неверное сопоставление ячейки с индексом Убедитесь, что ячейки пронумерованы от 1 до 9 слева направо и сверху вниз
Изображения не загружаются Ограничение cross-origin Загружайте изображения на сервере и конвертируйте в base64 перед отправкой
Пустой код инструкции Инструкция зашита в изображение, а не в текст Извлеките текст инструкции другим селектором или прогоните изображение инструкции через OCR-решатель
Долгий CAPCHA_NOT_READY Высокая очередь на решение или временная задержка Увеличьте число попыток опроса (for _ in range(20)) или интервал между запросами к res.php

Часто задаваемые вопросы

Что означает код инструкции BLS CAPTCHA?

Код (например, «664») сообщает решателю, какие ячейки сетки соответствуют нужному шаблону. CaptchaAI разбирает его сам — вручную сопоставлять цифры с картинками не нужно.

Сколько потоков нужно, чтобы обрабатывать BLS CAPTCHA в высоком темпе?

Сам решатель почти не создаёт задержки — узкое место обычно в числе параллельных браузерных сессий. Для точечного QA хватает тарифа BASIC (5 потоков); для параллельного прогона десятков сессий Selenium или Puppeteer возьмите ADVANCE (50 потоков), чтобы задачи не стояли в очереди.

Что делать, если .captcha-grid img не находит изображения?

Скорее всего, разметка целевой страницы отличается от примера. Откройте DevTools и проверьте фактический CSS-селектор сетки. Если картинки отрисованы через <canvas> без прямого src, используйте вариант с canvas.toDataURL(), как в примере на Puppeteer.

Можно ли отправить BLS CAPTCHA в CaptchaAI без Selenium или Puppeteer?

Да — оба фреймворка нужны только для извлечения изображений со страницы и клика по результату. Сам запрос к in.php/res.php — обычный HTTP POST/GET, который вызывается из любого языка; примеры к этой статье доступны на Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin и bash.

Законно ли автоматизировать прохождение BLS CAPTCHA на портале визового или сервисного центра?

Решение самой CAPTCHA не запрещено — вопрос в том, что вы делаете с результатом. Автоматизируйте только действия, на которые у вас есть право (собственный аккаунт, тестовая среда, согласие владельца сервиса), и не используйте решатель для обхода лимитов бронирования или сбора чужих персональных данных без правовых оснований — для российской аудитории это дополнительно регулируется 152-ФЗ «О персональных данных».


Начните решать BLS CAPTCHA через CaptchaAI

Зарегистрируйтесь, получите API-ключ и отправьте первую сетку 3×3 методом bls — CaptchaAI показывает стабильно высокую долю успешных решений на этом типе. Ключ для запросов выдаётся в личном кабинете на captchaai.com.


Связанные руководства

Комментарии для этой статьи отключены.