OCR-скрипт обычно без проблем читает чистый текст, но на капче со слипшимися буквами, шумом на фоне или шрифтом, который меняется от символа к символу, доля ошибок резко растёт — и самодельный парсер на этом месте просто останавливается. API CaptchaAI решает такие капчи не за счёт локального распознавания на вашей стороне, а за счёт правильно подобранных параметров запроса: текстовых подсказок, регистронезависимости и диапазона длины. Ниже — по каким признакам определить тип сложности и какие параметры реально повышают точность для каждого случая.
Где такие капчи встречаются на практике
Связанные буквы и фоновый шум чаще всего попадаются в возрастных формах: порталах бронирования визовых слотов вроде BLS, личных кабинетах коммунальных служб, вводе кода с квитанции — там дизайн капчи годами никто не обновлял. Если вы автоматизируете QA-тестирование такой формы или интеграционные тесты собственного продукта, не пытайтесь угадать стратегию заранее: соберите реальные изображения с целевой страницы, определите преобладающий тип сложности по списку ниже и включайте textinstructions именно под него, а не «на всякий случай» под все типы сразу.
Если данные собираются с чужого сайта, убедитесь, что вы вправе их обрабатывать: для российской аудитории это требования 152-ФЗ «О персональных данных», для трансграничных проектов — аналог GDPR. Это вопрос дисциплины по данным, а не ограничение самого решения капчи.
Какие капчи считаются сложными для OCR
- Чистый текст — без искажений, шрифт единообразный. Сложность: низкая.
- Искажённый текст — буквы повёрнуты или масштабированы по отдельности. Сложность: средняя.
- Связанные буквы — символы соприкасаются или накладываются друг на друга. Сложность: высокая.
- Несколько шрифтов — у каждого символа свой шрифт или начертание. Сложность: высокая.
- Шум и линии — фоновый шум, зачёркивающие линии. Сложность: средняя.
- Разный цвет символов — у каждого символа свой цвет. Сложность: средняя.
- Математическое выражение — числа и знаки операций, нужно вычислить результат. Сложность: средняя.
Сохраните тип капчи с целевого сайта — под него ниже собраны конкретные подсказки для API.
Как отправить сложную капчу через API CaptchaAI
Для большинства многосимвольных капч достаточно передать изображение в base64 вместе с подсказками, которые описывают её реальные особенности:
import requests
import base64
import time
import os
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
def solve_complex_image(image_b64, hints=None):
"""Solve a complex multi-character image CAPTCHA."""
payload = {
"key": API_KEY,
"method": "base64",
"body": image_b64,
"json": 1,
}
if hints:
payload.update(hints)
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"]
time.sleep(8)
for _ in range(24):
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("Solve timeout")
Это базовая функция, вокруг которой строятся все стратегии ниже — меняется только словарь hints.
Связанные буквы: какие подсказки реально помогают
Подсказка про связанные буквы
Слипшиеся или перекрывающие друг друга символы — самый частый повод для ошибок в базовом OCR, но не для CaptchaAI, если явно указать на эту особенность и задать ожидаемую длину ответа:
def solve_connected_letters(image_path):
"""Solve CAPTCHA with connected/overlapping characters."""
with open(image_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode("ascii")
return solve_complex_image(b64, hints={
"textinstructions": "Characters may be connected or overlapping",
"minLen": 4,
"maxLen": 8,
})
Шум и смешанный регистр: как не потерять точность
Подсказка про шум и регистр
Когда на изображении есть фоновый шум или зачёркивающие линии, а регистр символов важен для ответа, добавьте регистронезависимость и явно опишите, что нужно игнорировать:
def solve_noisy_mixed(image_path):
"""Solve CAPTCHA with background noise and mixed case."""
with open(image_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode("ascii")
return solve_complex_image(b64, hints={
"regsense": 1, # Case-sensitive
"language": 2, # Latin characters
"textinstructions": "Ignore background lines and noise",
})
Разные шрифты в одном изображении
Подсказка про смену шрифта
Если каждый символ отрисован своим шрифтом или стилем, обычная OCR-модель путает похожие по форме буквы. Здесь помогает та же схема — подсказка плюс ограничение длины:
def solve_multi_font(image_path):
"""Solve CAPTCHA using multiple fonts per character."""
with open(image_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode("ascii")
return solve_complex_image(b64, hints={
"textinstructions": "Each character may use a different font or style",
"minLen": 5,
"maxLen": 7,
})
Предобработка изображения: когда она реально нужна
CaptchaAI обрабатывает большинство искажений без дополнительной подготовки на вашей стороне — предобработка нужна не всегда, а точечно, для очень зашумлённых или низкоконтрастных изображений:
# preprocess.py
from PIL import Image, ImageFilter, ImageEnhance
import io
import base64
def preprocess_for_ocr(image_path):
"""Preprocess image to improve OCR accuracy."""
img = Image.open(image_path)
# Convert to grayscale
img = img.convert("L")
# Increase contrast
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(2.0)
# Sharpen
img = img.filter(ImageFilter.SHARPEN)
# Binarize (threshold)
threshold = 128
img = img.point(lambda p: 255 if p > threshold else 0)
# Encode back to base64
buffer = io.BytesIO()
img.save(buffer, format="PNG")
return base64.b64encode(buffer.getvalue()).decode("ascii")
Основные шаги — перевод в оттенки серого, повышение контраста, резкость и бинаризация по порогу. Каждый из них дешёвый по CPU, поэтому такую предобработку можно держать в конвейере постоянно и включать выборочно через флаг, а не гонять на каждом запросе без разбора.
Повторные попытки и обратная связь по качеству
Один запрос редко бывает последним — заложите резервные наборы подсказок на случай, если первая попытка вернула не то, что ожидалось, и отправляйте reportbad на каждый неверный ответ, чтобы модель дообучалась под конкретный сайт:
# retry_strategy.py
def solve_with_retry(image_b64, hints, max_retries=3):
"""Retry solving with fallback strategies."""
strategies = [
hints, # Original hints
{**hints, "textinstructions": ""}, # Without instructions
{**hints, "numeric": 0, "regsense": 0}, # Relaxed constraints
]
for i, strategy in enumerate(strategies[:max_retries]):
try:
result = solve_complex_image(image_b64, strategy)
return {"text": result, "strategy": i, "success": True}
except RuntimeError:
continue
return {"text": None, "strategy": -1, "success": False}
def report_bad_answer(task_id):
"""Report incorrect answer for quality feedback."""
requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "reportbad",
"id": task_id,
}, timeout=10)
Итоговый чек-лист перед продакшеном
Перед тем как выкатывать интеграцию в продакшен, пройдитесь по короткому списку:
- Определите тип капчи по фактическому виду на сайте, а не по предположению.
- Подберите
textinstructionsпод этот тип и не смешивайте формулировки для разных капч в одном проекте. - Включайте предобработку изображения только если базовая точность оказалась низкой на выборке.
- Настройте
solve_with_retryс запасным набором подсказок на случай первого промаха. - Отправляйте
reportbadна каждый неверный ответ, чтобы держать точность стабильной на конкретном сайте.
Типичные проблемы и как их устранить
| Проблема | Причина | Решение |
|---|---|---|
| Пропущены символы | Связанные буквы распознаны неверно | Добавьте textinstructions с описанием связанного текста |
| Лишние символы в ответе | Шум принят за часть текста | Уберите шум на этапе предобработки перед отправкой |
| Не совпадает регистр | Регистр не учитывается по умолчанию | Установите regsense=1 |
| Результат приходит как выражение, а не число | Не передан calc=1 |
Включите режим вычисления для капч с математикой |
| Стабильно неверный ответ на одном сайте | Шрифт специфичен именно для этого сайта | Отправляйте reportbad, чтобы модель дообучилась под этот случай |
Часто задаваемые вопросы
Законно ли использовать автоматическое решение капчи при сборе данных с чужого сайта?
Технически — да, если вы обрабатываете только те данные, которые вправе обрабатывать, и соблюдаете условия конкретного сайта и применимое законодательство (в РФ — 152-ФЗ, для трансграничных проектов — аналог GDPR). CaptchaAI решает саму капчу как техническую задачу; вопрос законности сбора данных остаётся на стороне того, кто запускает автоматизацию.
Что делать, если один и тот же сайт стабильно возвращает неверный ответ?
Отправляйте reportbad на каждый неверный результат — это помогает модели дообучиться под конкретный шрифт сайта. Параллельно уточните textinstructions: опишите реальную особенность капчи — связанные буквы, зачёркивающие линии, конкретный диапазон длины.
Нужна ли предобработка, если на капче просто шум или низкий контраст?
Не всегда. CaptchaAI обрабатывает большинство искажений без дополнительной подготовки. Предобработка — оттенки серого, повышение контраста, бинаризация — оправдана, только если доля ошибок остаётся высокой на очень зашумлённых или низкоконтрастных изображениях; проверяйте на выборке, прежде чем включать её на все запросы.
Как решаются капчи с математическим выражением?
Передайте в подсказках calc=1 — тогда сервис вернёт вычисленный результат, а не строку с выражением. Без этого параметра ответ может прийти как 7+3, и вычислять его придётся уже на своей стороне.
Чем стратегия для связанных букв отличается от стратегии для нескольких шрифтов?
Для связанных букв важно сообщить, что символы могут соприкасаться (textinstructions плюс диапазон minLen/maxLen), тогда как для разных шрифтов на одном изображении подсказка описывает смену стиля начертания, а не форму символов. Если капча сочетает обе сложности, оба набора подсказок можно передать в одном запросе.
Связанные материалы
- Настройки точности оптического распознавания символов
- Руководство по предварительной обработке изображений
Решаете капчи со сложными многосимвольными изображениями? — начните с CaptchaAI.