Как исправить ERROR_CAPTCHA_UNSOLVABLE и безопасно повторить попытку

Короткий ответ: ERROR_CAPTCHA_UNSOLVABLE означает, что сервис принял вашу задачу, попытался её решить и не смог получить ответ. С ключом всё в порядке, с настройкой тоже, просто эта конкретная попытка не удалась. Документированное решение — отправить новую задачу и повторить попытку, а не опрашивать тот же captcha ID снова. В этом руководстве — почему повторный опрос никогда не работает, что на самом деле вызывает сбой для каждого типа капчи и как построить цикл повторов, который не крутится вечно.
Что означает эта ошибка и откуда она берётся
В отличие от ошибки ключа или параметра, эта не появляется в момент отправки. Ваш вызов /in.php прошёл успешно и вернул ID. Сбой всплывает позже, когда вы опрашиваете /res.php за результатом.
# Submit: this part worked, you got an ID back curl "http://127.0.0.1:8080/in.php?key=YOUR_API_KEY&method=userrecaptcha&googlekey=YOUR_SITEKEY&pageurl=https://example.com/page-with-recaptcha" OK|2122988149 # Poll: the attempt finished, and it finished badly curl "http://127.0.0.1:8080/res.php?key=YOUR_API_KEY&action=get&id=2122988149" ERROR_CAPTCHA_UNSOLVABLE
Поэтому сама последовательность говорит о многом: всё вплоть до отправки было правильным. Проблема в том, что вы отправили, а не в том, как вы это сделали.
Почему повтор с тем же ID никогда не помогает
Две причины, и обе структурные.
Во-первых, попытка окончена. Результат для этого ID окончателен, и повторный опрос не запускает вторую попытку. Во-вторых, результаты читаются только один раз. Как только вы прочитали результат из /res.php, этому ID больше нечего вам дать.
Если ваша обработка ошибок продолжает опрашивать тот же ID после сбоя, она будет крутиться до срабатывания таймаута, а затем сообщит о таймауте — и отправит вас отлаживать совсем не то. Повтор означает новый вызов /in.php и получение нового ID. Это противоположно случаю CAPCHA_NOT_READY, где правильный ход — продолжать опрашивать имеющийся ID.
Что вызывает это на самом деле, по типам капчи
Графические капчи: обычно проблема во входных данных
Графическое распознавание — тот тип, где действительно нерешаемый вход встречается часто, потому что пиксели предоставляете вы. Проверьте файл, прежде чем винить сервис.
- Ограничения размера. Больше 600 кБ или больше 1000 px по любой стороне вернёт
ERROR_TOO_BIG_CAPTCHA_FILESIZE, а не эту ошибку, но изображения, близкие к этим пределам, часто оказываются скриншотами целой страницы. - Вы обрезали не ту область. Обрезка, захватывающая подпись, рамку или половину следующего поля, — гораздо более трудное изображение, чем капча сама по себе.
- Вы сохранили заглушку. Отдельный запрос к URL изображения часто возвращает новую, другую капчу, или уже истёкшую, или пиксель 1×1. Забирайте те байты, которые браузер уже получил.
- Формат. Повреждённый или неожиданный формат даёт
ERROR_INVALID_IMAGE, а некорректный data URI даётERROR_INVALID_BASE64.
Сохраните на диск ровно те байты, которые отправляете, и откройте их. Половина всех сбоев с изображениями видна за две секунды. Страница решатель картиночных капч перечисляет допустимые формы ввода: путь к файлу, удалённый URL или data:image/png;base64, URI.
reCAPTCHA: устаревший sitekey или неверный URL страницы
Sitekey, прочитанный из закэшированного исходника страницы или скопированный из тестового окружения, отправляется без ошибок, а потом приводит к сбою. То же самое с pageurl , который не соответствует странице, где на самом деле находится виджет, включая пропущенную схему или неотслеженный редирект.
Enterprise — вторая частая причина. Если на сайте работает reCAPTCHA Enterprise, а вы отправляете задачу без флага enterprise , она решается против неверной конфигурации. То же и для v3: передавайте versionи передавайте настоящее значение action этого сайта, а не значение по умолчанию verify.
В CapSkip нет параметра минимального балла, поэтому, если вы переносите код из другого сервиса, уберите любой параметр min_score или minScore . Он не является причиной этой ошибки, но и того, чего вы ждёте, тоже не сделает.
Turnstile: страницам-проверкам нужен не только sitekey
Виджету Turnstile достаточно sitekey и URL. Полной странице-проверке нужны ещё data (значение cData) и pagedata (chlPageData), оба считываются со страницы в тот же момент. Отправьте страницу-проверку так, будто это виджет, и получите задачу, которую сервис не сможет выполнить. Оба значения живут недолго, поэтому забирайте их непосредственно перед отправкой.
GeeTest: обычно ответ — истёкшая задача
The gt значение постоянно для сайта. А значение challenge одноразовое и истекает примерно за минуту. Если вы получили задачу, занялись чем-то другим и только потом отправили её, она уже может быть мертва. Получайте её непосредственно перед решением. Подробности на странице Решение для GeeTest .
Цикл повторов, который действительно повторяет
Отправляйте заново, ограничьте число попыток и делайте паузу между ними. Три попытки — разумный потолок: если цель провалила три свежие отправки, значит, входные данные неверны, и четвёртая ничего не исправит.
# pip install capskip
import time
from capskip import CapSkip, ApiException
solver = CapSkip(host="127.0.0.1", port=8080)
def solve_with_retry(sitekey, url, attempts=3):
for n in range(attempts):
try:
# A fresh call means a fresh task, which is the fix.
return solver.recaptcha(sitekey=sitekey, url=url)
except ApiException as e:
if "UNSOLVABLE" not in str(e) or n == attempts - 1:
raise
time.sleep(2 ** n) # 1s, then 2s
token = solve_with_retry("YOUR_SITEKEY", "https://example.com/page-with-recaptcha")
print(token["code"][:40])Обратите внимание, чего он не делает: он не повторяет ValidationException, потому что неверные параметры дают сбой одинаково каждый раз, и не повторяет NetworkException, потому что это означает, что приложение недоступно и все остальные цели вот-вот тоже упадут.
Та же схема на Node.js:
// npm install capskip
const { CapSkip } = require('capskip');
const solver = new CapSkip({ host: '127.0.0.1', port: 8080 });
async function solveWithRetry(sitekey, url, attempts = 3) {
for (let n = 0; n < attempts; n++) {
try {
return await solver.recaptcha(sitekey, url);
} catch (e) {
const last = n === attempts - 1;
if (last || !String(e).includes('UNSOLVABLE')) throw e;
await new Promise(r => setTimeout(r, 1000 * 2 ** n));
}
}
}Как сделать так, чтобы это случалось реже
- Читайте sitekey из живого DOM, а не из константы в коде. Сайты меняют их.
- Отправляйте тот URL, на котором вы действительно находитесь, после редиректов и со схемой.
- Короткоживущие значения получайте в последнюю очередь. Задачи GeeTest и cData у Turnstile устаревают меньше чем за минуту.
- Обрезайте изображения плотно и отправляйте байты, которые страница уже загрузила.
- Логируйте captcha ID при каждом сбое. Это делает закономерность видимой: одна плохая цель или общая проблема.
- Сначала протестируйте на заведомо рабочей странице. Если страница, которая обычно работает, тоже даёт сбой, проблема в вашем окружении, а не в цели.
Соседние коды ошибок
Вот те, что путают с нерешаемой задачей. Они означают разное и требуют разных действий.
| Код | Означает | Что делать |
|---|---|---|
CAPCHA_NOT_READY | Ещё в работе | Продолжайте опрашивать тот же ID |
ERROR_INVALID_IMAGE | Неверный формат или повреждённые данные | Пересохраните изображение и проверьте байты |
ERROR_TOO_BIG_CAPTCHA_FILESIZE | Больше 600 кБ или больше 1000 px | Обрежьте до самой капчи |
ERROR_INVALID_BASE64 | Полезная нагрузка base64 не декодируется | Уберите префикс data URI или исправьте выравнивание |
ERROR_UPLOAD | Данные изображения не пришли | Проверьте имя поля и тело запроса |
ERROR_GOOGLEKEY | Sitekey отклонён сразу | Перечитайте его с живой страницы |
ERROR_PAGEURL | URL страницы отсутствует или составлен неверно | Отправляйте полный URL вместе со схемой |
Каждый код, который может вернуть API, с его точным значением, есть на странице Документация по API.
Часто задаваемые вопросы
Стоит ли мне что-нибудь неудачное решение?
Нет. Ни платы за решение, ни баланса, потому что работа идёт на вашей собственной машине. Повтор стоит вам времени и процессора, и больше ничего — именно поэтому цикл из трёх попыток здесь уместен.
Можно ли получить результат снова после первого прочтения?
Нет. Результаты читаются один раз. Сохраняйте токен в тот момент, когда получили его, и считайте повторное чтение того же ID ошибкой в вашем коде, а не способом восстановления.
Поможет ли прокси с нерешаемой графической капчей?
Нет. Прокси применимы только к reCAPTCHA, Turnstile и GeeTest, но не к графическому распознаванию. Задача с изображением оценивается исключительно по присланным вами пикселям, поэтому исправляйте обрезку.
Все задачи на одном сайте падают. Это тоже эта ошибка?
Обычно это одна неверная константа, применённая везде: устаревший sitekey, отсутствующий флаг enterprise или страница-проверка, отправленная как виджет. Исправьте цель один раз — и весь набор начнёт проходить.
Сводка
Относитесь к error_captcha_unsolvable как к вердикту по той задаче, которую вы отправили. Не опрашивайте старый ID. Отправьте новый, ограничьте число попыток тремя и потратьте время отладки на входные данные: sitekey, URL страницы, обрезку и всё недолговечное, что вы получили слишком рано.
Приятная сторона локального локальный сервис распознавания капчи в том, что это дешёвый сбой. Не сгорает ни кредит, ни лимит запросов, и вы можете воспроизводить одну и ту же задачу столько раз, сколько нужно, чтобы понять, какое значение было неверным.
