Решатель капчи для Selenium на Python: рабочий пример (2026)
Selenium запускает настоящий браузер, поэтому страница отрисовывается и ее скрипты выполняются так же, как для человека. Единственный шаг, который Selenium не может выполнить, — решить виджет PopularCaptcha. Это руководство добавляет этот шаг: читаем sitekey с отрисованной страницы, получаем токен одним вызовом API, записываем токен в форму и отправляем ее.
Оно охватывает виджет PopularCaptcha, который Scarnox решает сегодня без прокси. Начните с бесплатного пробного баланса, карта не нужна и опробуйте скрипт сначала на тестовой форме.
Что должен делать Selenium
Поток состоит из четырех частей:
- Загрузить страницу и дождаться отрисовки виджета.
- Прочитать атрибут
data-sitekeyу виджета. - Получить токен из API и поместить его в форму.
- Отправить форму до истечения срока токена.
Третий шаг — единственный, который касается капчи. Все остальное — обычная работа с Selenium.
Установка пакетов
pip install selenium requests
Selenium 4.6 и новее сам находит подходящий ChromeDriver, поэтому скачивать драйвер вручную не нужно.
Полный скрипт
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
API_KEY = "scarnox_YOURAPIKEY"
API_URL = "https://api.scarnox.com/api/tasks/create"
PAGE_URL = "https://example.com/signup"
def solve(sitekey: str, page_url: str, invisible: bool = False) -> str:
body = {
"captcha_type": "PopularCaptchaTaskProxyless",
"site_key": sitekey,
"site_url": page_url,
}
if invisible:
body["is_invisible"] = True
r = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
json=body,
timeout=185, # блокируется, пока токен не будет готов
)
data = r.json()
if data.get("errorId") != 0:
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data["solution"]["token"]
INJECT_TOKEN_JS = """
const token = arguments[0];
let field = document.querySelector('[name="h-captcha-response"]');
if (!field) {
field = document.createElement("textarea");
field.name = "h-captcha-response";
field.style.display = "none";
document.querySelector("form").appendChild(field);
}
field.value = token;
let extra = document.querySelector('[name="g-recaptcha-response"]');
if (!extra) {
extra = document.createElement("textarea");
extra.name = "g-recaptcha-response";
extra.style.display = "none";
document.querySelector("form").appendChild(extra);
}
extra.value = token;
"""
def main() -> None:
driver = webdriver.Chrome()
try:
driver.get(PAGE_URL)
widget = WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey]"))
)
sitekey = widget.get_attribute("data-sitekey")
invisible = widget.get_attribute("data-size") == "invisible"
token = solve(sitekey, driver.current_url, invisible=invisible)
# Сначала заполняем остальные поля, затем вставляем токен непосредственно перед отправкой,
# потому что токен истекает примерно через две минуты.
driver.find_element(By.NAME, "email").send_keys("you@example.com")
driver.execute_script(INJECT_TOKEN_JS, token)
driver.find_element(By.CSS_SELECTOR, "form button[type=submit]").click()
WebDriverWait(driver, 15).until(EC.url_changes(PAGE_URL))
print("Submitted. Now at:", driver.current_url)
finally:
driver.quit()
if __name__ == "__main__":
main()
Для решения PopularCaptcha без прокси прокси не нужен. Уберите поле прокси и пусть сайт видит ваше обычное подключение.
Порядок действий — та часть, в которой чаще всего ошибаются. Сначала заполните остальную форму, затем решите капчу, затем вставьте токен, затем нажмите кнопку. Если решать капчу до ввода в другие поля, медленная страница или медленная форма могут отодвинуть отправку за пределы срока жизни токена. Держите разрыв между решением и кликом как можно короче и проверяйте страницу результата на ошибку, прежде чем считать, что капча пройдена.
Почему токен вставляется через JavaScript
Большинство виджетов PopularCaptcha записывают токен в скрытое textarea с именем h-captcha-response, когда человек решает их. Поскольку Selenium не видит человека, скрипт записывает то же поле сам. Фрагмент INJECT_TOKEN_JS делает две вещи:
- Переиспользует textarea, если виджет уже его создал.
- Создает textarea, если страница его не создала, и добавляет в форму.
Он также заполняет g-recaptcha-response, потому что многие сайты читают это имя для совместимости.
Невидимые виджеты
У невидимого виджета нет чекбокса. Он работает в фоне и обычно срабатывает при отправке формы. Скрипт проверяет data-size="invisible" и отправляет is_invisible: true, когда видит это. Некоторые сайты также привязывают JavaScript callback к виджету. Если форма остается на месте после вставки токена, посмотрите атрибут data-callback и вызовите эту функцию с токеном. Наше руководство по невидимой капче охватывает этот случай.
Использование в тестах
Selenium также обычно используется для сквозных тестов. Если ваш тестовый сайт показывает капчу, тот же код позволяет тесту ее пройти. Держите тестовую среду отдельно от продакшена и не запускайте тесты против сайтов, которыми вы не владеете. Настройка наборов тестов описана в капче в автоматизированных тестах.
Частые проблемы
- Виджет не появляется. Увеличьте ожидание или проверьте, находится ли виджет внутри iframe. Если да, переключитесь на фрейм через
driver.switch_to.frame(...). - Форма отправляется, но сайт отклоняет токен. Проверьте, что токен отправлен на ту страницу, где показан виджет.
driver.current_urlдолжен совпадать с реальным URL страницы, включая строку запроса. - Токен истек. Перенесите вызов
solveближе к шагу отправки. Токен живет около двух минут. - Ошибка таймаута от API. Используйте таймаут около 185 секунд, как в скрипте. Логика повторов описана в обработке ошибок решателя капчи.
Цены
Вы платите за каждое успешное решение. Неудачные решения не тарифицируются. Тарифы — на странице цен, а также начните с бесплатного пробного баланса, карта не нужна.