Looking for international version of our service? Go to 2captcha.com

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

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

Как обойти Cloudflare Turnstile с помощью Playwright

Грегори Фишер
Грегори Фишер

Технический специалист

Cloudflare Turnstile — это современная и более дружелюбная к приватности альтернатива классическим капчам. Вместо того чтобы просить пользователя кликать по картинкам, Turnstile незаметно анализирует поведение браузера, окружение и репутацию IP-адреса, чтобы отличить человека от бота. В большинстве случаев проверка проходит невидимо — но для скриптов автоматизации, QA-тестирования и скрапинга Turnstile всё равно может заблокировать доступ к нужной странице.

В этом туториале показано, как обойти Cloudflare Turnstile в Playwright с помощью API RuCaptcha: найти виджет, получить решённый токен от RuCaptcha, вставить его на страницу и продолжить автоматизацию так, будто проверку прошёл реальный пользователь.

Что понадобится

  • Установленный Node.js или Python
  • Установленный Playwright для вашего языка
  • Аккаунт RuCaptcha и API-ключ (получить здесь)
  • URL целевой страницы и, если для виджета нужна привязка к конкретному IP, рабочий прокси

Есть два разных сценария:

  • Обычный виджет Turnstile — капча встроена прямо в страницу (например, в форму регистрации или входа). Именно этот случай разобран в туториале.
  • Cloudflare Challenge page — Cloudflare полностью заменяет страницу экраном проверки перед тем, как пропустить браузер дальше. Этот сценарий требует дополнительных параметров (cData, chlPageData, action) и разбирается в отдельном туториале.

Шаг 1. Установка зависимостей

Для Python:

bash Copy
pip install playwright 2captcha-python
playwright install chromium

Для Node.js:

bash Copy
npm install playwright @2captcha/captcha-solver
npx playwright install chromium

Шаг 2. Запуск браузера и открытие целевой страницы

Начните с обычной сессии Playwright. Пока вы пишете и тестируете скрипт, запускайте браузер в видимом режиме (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://rucaptcha.com/demo/cloudflare-turnstile")
    page.wait_for_selector(".cf-turnstile")

Шаг 3. Извлечение sitekey из виджета Turnstile

Каждый виджет Turnstile хранит свой sitekey в атрибуте data-sitekey контейнера .cf-turnstile. Достать его из DOM можно через get_attribute:

python Copy
sitekey = page.locator(".cf-turnstile").get_attribute("data-sitekey")
page_url = page.url

print(f"Sitekey: {sitekey}")
print(f"Page URL: {page_url}")

Если виджет рендерится динамически через JavaScript (turnstile.render(...)), а не как статичный div, поищите sitekey в исходном коде страницы или перехватите сетевой запрос к challenges.cloudflare.com — там sitekey передаётся как query-параметр.

Шаг 4. Отправка sitekey в RuCaptcha и получение токена

Имея sitekey и URL страницы, отправьте их в RuCaptcha. Python SDK сам создаёт задачу и опрашивает результат, пока капча не будет решена:

python Copy
from twocaptcha import TwoCaptcha

solver = TwoCaptcha('YOUR_API_KEY')

result = solver.turnstile(
    sitekey=sitekey,
    url=page_url
)

token = result['code']
print(f"Получен токен: {token}")

Это вызывает метод turnstile официального SDK 2captcha-python, который отправляет задачу в API RuCaptcha и опрашивает результат, пока капча не будет решена. Решение обычно занимает 10–20 секунд. Если виджету нужны дополнительные параметры (action, data/cData, pagedata), передайте их как дополнительные именованные аргументы — solver.turnstile(sitekey=sitekey, url=page_url, action='login', data='...').

Если вы обращаетесь напрямую к API, а не через SDK, запрос выглядит так (proxyless-режим, используется, когда виджету не нужен прокси, привязанный к конкретному IP):

bash Copy
curl -X POST https://api.rucaptcha.com/createTask \
  -H "Content-Type: application/json" \
  -d '{
    "clientKey": "YOUR_API_KEY",
    "task": {
      "type": "TurnstileTaskProxyless",
      "websiteURL": "https://rucaptcha.com/demo/cloudflare-turnstile",
      "websiteKey": "3x00000000000000000000FF"
    }
  }'

Если нужен прокси, привязанный к задаче, используйте type: "TurnstileTask" и добавьте поля proxyType, proxyAddress, proxyPort, proxyLogin, proxyPassword — подробнее в документации по API Cloudflare Turnstile.

Шаг 5. Вставка токена на страницу

Получив токен, нужно поместить его в скрытое поле, которое создаёт Turnstile — обычно это . Так как это поле не принимает ввод через клавиатуру, значение нужно выставить напрямую через page.evaluate:

python Copy
page.evaluate(f"""
    document.querySelector('input[name="cf-turnstile-response"]').value = "{token}";
""")

На некоторых страницах одного значения поля недостаточно — сайт ожидает срабатывания callback-функции виджета, поскольку именно она активирует кнопку «Отправить» или запускает дополнительную клиентскую логику. Если callback настроен, вызовите его явно — вместо простой установки значения или вместе с ней:

python Copy
page.evaluate(f"""
    if (window.turnstileCallback) {{
        window.turnstileCallback("{token}");
    }}
""")

Узнать имя callback-функции можно по атрибуту data-callback элемента .cf-turnstile, либо посмотрев вызов turnstile.render() в JavaScript-коде страницы.

Шаг 6. Продолжение автоматизации

На этом этапе страница считает, что проверку прошёл живой человек. Отправляйте форму или продолжайте навигацию как обычно:

python Copy
page.click("button[type='submit']")
page.wait_for_load_state("networkidle")

browser.close()

Полный рабочий пример (Python)

python Copy
from playwright.sync_api import sync_playwright
from twocaptcha import TwoCaptcha

API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://rucaptcha.com/demo/cloudflare-turnstile"

solver = TwoCaptcha(API_KEY)

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto(TARGET_URL)
    page.wait_for_selector(".cf-turnstile")

    sitekey = page.locator(".cf-turnstile").get_attribute("data-sitekey")

    result = solver.turnstile(sitekey=sitekey, url=TARGET_URL)
    token = result['code']

    page.evaluate(f"""
        document.querySelector('input[name="cf-turnstile-response"]').value = "{token}";
        if (window.turnstileCallback) {{
            window.turnstileCallback("{token}");
        }}
    """)

    page.click("button[type='submit']")
    page.wait_for_load_state("networkidle")

    browser.close()

Версия на Node.js (Playwright + JavaScript)

javascript Copy
const { chromium } = require('playwright');
const Captcha = require('@2captcha/captcha-solver');

const solver = new Captcha.Solver('YOUR_API_KEY');
const targetUrl = 'https://rucaptcha.com/demo/cloudflare-turnstile';

(async () => {
  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto(targetUrl);
  await page.waitForSelector('.cf-turnstile');

  const sitekey = await page.locator('.cf-turnstile').getAttribute('data-sitekey');

  const result = await solver.cloudflareTurnstile({
    pageurl: targetUrl,
    sitekey: sitekey
  });
  const token = result.data;

  await page.evaluate((token) => {
    document.querySelector('input[name="cf-turnstile-response"]').value = token;
    if (window.turnstileCallback) {
      window.turnstileCallback(token);
    }
  }, token);

  await page.click("button[type='submit']");
  await page.waitForLoadState('networkidle');

  await browser.close();
})();

Решение проблем

  • Токен отклоняется / форма не отправляется — проверьте, что значение подставляется в поле с правильным именем, и что callback (если он есть) действительно вызывается.
  • Sitekey не найден — виджет может подгружаться внутри iframe уже после загрузки страницы; дождитесь сетевого запроса к challenges.cloudflare.com/turnstile и возьмите sitekey из его query-строки вместо DOM.
  • Работает с headless: False, но не работает с headless: True — Cloudflare также учитывает фингерпринт браузера при оценке риска. Комбинируйте решённый токен с прокси и реалистичным user-agent, а также рассмотрите playwright-extra со stealth-плагином, чтобы снизить признаки headless-режима.
  • Токен получен, но всё равно редиректит на Challenge page — вы столкнулись со сценарием Cloudflare Challenge page, а не обычным виджетом. Для этого случая нужны дополнительные параметры cData/chlPageData/action, которые описаны в туториале по Cloudflare Challenge.

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