Розв'язувач капчі для Selenium на Python: робочий приклад (2026)
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 записують токен у приховане текстове поле 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-сайт показує капчу, той самий код дозволяє тесту її пройти. Тримайте тестове середовище окремо від продакшену і не запускайте його проти сайтів, які вам не належать. Налаштування для тестових наборів описано в капчі в автоматизованих тестах.
Типові проблеми
- Віджет ніколи не з'являється. Збільште очікування або перевірте, чи віджет не всередині iframe. Якщо так, переключіться на фрейм через
driver.switch_to.frame(...). - Форма відправляється, але сайт відхиляє токен. Перевірте, що токен надіслано на ту сторінку, де показували віджет.
driver.current_urlмає збігатися з реальною URL сторінки, включно з рядком запиту. - Токен прострочився. Перенесіть виклик
solveближче до кроку відправки. Токен живе приблизно дві хвилини. - Помилка тайм-ауту від API. Використовуйте тайм-аут близько 185 секунд, як у скрипті. Логіку повторів розглянуто в обробці помилок розв'язувача капчі.
Ціни
Ви платите за кожне успішне розв'язання. Невдалі розв'язання не тарифікуються. Актуальні тарифи дивіться на сторінці тарифів, і почніть з безкоштовного пробного кредиту, картка не потрібна.