Эта статья была полезной?
Как обойти GeeTest с помощью Playwright
Технический специалист
GeeTest — одна из самых популярных капч на рынке, особенно в Азии и среди крупных e-commerce площадок. Она выглядит как слайдер-пазл, где нужно перетащить кусочек изображения в нужное место, но под капотом скрывается серьёзная проверка поведения пользователя.
В этом руководстве мы разберём полный цикл обхода GeeTest в Playwright: определим версию капчи (v3 или v4), извлечём нужные параметры, получим решение через API 2Captcha и корректно внедрим ответные токены в форму.
Примечание: GeeTest v3 и v4 требуют совершенно разных параметров. Если отправить challenge от v3 в задачу v4 — капча не пройдёт. Поэтому первый и самый важный шаг — правильно определить версию.
Что понадобится
- Python 3.7 или выше
- Установленный Playwright
- Аккаунт и API-ключ от 2Captcha
- URL целевой страницы с GeeTest
- Опционально: прокси, если сайт чувствителен к IP-адресам
Шаг 1. Установка зависимостей
Установите необходимые библиотеки и браузеры Playwright:
bash
pip install playwright 2captcha-python
playwright install chromium
Шаг 2. Инициализация браузера и определение версии
Начнём с открытия страницы и определения, с какой версией GeeTest мы имеем дело. Для отладки используйте видимый режим headless=False.
python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://2captcha.com/demo/geetest")
# Ожидание появления виджета GeeTest
page.wait_for_selector(".geetest_panel_box")
Чтобы понять версию, откройте DevTools и посмотрите исходный код или вкладку Network:
- Если рядом со значением gt вы видите challenge — это v3
- Если видите только captcha_id — это v4
- Скрипт v4 загружается с gcaptcha4.geetest.com/load
Шаг 3. Извлечение параметров для GeeTest v3
Для v3 нужны два значения: gt (статический ключ сайта) и challenge (динамический одноразовый токен).
python
# Извлекаем статический gt
gt = page.evaluate("window.GeeTest_gt || document.querySelector('.geetest_wind').getAttribute('data-gt')")
# Извлекаем динамический challenge
# Важно: challenge генерируется при каждом открытии капчи и одноразовый!
challenge = page.evaluate("""
() => {
// Ищем в сетевых запросах или в глобальных переменных
return window.GeeTest_challenge ||
document.querySelector('script[data-challenge]')?.getAttribute('data-challenge');
}
""")
print(f"GT: {gt}")
print(f"Challenge: {challenge}")
Важно: параметр challenge одноразовый. Если вы скопируете его один раз и будете переиспользовать, API вернёт ошибку истёкшего токена. Перед каждой отправкой задачи нужно перехватывать свежий challenge из сетевого запроса страницы к /ajax.php или аналогичному эндпоинту GeeTest.
Чтобы перехватить его, используйте route или отслеживайте сетевые ответы:
python
captured_challenge = None
def handle_response(response):
global captured_challenge
if "ajax.php" in response.url and "gt=" in response.url:
# Извлекаем challenge из URL запроса
import urllib.parse
params = urllib.parse.parse_qs(urllib.parse.urlparse(response.url).query)
if "challenge" in params:
captured_challenge = params["challenge"][0]
page.on("response", handle_response)
# Перезагружаем страницу или кликаем на виджет, чтобы спровоцировать запрос
page.reload()
page.wait_for_timeout(3000)
print(f"Перехвачен свежий challenge: {captured_challenge}")
Шаг 4. Извлечение параметров для GeeTest v4
С v4 всё проще: нужен только статический captcha_id, который не протухает.
python
# Извлекаем captcha_id из скрипта загрузки или DOM
captcha_id = page.evaluate("""
() => {
// Ищем в URL скрипта v4
const scripts = document.querySelectorAll('script[src*="gcaptcha4"]');
for (const script of scripts) {
const url = new URL(script.src);
if (url.searchParams.has('captcha_id')) {
return url.searchParams.get('captcha_id');
}
}
// Или ищем в initGeetest4 вызове
return window.captchaId || null;
}
""")
print(f"Captcha ID: {captcha_id}")
Шаг 5. Отправка задачи в API и получение токенов
Используем официальный Python SDK. Он автоматически создаёт задачу и опрашивает сервер до получения результата.
Для GeeTest v3:
python
from twocaptcha import TwoCaptcha
solver = TwoCaptcha('ВАШ_API_КЛЮЧ')
result = solver.geetest(
gt=gt,
challenge=captured_challenge,
url=page.url
)
print(f"Ответ v3: {result}")
# result содержит: challenge, validate, seccode
Для GeeTest v4:
python
result = solver.geetest_v4(
captcha_id=captcha_id,
url=page.url
)
print(f"Ответ v4: {result}")
# result содержит: captcha_id, lot_number, pass_token, gen_time, captcha_output
Шаг 6. Внедрение ответа в форму
Ответ нужно внедрить в форму так, как это сделал бы сам GeeTest после ручного решения.
Для GeeTest v3 внедряем три токена:
python
page.evaluate(f"""
const form = document.querySelector('form');
// Создаём скрытые поля, если их нет
const fields = ['geetest_challenge', 'geetest_validate', 'geetest_seccode'];
const values = ['{result['challenge']}', '{result['validate']}', '{result['seccode']}'];
fields.forEach((name, i) => {{
let input = form.querySelector(`input[name="${{name}}"]`);
if (!input) {{
input = document.createElement('input');
input.type = 'hidden';
input.name = name;
form.appendChild(input);
}}
input.value = values[i];
}});
// Вызываем callback, если он задан
if (typeof window.geetestCallback === 'function') {{
window.geetestCallback('{result['validate']}');
}}
""")
Для GeeTest v4 внедряем пять полей:
python
page.evaluate(f"""
const form = document.querySelector('form');
const fields = ['lot_number', 'pass_token', 'gen_time', 'captcha_output'];
const values = [
'{result['lot_number']}',
'{result['pass_token']}',
'{result['gen_time']}',
'{result['captcha_output']}'
];
fields.forEach((name, i) => {{
let input = form.querySelector(`input[name="${{name}}"]`);
if (!input) {{
input = document.createElement('input');
input.type = 'hidden';
input.name = name;
form.appendChild(input);
}}
input.value = values[i];
}});
// Вызываем callback для v4
if (typeof window.captchaCallback === 'function') {{
window.captchaCallback('{result['pass_token']}');
}}
""")
Шаг 7. Отправка формы
После внедрения токенов форма должна считать себя валидной.
python
page.click("button[type='submit']")
page.wait_for_load_state("networkidle")
browser.close()
Решение частых проблем
| Проблема | Причина и решение |
|---|---|
| API возвращает ошибку истёкшего challenge | Для v3 challenge одноразовый. Перехватывайте свежий challenge из сетевого запроса перед каждой отправкой задачи. |
| Не удаётся найти captcha_id для v4 | Скрипт загружается динамически. Дождитесь появления тега script с src, содержащим gcaptcha4.geetest.com, и извлеките параметр captcha_id из URL. |
| Форма не отправляется после внедрения токенов | Сайт ожидает вызова JavaScript-колбэка. Найдите имя функции в атрибуте data-callback или в коде инициализации GeeTest и вызовите её через page.evaluate. |
| Появляется дополнительная проверка поведения | GeeTest анализирует движение мыши и время взаимодействия. Используйте реалистичные задержки, эмулируйте движение мыши через page.mouse.move перед кликом на виджет. |
| Скрипт работает в видимом режиме, но падает в headless | Это детекция headless-режима антибот-системой. Используйте библиотеки для маскировки (например, playwright-stealth) или передавайте в API качественные резидентские прокси. |
Заключение
Автоматизация обхода GeeTest в Playwright сводится к чёткому пониманию версии капчи и правильному извлечению параметров. Для v3 критически важно перехватывать свежий challenge перед каждой задачей, так как этот токен одноразовый. Для v4 достаточно один раз найти статический captcha_id и использовать его повторно.
После получения решения от API ключевой момент — корректное внедрение токенов в форму. Для v3 это три поля (challenge, validate, seccode), для v4 — пять полей (lot_number, pass_token, gen_time, captcha_output, captcha_id). Многие сайты также ожидают вызова JavaScript-колбэка, который разблокирует кнопку отправки формы.
Следуя этому руководству, вы сможете надёжно обходить GeeTest обеих версий, превратив капчу из источника ошибок в предсказуемый этап вашей автоматизации.
Полезные ссылки
- Документация API 2Captcha по GeeTest: https://2captcha.com/api-docs/geetest
- Демо-страница GeeTest v3: https://2captcha.com/demo/geetest
- Демо-страница GeeTest v4: https://2captcha.com/demo/geetest-v4
- Python SDK 2Captcha на GitHub: https://github.com/2captcha/2captcha-python