API Tutorials

Инструкции BLS CAPTCHA и подробное описание параметров кода

Если запрос на решение BLS CAPTCHA то и дело возвращает ERROR_BAD_PARAMETERS или CaptchaAI отклоняет уже готовое решение, дело редко в sitekey. Чаще проблема в двух необязательных, но критичных для точности полях — instructions и code.

Разбираем, что это за параметры, когда их стоит передавать и как извлекать их автоматически со страницы.

Коротко, если нужен быстрый ответ:

  • sitekey и pageurl — обязательны всегда, без них запрос не пройдёт.
  • instructions и code — необязательны, но повышают точность на неоднозначных заданиях.
  • Оба поля надёжнее извлекать заново при каждом запросе, а не хранить как константу.

Справочник параметров BLS CAPTCHA

BLS CAPTCHA — задание на выбор и упорядочивание изображений, которое часто встречается на порталах бронирования и госсервисах. Для отправки задачи в CaptchaAI используются следующие поля:

Параметр Обязательный Тип Описание
method Да Строка Всегда bls
sitekey Да Строка Ключ сайта BLS CAPTCHA
pageurl Да Строка URL страницы с CAPTCHA
instructions Нет Строка Текст задания, извлечённый с изображения CAPTCHA
code Нет Строка Идентификатор кода/варианта BLS CAPTCHA
json Нет Целое число 1 — ответ в формате JSON

sitekey и pageurl нужны всегда.

instructions и code можно вообще не передавать — CaptchaAI решает большинство заданий и без них, — но для неоднозначных случаев эти два поля напрямую влияют на точность решения.


Как извлечь параметры BLS со страницы

Прежде чем отправлять запрос, параметры нужно достать из DOM.

На практике это сводится к трём шагам:

  1. Дождитесь, пока элемент с data-sitekey (или классом .bls-captcha) появится в DOM.
  2. Извлеките sitekey и, если рядом с изображением есть текст задания, заберите его как instructions.
  3. Проверьте исходный код страницы на code/тип CAPTCHA — он может быть скрыт в атрибуте данных или в инлайновом скрипте.

Ниже — рабочий пример на Selenium, который делает всё это автоматически:

# extract_bls.py
import re
from selenium import webdriver
from selenium.webdriver.common.by import By


def extract_bls_params(url):
    """Extract BLS CAPTCHA parameters from a page."""
    driver = webdriver.Chrome()
    driver.get(url)

    params = {"pageurl": url}

    # Extract sitekey
    captcha_el = driver.find_element(By.CSS_SELECTOR, "[data-sitekey], .bls-captcha")
    sitekey = captcha_el.get_attribute("data-sitekey")
    if sitekey:
        params["sitekey"] = sitekey

    # Extract instructions if visible
    try:
        instructions_el = driver.find_element(
            By.CSS_SELECTOR, ".captcha-instructions, .captcha-text"
        )
        params["instructions"] = instructions_el.text.strip()
    except Exception:
        pass

    # Extract code from hidden input or script
    page_source = driver.page_source
    code_match = re.search(r'captcha_code["\']?\s*[:=]\s*["\']([^"\']+)', page_source)
    if code_match:
        params["code"] = code_match.group(1)

    driver.quit()
    return params


# Usage
params = extract_bls_params("https://bls-example.com/appointment")
print(params)

Отправка задачи в CaptchaAI

Базовый запрос

Минимальный набор полей — method, sitekey, pageurl.

instructions и code добавляются в payload, только если их удалось найти на предыдущем шаге:

# solve_bls_basic.py
import requests
import time
import os


def solve_bls(sitekey, pageurl, instructions=None, code=None):
    """Solve BLS CAPTCHA via CaptchaAI API."""
    api_key = os.environ["CAPTCHAAI_API_KEY"]

    payload = {
        "key": api_key,
        "method": "bls",
        "sitekey": sitekey,
        "pageurl": pageurl,
        "json": 1,
    }

    # Add optional parameters for higher accuracy
    if instructions:
        payload["instructions"] = instructions
    if code:
        payload["code"] = code

    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"]

    # Poll for result
    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 solve timeout")


# Usage
solution = solve_bls(
    sitekey="your-bls-sitekey",
    pageurl="https://bls-example.com/appointment",
    instructions="Select images in the correct order",
)
print(f"Solution: {solution}")

Опрос res.php начинается только через 10 секунд после отправки — раньше результат всё равно не будет готов.

Более частые запросы до этого момента ничего не ускоряют, а лишь расходуют лимит.


Зачем нужен параметр instructions

instructions сообщает CaptchaAI, что именно спрашивает CAPTCHA.

На одних порталах BLS текст задания встроен прямо в изображение, на других выводится отдельным блоком рядом с ним — во втором случае без этого параметра распознавание задания менее надёжно.

# Common BLS instruction patterns:
instructions_examples = [
    "Select images in the correct order",
    "Click the images in order from left to right",
    "Arrange the images by number",
    "Select the matching image",
    "Click in the order shown",
]

# Extract instructions from the CAPTCHA image area
def get_instructions_from_page(driver):
    """Try multiple selectors to find instruction text."""
    selectors = [
        ".captcha-instructions",
        ".bls-captcha-text",
        "#captcha-prompt",
        ".challenge-text",
    ]

    for sel in selectors:
        try:
            el = driver.find_element(By.CSS_SELECTOR, sel)
            text = el.text.strip()
            if text:
                return text
        except Exception:
            continue

    return None

Что означает параметр code

code определяет вариант BLS CAPTCHA — часть внедрений использует несколько типов заданий, различающихся именно по этому идентификатору.

Он не всегда статичен: код может отличаться от сессии к сессии и от страницы к странице, поэтому надёжнее извлекать его заново при каждом запросе, а не переиспользовать однажды сохранённое значение.

# Detect BLS CAPTCHA code from page
def detect_bls_code(page_source):
    """Detect which BLS CAPTCHA code/type is being used."""
    patterns = [
        (r'captchaType["\']?\s*[:=]\s*["\'](\w+)', "captchaType"),
        (r'data-captcha-code["\']?\s*=\s*["\'](\w+)', "data attribute"),
        (r'bls_code["\']?\s*[:=]\s*["\'](\w+)', "bls_code"),
    ]

    for pattern, source in patterns:
        match = re.search(pattern, page_source)
        if match:
            return match.group(1)

    return None

Пример из практики: визовые агентства и порталы BLS International

BLS CAPTCHA особенно часто встречается на порталах BLS International, через которые подаются заявления на шенгенские и другие визы. Визовые агентства и travel-сервисы в России, Казахстане и других странах СНГ регулярно тестируют собственную интеграцию с такими формами в рамках QA перед обновлением личного кабинета клиента: вёрстка портала и вместе с ней значение code отличаются по регионам обслуживания, поэтому разница между запросом с instructions/code и без них на этих формах особенно заметна.

Из практики почти всегда стоит учитывать три вещи:

  • региональные версии портала BLS используют разную вёрстку — не полагайтесь на один захардкоженный селектор для всех стран;
  • значение code может отличаться даже для одного и того же типа задания в разных региональных версиях;
  • перед продакшеном стоит прогонять QA-тест на каждой обслуживаемой региональной версии портала, а не только на одной.

Полный сценарий с Selenium: от формы до подтверждения

Ниже — сквозной пример: заполнение полей формы, извлечение параметров CAPTCHA, решение через API, вставка токена в форму и её отправка:

# full_bls_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
import os
import re


def solve_bls_with_selenium(url, form_data=None):
    """Complete BLS CAPTCHA flow using Selenium."""
    driver = webdriver.Chrome()
    driver.get(url)

    wait = WebDriverWait(driver, 15)

    # Fill any form fields before CAPTCHA
    if form_data:
        for field_id, value in form_data.items():
            el = wait.until(EC.presence_of_element_located((By.ID, field_id)))
            el.clear()
            el.send_keys(value)

    # Extract CAPTCHA parameters
    captcha_container = wait.until(
        EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey], .bls-captcha"))
    )
    sitekey = captcha_container.get_attribute("data-sitekey")

    # Get instructions
    instructions = None
    try:
        inst_el = driver.find_element(By.CSS_SELECTOR, ".captcha-instructions")
        instructions = inst_el.text.strip()
    except Exception:
        pass

    # Solve via API
    solution = solve_bls(
        sitekey=sitekey,
        pageurl=driver.current_url,
        instructions=instructions,
    )

    # Inject solution
    driver.execute_script("""
        var input = document.querySelector('input[name="captcha-response"], #captcha-response');
        if (input) {
            input.value = arguments[0];
        } else {
            var hidden = document.createElement('input');
            hidden.type = 'hidden';
            hidden.name = 'captcha-response';
            hidden.value = arguments[0];
            document.forms[0].appendChild(hidden);
        }
    """, solution)

    # Submit form
    submit_btn = driver.find_element(By.CSS_SELECTOR, "button[type='submit'], #submit")
    submit_btn.click()

    # Wait for confirmation
    wait.until(EC.url_changes(url))
    result_url = driver.current_url
    driver.quit()

    return result_url

Типичные ошибки и как их исправить

Прежде чем разбирать таблицу ниже, проверьте самое очевидное: sitekey и pageurl вообще передаются в запрос. Это причина большинства ERROR_BAD_PARAMETERS.

Проблема Причина Как исправить
ERROR_BAD_PARAMETERS Не передан sitekey или pageurl Проверьте, что оба значения извлечены корректно перед отправкой
Решение отклонено CAPTCHA передана без instructions Добавьте instructions для заданий с неоднозначной формулировкой
Определён не тот тип CAPTCHA Это не BLS CAPTCHA Проверьте, не reCAPTCHA ли это или собственный виджет сайта
sitekey не найден Элемент CAPTCHA ещё не отрисован Дождитесь появления элемента в DOM перед извлечением

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

Обязательно ли передавать instructions в каждом запросе?

Нет. CaptchaAI решает большинство заданий BLS CAPTCHA и без этого параметра.

Передавайте instructions, когда задание неоднозначно или его текст не встроен в изображение, — так вы повышаете точность решения.

Что делать, если code отличается на разных страницах одного портала?

Извлекайте его заново на каждой странице, а не переиспользуйте однажды полученное значение.

Код BLS CAPTCHA может отличаться по сессии, региону обслуживания и даже конкретной странице формы.

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

BLS CAPTCHA решается быстро — как правило, меньше секунды, — поэтому даже плана BASIC ($15/мес, 5 потоков) с запасом хватает на большинство сценариев с формами и QA-тестированием.

Больше потоков имеет смысл брать под общую параллельность пайплайна, а не конкретно под BLS.

Можно ли решать BLS CAPTCHA без Selenium, одними HTTP-запросами?

Да: сам вызов CaptchaAI — обычный POST на in.php и опрос res.php, библиотека браузера для этого не нужна.

Selenium или Playwright требуются только для того, чтобы получить sitekey, instructions и code со страницы, если сайт не отдаёт их через собственный открытый API.

Почему CaptchaAI возвращает ERROR_BAD_PARAMETERS, хотя sitekey и pageurl вроде бы на месте?

Чаще всего sitekey извлечён из не того элемента страницы — например, из скрытого дубля виджета, — либо pageurl не совпадает с фактическим адресом, на котором показывается CAPTCHA.

Сверьте оба значения вручную перед отправкой запроса.


Похожие материалы


Параметры instructions и code — то, что отличает надёжное решение BLS CAPTCHA от случайного результата. Начните с CaptchaAI и подключите готовые примеры к своему пайплайну.

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