API Tutorials

Решите BLS CAPTCHA с помощью Python и CaptchaAI

BLS CAPTCHA решается в три действия: забрать из DOM девять картинок сетки и числовой код инструкции, отправить всё это в CaptchaAI одним POST-запросом на in.php, затем забрать из res.php список номеров ячеек и кликнуть их в Selenium. Собственное распознавание писать не нужно — номера ячеек приходят готовыми.

Отличие от reCAPTCHA v2 или Turnstile здесь принципиальное: там вы отдаёте sitekey и pageurl, а обратно получаете один токен. В BLS токена нет вообще. Это задача классификации изображений: вы передаёте сами картинки и получаете индексы, а форму дальше отправляет ваш браузер. Ниже — рабочий скрипт на Python с requests и selenium, который проходит этот путь целиком.


Что нужно подготовить

Элемент Значение
CaptchaAI API-ключ Из captchaai.com
Python 3.7+
Библиотеки requests, selenium, Pillow
Целевая страница Страница с BLS CAPTCHA

BLS входит в число типов, которые CaptchaAI решает в общей доступности, наравне с reCAPTCHA v2/v3, Cloudflare Turnstile, Cloudflare Challenge, GeeTest v3 и обычными image/OCR-капчами. Отдельного тарифа под BLS нет: тарификация у CaptchaAI идёт по потокам, а не по числу решений. Младший план — BASIC ($15/мес, 5 потоков), дальше STANDARD ($30/мес, 15 потоков) и ADVANCE ($90/мес, 50 потоков); число решений на поток внутри месяца не ограничено. Для скрипта из этой статьи, который обрабатывает одну форму за раз, BASIC хватает с запасом.


Устройство сетки 3×3

Сетка BLS — это девять маленьких картинок и числовая инструкция над ними, например «664». Инструкция говорит, какие ячейки выбрать. Нумерация идёт слева направо и сверху вниз:

1 | 2 | 3
---------
4 | 5 | 6
---------
7 | 8 | 9

Из этой схемы следуют два практических вывода. Первый: порядок элементов в списке, который вернёт find_elements, обязан совпадать с этой нумерацией — если вёрстка страницы перемешивает ячейки, сортируйте их по координатам, а не полагайтесь на порядок в DOM. Второй: API отдаёт номера в человеческой нумерации от 1 до 9, а Selenium работает со списком, индексируемым с нуля, поэтому перед кликом из каждого номера вычитается единица. Ошибка ровно на единицу — самая частая причина того, что скрипт «решил» капчу, но форма всё равно не прошла.


Шаг 1: соберите картинки и код инструкции

Откройте страницу и вытащите из неё текст инструкции и девять изображений. Часть страниц отдаёт картинки уже как data:-URI, часть — обычными ссылками; во втором случае их нужно скачать и закодировать в base64 самостоятельно.

import base64
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com/bls-form")

# Get the instruction code
instruction = driver.find_element(By.CSS_SELECTOR, ".bls-instruction").text
# e.g., "664"

# Get all 9 grid cell images as base64
cells = driver.find_elements(By.CSS_SELECTOR, ".bls-grid img")
images = []
for cell in cells:
    src = cell.get_attribute("src")
    if src.startswith("data:"):
        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: отправьте задачу в CaptchaAI

Метод запроса — bls. Изображения уходят как multipart-поля image_base64_1image_base64_9, код инструкции — отдельным параметром instructions. Ключ подставьте вместо YOUR_API_KEY, а лучше — читайте его из переменной окружения, чтобы он не попал в репозиторий.

import requests
import time
import json

API_KEY = "YOUR_API_KEY"

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

response = requests.post("https://ocr.captchaai.com/in.php", data=data, files=files)
result = response.json()

if result["status"] != 1:
    raise Exception(f"Submit failed: {result['request']}")

task_id = result["request"]
print(f"Task submitted: {task_id}")

Если status вернулся не равным 1, в поле request лежит код ошибки — его разбор в таблице ниже. При успехе там будет ID задачи, который понадобится на следующем шаге.


Шаг 3: опрашивайте res.php до готовности

Решение забирается опросом res.php по ID задачи. Первую паузу держите около пяти секунд, дальше опрашивайте с тем же интервалом и обязательно ограничьте число попыток — бесконечный цикл на нестабильном мобильном канале превращается в зависший воркер.

time.sleep(5)

for _ in range(30):
    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:
        selected_cells = json.loads(result["request"])
        print(f"Selected cells: {selected_cells}")
        # e.g., [1, 4, 7, 8]
        break

    if result["request"] != "CAPCHA_NOT_READY":
        raise Exception(f"Error: {result['request']}")

    time.sleep(5)

Ответ приходит в виде JSON-массива номеров ячеек, например [1, 4, 7, 8].


Шаг 4: кликните ячейки и отправьте форму

Осталось перевести номера в индексы списка и нажать кнопку отправки.

# Click the identified cells (0-indexed in Selenium)
for cell_number in selected_cells:
    idx = cell_number - 1  # Convert to 0-based index
    cells[idx].click()

# Submit the form
driver.find_element(By.CSS_SELECTOR, ".bls-submit").click()
print("BLS CAPTCHA solved and submitted")

Полный скрипт целиком

Ниже все четыре шага собраны в один файл: загрузка страницы, извлечение сетки, отправка, опрос и клик.

import requests
import time
import json
import base64
from selenium import webdriver
from selenium.webdriver.common.by import By

API_KEY = "YOUR_API_KEY"

# 1. Load the page
driver = webdriver.Chrome()
driver.get("https://example.com/bls-form")

# 2. Extract instruction and images
instruction = driver.find_element(By.CSS_SELECTOR, ".bls-instruction").text
cells = driver.find_elements(By.CSS_SELECTOR, ".bls-grid img")
images = []
for cell in cells:
    src = cell.get_attribute("src")
    if src.startswith("data:"):
        images.append(src)
    else:
        img_data = requests.get(src).content
        b64 = base64.b64encode(img_data).decode()
        images.append(f"data:image/png;base64,{b64}")

# 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)}
submit = requests.post("https://ocr.captchaai.com/in.php", data=data, files=files).json()
task_id = submit["request"]

# 4. Poll for result
time.sleep(5)
for _ in range(30):
    poll = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY, "action": "get", "id": task_id, "json": 1
    }).json()
    if poll["status"] == 1:
        selected = json.loads(poll["request"])
        break
    if poll["request"] != "CAPCHA_NOT_READY":
        raise Exception(poll["request"])
    time.sleep(5)

# 5. Click and submit
for cell_num in selected:
    cells[cell_num - 1].click()
driver.find_element(By.CSS_SELECTOR, ".bls-submit").click()
print(f"Solved: clicked cells {selected}")
driver.quit()

Ожидаемый вывод:

Solved: clicked cells [1, 4, 7, 8]

Разбор ошибок

Ошибка Причина Что делать
ERROR_BAD_PARAMETERS Не хватает изображений или инструкция пустая Проверьте, что уходят все 9 картинок и непустой параметр instructions
CAPCHA_NOT_READY Задача ещё в работе Это не ошибка — продолжайте опрос с интервалом 5 с
ERROR_ZERO_BALANCE На счёте нет средств Пополните баланс аккаунта CaptchaAI

Отдельно стоит ловить сетевые сбои: если res.php не ответил по тайм-ауту, повторите запрос с экспоненциальной задержкой, а не считайте задачу проваленной с первой попытки.


Как это выглядит в реальном пайплайне

Типичный сценарий для команд из России, Казахстана и Беларуси — автоматизированное регрессионное тестирование формы на визовом или сервисном портале, где BLS-сетка стоит перед отправкой заявки. QA-скрипт прогоняет форму на staging-стенде, проверяет валидацию полей и то, что бэкенд принимает заявку, а сетка BLS иначе останавливает прогон на каждом запуске.

Два замечания по такому применению. Первое — инфраструктурное: если воркеры крутятся во франкфуртском или алматинском регионе, RTT до ocr.captchaai.com добавляется к каждому из двух вызовов, поэтому закладывайте его в тайм-ауты, а не подбирайте time.sleep наугад. Второе — правовое: если сценарий попутно сохраняет введённые в форму данные, помните про 152-ФЗ «О персональных данных» и собирайте только те поля, которые вы вправе обрабатывать. Это ваша зона ответственности, а не функция CaptchaAI.

Держите такие прогоны в рамках собственных или тестовых окружений и того, что разрешено правилами целевого сервиса.


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

Почему BLS не возвращает токен, как reCAPTCHA?

Потому что это другой класс задачи. У reCAPTCHA и Turnstile ответом служит токен (g-recaptcha-response, cf-turnstile-response), который вы подставляете в форму. BLS — это выбор ячеек в сетке, поэтому API отдаёт массив номеров, а клики и отправку формы делает ваш браузер.

Что делать, если номера ячеек пришли, а форма не проходит?

Сначала проверьте смещение индексов: API нумерует ячейки с 1, список Selenium — с 0. Затем убедитесь, что порядок элементов в cells соответствует визуальному порядку сетки. И только потом смотрите на саму отправку — часто клик проходит, но кнопка submit ещё не активна.

Сколько потоков нужно, если сеток много?

Один поток — одна задача в полёте. Если пайплайн параллелит 12 форм, нужно 12 потоков, то есть STANDARD ($30/мес, 15 потоков). Число решений внутри месяца при этом не ограничено, поэтому масштабировать нужно параллелизм, а не «пакет решений».

Быстро ли решается BLS?

По внутренним метрикам CaptchaAI потолок для BLS — менее 1 с. Основное время в скрипте съедают не вызовы API, а ваш собственный цикл опроса: если первая пауза стоит на пяти секундах, вы столько и прождёте. Для BLS первый опрос можно делать заметно раньше.

Можно ли отправить всю сетку одной картинкой?

Нет. Метод bls ожидает девять отдельных изображений в полях image_base64_1image_base64_9. Склеенный скриншот сетки уйдёт как одно изображение и вернёт ERROR_BAD_PARAMETERS.


Похожие руководства


Подключите решение BLS CAPTCHA в CaptchaAI →


Что читать дальше

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