Логотип «2Captcha»Перейти на главную страницу
Туториалы по обходу капчи

Эта статья была полезной?

Как обойти 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 Copy
pip install playwright 2captcha-python
playwright install chromium

Шаг 2. Инициализация браузера и определение версии

Начнём с открытия страницы и определения, с какой версией GeeTest мы имеем дело. Для отладки используйте видимый режим headless=False.

python Copy
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 Copy
# Извлекаем статический 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 Copy
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 Copy
# Извлекаем 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 Copy
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 Copy
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 Copy
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 Copy
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 Copy
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 обеих версий, превратив капчу из источника ошибок в предсказуемый этап вашей автоматизации.

Полезные ссылки