Если запрос на решение 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.
На практике это сводится к трём шагам:
- Дождитесь, пока элемент с
data-sitekey(или классом.bls-captcha) появится в DOM. - Извлеките
sitekeyи, если рядом с изображением есть текст задания, заберите его какinstructions. - Проверьте исходный код страницы на
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 и подключите готовые примеры к своему пайплайну.