Troubleshooting

Распространенные ошибки CAPTCHA в виде сетки и их исправления

Если решение Grid Image CAPTCHA возвращает ошибку вместо индексов ячеек, дело чаще всего не в самом решателе, а в том, как капча передана в API: не тот формат файла, неполный скриншот или сдвиг индексации при разборе ответа. Ниже — разбор ошибок по кодам API CaptchaAI, их причины и рабочие исправления: от ERROR_WRONG_FILE_EXTENSION до зависающего CAPCHA_NOT_READY.


Три причины, из-за которых Grid Image CAPTCHA не решается чаще всего

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

  1. Файл передан не в том формате. API принимает только чистый base64 PNG или JPEG без префикса data:image/...;base64, — этот префикс и есть причина ERROR_WRONG_FILE_EXTENSION в девяти случаях из десяти.
  2. Скриншот снят не полностью или слишком рано. У команд, которые гоняют QA-тесты через нестабильный мобильный интернет, чаще всего ловится ERROR_ZERO_CAPTCHA_FILESIZE: скрипт делает скриншот раньше, чем прогрузится картинка сетки.
  3. Индексы ответа применены без пересчёта базы. API возвращает индексы ячеек с отсчётом от 1, а массив в коде — с отсчётом от 0; это самая частая причина, когда решение приходит успешным, а клик уходит не туда.

Ошибки при отправке изображения

ERROR_WRONG_FILE_EXTENSION

Причина: файл, который вы передаёте, не распознаётся как валидное изображение.

Как исправить

  1. Отправляйте только PNG или JPEG.
  2. Проверьте, что base64-строка закодирована без ошибок.
  3. Уберите префикс data:image/...;base64, перед отправкой — это самая частая причина этой ошибки.
# WRONG — includes data URI prefix
body = "data:image/png;base64,iVBORw0KGgo..."

# CORRECT — raw base64 only
body = "iVBORw0KGgo..."

ERROR_TOO_BIG_CAPTCHA_FILESIZE

Причина: изображение превышает максимальный размер файла (обычно 600 КБ).

Как исправить: уменьшите изображение перед отправкой, сохранив пропорции:

from PIL import Image
import io
import base64

# Resize if too large
img = Image.open("captcha.png")
if img.width > 600:
    ratio = 600 / img.width
    img = img.resize((600, int(img.height * ratio)), Image.LANCZOS)

buffer = io.BytesIO()
img.save(buffer, format="PNG")
b64 = base64.b64encode(buffer.getvalue()).decode()

Если ошибка остаётся после сжатия

Проверьте, что в тело запроса действительно ушёл пересохранённый файл, а не старая base64-строка из кеша — частая причина, когда код сжатия отработал, а переменная с запросом осталась прежней.

ERROR_ZERO_CAPTCHA_FILESIZE

Причина: файл пустой — картинка не успела загрузиться в момент захвата.

Как исправить

  1. Проверяйте, что элемент изображения полностью загружен, прежде чем делать скриншот.
  2. Убедитесь, что атрибут src не пустой.
  3. Дождитесь ленивой подгрузки изображения.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# Wait for image to load
WebDriverWait(driver, 10).until(
    lambda d: d.find_element(By.CSS_SELECTOR, ".captcha img").get_attribute("complete") == "true"
)

Ошибки при решении

ERROR_CAPTCHA_UNSOLVABLE

Причина: изображение размыто, искажено, либо объекты на нём физически не различить.

Как исправить:

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

Решатель выбирает не те клетки

Причина: низкое качество скриншота или сетка захвачена не полностью.

Как исправить

  1. Снимайте скриншот всего элемента капчи, включая границы.
  2. Не обрезайте изображение впритык — оставьте пару пикселей отступа.
  3. Сохраните захваченную картинку и откройте её вручную: визуальная проверка сразу показывает, где всё пошло не так.
# Take a proper element screenshot
captcha_el = driver.find_element(By.CSS_SELECTOR, "#captcha-container")
captcha_el.screenshot("debug_captcha.png")

# Open and check manually
from PIL import Image
Image.open("debug_captcha.png").show()

Совет: держите под рукой папку с последними 5–10 сохранёнными скриншотами капчи во время отладки — визуальное сравнение «было / стало» находит дефект захвата быстрее, чем чтение логов.


Ошибки применения решения

Смещение индекса на единицу

Причина: API возвращает индексы с отсчётом от 1, а массив в коде — с отсчётом от 0.

# API returns "1,3,5" (1-based)
solution = "1,3,5"
indices = [int(i) for i in solution.split(",")]

# DON'T: use directly as array index
# cells[1], cells[3], cells[5]  ← WRONG (off by one)

# DO: convert to 0-based
for idx in indices:
    cells[idx - 1].click()  # 1→0, 3→2, 5→4

Как быстро проверить, что дело именно в этом

Если решение приходит со статусом успеха, но клики попадают в соседние ячейки со стабильным смещением на одну позицию — это почти всегда сдвиг базы индексации, а не сбой решателя.

Клики по ячейкам не срабатывают

Причина: клик уходит не туда — мимо цели из-за оверлея, iframe или shadow DOM.

Сначала проверьте, в каком контексте документа находится скрипт

Большинство «неработающих» кликов на самом деле приходятся на родительскую страницу, а не на iframe с капчей — переключение контекста нужно делать до запроса решения, а не после.

Как исправить:

# Check if captcha is in an iframe
iframes = driver.find_elements(By.TAG_NAME, "iframe")
for iframe in iframes:
    if "captcha" in iframe.get_attribute("src").lower():
        driver.switch_to.frame(iframe)
        break

# Now find and click cells
cells = driver.find_elements(By.CSS_SELECTOR, ".grid-cell")

Динамическая сетка: плитки меняются после клика

Причина: динамические сетки в стиле reCAPTCHA подменяют плитки после взаимодействия.

Как исправить: для reCAPTCHA используйте не метод изображения, а метод токена — тогда динамику сетки обрабатывает API, а не ваш код:

# Token method handles dynamic grids automatically
response = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": "SITE_KEY",
    "pageurl": "https://example.com",
    "json": 1
})

Ошибки тайм-аута

Капча истекает раньше, чем приходит решение

Причина: Grid CAPTCHA обычно живёт 2–3 минуты.

Как исправить

  1. Отправляйте изображение сразу после захвата, не откладывая.
  2. Если решение занимает больше 60 секунд, обновите капчу и запросите заново.

CAPCHA_NOT_READY зацикливается без конца

Причина: скорее всего, задача тихо завершилась ошибкой на стороне решателя.

Как отличить обычную задержку решения от тихого сбоя

Нормальное решение Grid CAPTCHA укладывается в 5–20 секунд. Если статус CAPCHA_NOT_READY держится дольше минуты — это уже не задержка, а зависшая задача, и продолжать опрос без предела попыток бессмысленно.

Как исправить: задайте предел числа попыток опроса и явно обрабатывайте отказ:

for attempt in range(30):
    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.get("status") == 1:
        return result["request"]
    if result.get("request") not in ["CAPCHA_NOT_READY"]:
        break  # Actual error, stop polling

raise Exception("Grid captcha solve failed — refresh and retry")

Итоговый чек-лист перед обращением в поддержку

До отправки запроса

  1. Формат — PNG или JPEG, корректно закодирован, без data:image/...;base64, в теле запроса.
  2. Размер — меньше 600 КБ.
  3. Сетка захвачена целиком, с отступами по краям, не обрезана впритык.
  4. Изображение чёткое: не размытое и не уменьшенное вручную.

После получения ответа

  1. Решение разобрано верно: индексы через запятую и переведены из базы 1 в базу 0.
  2. Скрипт переключён на iframe с капчей, если она встроена во фрейм.
  3. Изображение было отправлено сразу после захвата, капча не успела истечь.
  4. Опрос res.php ограничен по числу попыток, а не крутится бесконечно.

Если все восемь пунктов пройдены, а ошибка повторяется — сохраните конкретный id задачи и обратитесь в поддержку CaptchaAI с этим ID, а не с общим описанием «капча не решается».


Частые вопросы

Почему ERROR_CAPTCHA_UNSOLVABLE повторяется на одном и том же сайте?

Обычно это значит, что верстка сайта отдаёт капчу с постоянным дефектом — например, элемент перекрыт другим слоем или скриншот всегда обрезает край сетки. Сравните несколько сохранённых захватов вручную: если дефект повторяется, дело в коде захвата, а не в конкретной капче.

Файл открывается нормально в браузере, но API всё равно возвращает ERROR_WRONG_FILE_EXTENSION — почему?

Почти всегда дело не в самом изображении, а в том, что перед base64-строкой остался префикс data:image/png;base64, или в кодировке проскочил лишний перенос строки. API проверяет байты, которые вы прислали, а не то, что видно в браузере, — сверьте тело запроса напрямую, а не превью в интерфейсе.

Сколько раз стоит повторять опрос при CAPCHA_NOT_READY, прежде чем сдаться?

Ориентируйтесь на 20–30 попыток с паузой в 5 секунд — это покрывает почти все нормальные случаи решения.

Ориентир по времени ожидания

Если статус не меняется дольше пары минут, задача, скорее всего, уже завершилась ошибкой, и её нужно пересоздать, а не опрашивать дальше.

Что делать, если сетка имеет нестандартные размеры?

CaptchaAI анализирует изображение как есть. Нестандартные сетки (например, 5×3, 2×4) обрабатываются на основе визуального анализа, а не жёстких предположений о фиксированной сетке.

Решение стало занимать заметно дольше, хотя раньше проходило быстро — в чём дело?

Скорее всего, дело не в API, а в том, что изменился сам скриншот: выросло разрешение, добавился оверлей, либо сетка стала сниматься с задержкой на медленном соединении. Сравните текущий захват с сохранённым эталонным изображением — если размер файла или чёткость заметно отличаются, проблема в шаге захвата, а не в очереди решения.


Связанные руководства

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