Как решить PopularCaptcha на Python: рабочий пример (2026)
Если ваш Python-скрипт наткнулся на PopularCaptcha, вам не нужна ферма браузеров или собственная модель. Нужны sitekey страницы, один POST-запрос и токен, который придет в ответ.
Это руководство проведет вас от нуля до рабочего токена примерно за пять минут: получить API-ключ, найти sitekey, запросить токен, отправить его в форму и обработать ошибки, которые появляются, когда скрипт работает без присмотра. Неудачные решения бесплатны, поэтому повтор стоит вам только времени.
Scarnox решает PopularCaptcha сегодня, как без прокси, так и со своим прокси. Другие типы капчи, например reCAPTCHA, Cloudflare Turnstile и AWS WAF, скоро появятся, поэтому все примеры здесь используют PopularCaptcha. Обзор типов капчи объясняет, чем они отличаются.
1. Получите API-ключ
Создайте аккаунт и начните с бесплатного пробного баланса, карта не нужна. Ваш API-ключ находится в личном кабинете. Не храните его в исходном коде, читайте из переменной окружения:
export SCARNOX_KEY="scarnox_YOURAPIKEY"
2. Найдите sitekey
Откройте страницу с капчей, откройте DevTools и выполните поиск data-sitekey во вкладке Elements. Sitekey PopularCaptcha — это UUID:
<div class="h-captcha" data-sitekey="10000000-ffff-ffff-ffff-000000000001"></div>
Нет data-sitekey в HTML? Виджет, скорее всего, отрисован JavaScript. Проверьте вкладку Network на запрос конфигурации виджета: нужен параметр запроса sitekey. Другие способы найти его описывают URL iframe и невидимые виджеты.
В качестве site_url отправьте URL страницы, которая показывает виджет. Важнее всего хост, но безопаснее передавать полный URL страницы.
3. Запросите токен
import os
import requests
API_URL = "https://api.scarnox.com/api/tasks/create"
API_KEY = os.environ["SCARNOX_KEY"]
def solve_captcha(sitekey: str, page_url: str) -> str:
r = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"captcha_type": "PopularCaptchaTaskProxyless",
"site_key": sitekey,
"site_url": page_url,
},
timeout=185, # вызов блокируется, пока токен не будет готов
)
data = r.json()
if data.get("errorId") != 0:
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data["solution"]["token"]
if __name__ == "__main__":
token = solve_captcha("10000000-ffff-ffff-ffff-000000000001", "https://example.com/signup")
print(token[:40], "...")
Это вся интеграция. Цикла опроса нет, и второго запроса «получить результат» тоже нет. Запрос возвращается, когда токен готов, поэтому единственная важная настройка — таймаут, достаточный для медленного решения. Используйте около 185 секунд.
Успешный ответ имеет errorId, равный 0, а токен лежит в solution.token. Любой другой errorId означает, что решение не удалось, и ответ содержит errorCode и errorDescription с объяснением причины.
4. Отправьте токен
Токен идет туда, где сайт ожидает ответ на капчу. Для PopularCaptcha это почти всегда поле формы с именем h-captcha-response. Многие сайты также принимают g-recaptcha-response, поэтому отправляйте оба:
import requests
def sign_up(session: requests.Session, form_url: str, email: str, sitekey: str) -> requests.Response:
token = solve_captcha(sitekey, form_url)
return session.post(form_url, data={
"email": email,
"h-captcha-response": token,
"g-recaptcha-response": token,
}, timeout=30)
Здесь важны две детали. Реальные сайты обычно также проверяют cookie сессии, полученные при загрузке страницы, поэтому загружайте форму тем же requests.Session перед отправкой. И отправляйте POST на URL action формы, а он не всегда совпадает с URL страницы.
Решайте капчу непосредственно перед отправкой. Токен истекает примерно через две минуты, поэтому не получайте его в начале долгой задачи и не держите. Если сайт отклоняет токен, откройте форму в DevTools и проверьте имена скрытых полей.
5. Обработка ошибок
Неудачные решения бесплатны, поэтому повтор стоит только времени. Некоторые ошибки никогда не будут успешны при повторе, поэтому не зацикливайтесь вслепую. Проверяйте errorId каждый раз, логируйте errorCode и errorDescription и повторяйте только временные сбои.
Сетевые ошибки требуют отдельной обработки, потому что requests выбрасывает исключение до того, как появится какой-либо ответ:
import requests
try:
token = solve_captcha(sitekey, page_url)
except requests.RequestException as exc:
print("network problem, retry later:", exc)
except RuntimeError as exc:
print("solve rejected:", exc)
В руководстве по обработке ошибок есть полная политика повторов с паузами и случайным разбросом.
Частые ошибки
- **Неверный
site_url.** Отправляйте страницу, которая показывает виджет, а не главную страницу сайта. - Устаревший токен. Токен, использованный спустя примерно две минуты, будет отклонен. Решайте непосредственно перед отправкой.
- Отсутствующая сессия. Отправка без cookie страницы может не пройти, даже с действительным токеном.
- **Некоторым сайтам нужен
rqdata.** Если страница передает значениеrqdataдля виджета, передайте его в запросе в необязательном полеrqdata. - Невидимый виджет. Если чекбокса нет и сайт запускает виджет из собственного кода, добавьте
"is_invisible": trueв запрос. Руководство по невидимой капче показывает, как вернуть токен на сайт.
Попробуйте бесплатно
Создайте аккаунт и начните с бесплатного пробного баланса, карта не нужна. Запустите пример выше на форме, которой вы владеете, прежде чем встраивать его в большую задачу. Стоимость решений при большом объеме — на странице цен.
Логирование каждого решения
Записывайте одну строку на каждое решение: sitekey, хост страницы, errorId, errorCode при ошибке и время вызова. Не записывайте API-ключ и пароли прокси. Эти строки покажут, медленно ли работает скрипт из-за страницы, прокси или решателя. Они также первое, что понадобится, если вы откроете обращение в поддержку.
Решение в цикле
Если ваш скрипт решает много капч подряд, держите цикл простым. Решите, отправьте, проверьте результат и только потом переходите дальше. Не решайте заранее и не ставьте токены в очередь, потому что каждый истекает примерно через две минуты. Короткая пауза между решениями на одном сайте держит частоту запросов близкой к той, которую создал бы человек.