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