Scarnox · Blog

Розв'язувач капчі для Selenium на Python: робочий приклад (2026)

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 записують токен у приховане текстове поле h-captcha-response, коли людина розв'язує перевірку. Оскільки Selenium не бачить людини, скрипт записує це поле сам. Фрагмент INJECT_TOKEN_JS робить дві речі:

Він також заповнює g-recaptcha-response, бо багато сайтів читають це ім'я для сумісності.

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

Невидимий віджет не має прапорця. Він працює у фоновому режимі і зазвичай запускається під час відправки форми. Скрипт перевіряє data-size="invisible" і надсилає is_invisible: true, коли бачить це. Деякі сайти також прив'язують до віджета JavaScript callback. Якщо форма залишається на місці після вставки токена, шукайте атрибут data-callback і викличте цю функцію з токеном. Наш посібник про невидиму капчу розглядає цей випадок.

Використання в тестах

Selenium також є звичайним інструментом для end-to-end тестів. Якщо ваш власний staging-сайт показує капчу, той самий код дозволяє тесту її пройти. Тримайте тестове середовище окремо від продакшену і не запускайте його проти сайтів, які вам не належать. Налаштування для тестових наборів описано в капчі в автоматизованих тестах.

Типові проблеми

Ціни

Ви платите за кожне успішне розв'язання. Невдалі розв'язання не тарифікуються. Актуальні тарифи дивіться на сторінці тарифів, і почніть з безкоштовного пробного кредиту, картка не потрібна.

Що далі