Scarnox · Blog

Решатель капчи для Selenium на Python: рабочий пример (2026)

Selenium запускает настоящий браузер, поэтому страница отрисовывается и ее скрипты выполняются так же, как для человека. Единственный шаг, который Selenium не может выполнить, — решить виджет PopularCaptcha. Это руководство добавляет этот шаг: читаем sitekey с отрисованной страницы, получаем токен одним вызовом API, записываем токен в форму и отправляем ее.

Оно охватывает виджет PopularCaptcha, который Scarnox решает сегодня без прокси. Начните с бесплатного пробного баланса, карта не нужна и опробуйте скрипт сначала на тестовой форме.

Что должен делать Selenium

Поток состоит из четырех частей:

  1. Загрузить страницу и дождаться отрисовки виджета.
  2. Прочитать атрибут data-sitekey у виджета.
  3. Получить токен из API и поместить его в форму.
  4. Отправить форму до истечения срока токена.

Третий шаг — единственный, который касается капчи. Все остальное — обычная работа с 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 делает две вещи:

Он также заполняет g-recaptcha-response, потому что многие сайты читают это имя для совместимости.

Невидимые виджеты

У невидимого виджета нет чекбокса. Он работает в фоне и обычно срабатывает при отправке формы. Скрипт проверяет data-size="invisible" и отправляет is_invisible: true, когда видит это. Некоторые сайты также привязывают JavaScript callback к виджету. Если форма остается на месте после вставки токена, посмотрите атрибут data-callback и вызовите эту функцию с токеном. Наше руководство по невидимой капче охватывает этот случай.

Использование в тестах

Selenium также обычно используется для сквозных тестов. Если ваш тестовый сайт показывает капчу, тот же код позволяет тесту ее пройти. Держите тестовую среду отдельно от продакшена и не запускайте тесты против сайтов, которыми вы не владеете. Настройка наборов тестов описана в капче в автоматизированных тестах.

Частые проблемы

Цены

Вы платите за каждое успешное решение. Неудачные решения не тарифицируются. Тарифы — на странице цен, а также начните с бесплатного пробного баланса, карта не нужна.

Следующие шаги