Comparisons

Управляемый вызов Cloudflare против интерактивного вызова

Вернулся 503 без единого видимого элемента на странице? Это, скорее всего, Managed Challenge — он уже пропустил запрос невидимо. Пришёл 403 с полноэкранным виджетом? Это Interactive Challenge, устаревшее действие, которое требует взаимодействия всегда. Разница определяет и то, что увидит посетитель, и какой метод CaptchaAI вызывать: turnstile для видимого виджета или cloudflare_challenge для полностраничной JS-проверки. Коротко о том, что меняется, если сайт вот-вот перейдёт с одного типа на другой:

  • Interactive → Managed: запрос может начать проходить невидимо (шанс ~90%).
  • HTTP 403 → 503: обновите проверку кода ответа в своём коде.
  • Всегда видимый виджет → адаптивный: он может вовсе отсутствовать в HTML.
  • Sitekey не меняется, код решения CaptchaAI остаётся прежним.
  • qa_validation_cookie тот же — логика обработки cookie не меняется.

Чем управляемый вызов отличается от интерактивного

Параметр Managed Challenge Interactive Challenge
Появился 2021 год До 2021 года (наследие)
Адаптивный? Да — Cloudflare оценивает каждый визит отдельно Нет — всегда интерактивен
Возможно невидимое прохождение? Да, ~90% посетителей проходят незаметно Нет, CAPTCHA показывается всегда
Какие проверки задействует Невидимая проверка → Turnstile → JS-задача Всегда видимая CAPTCHA
Рекомендован Cloudflare? Да, вариант по умолчанию для новых правил Нет, оставлен для обратной совместимости
Трение для пользователя Низкое — большинство ничего не замечает Высокое — взаимодействие обязательно
HTTP-статус 503 403
Метод CaptchaAI turnstile или cloudflare_challenge turnstile

Что важно запомнить в первую очередь:

  1. Managed Challenge — вариант по умолчанию для новых WAF-правил, Interactive Challenge — наследие для обратной совместимости.
  2. HTTP-статус сразу подсказывает тип: 503 значит Managed, 403 значит Interactive.
  3. Оба варианта решаются через CaptchaAI, разница только в методе API.

Как работает Managed Challenge изнутри

Managed Challenge — рекомендуемое действие Cloudflare для новых WAF-правил. Вместо того чтобы показывать CAPTCHA каждому подряд, Cloudflare оценивает сигналы конкретного визита и подбирает наименее навязчивую проверку.

Ключевая мысль: сложность проверки подбирается динамически, поэтому один и тот же маршрут может в разные заходы выглядеть по-разному в логах.

Логика принятия решения

WAF rule triggers Managed Challenge
    ↓
Cloudflare evaluates visitor signals:
  ├─ Browser сигналы браузера quality
  ├─ IP reputation score
  ├─ TLS сигналы браузера (JA3/JA4)
  ├─ Request history
  ├─ Behavioral signals
  └─ Device capabilities
    ↓
Risk assessment → Challenge level selected:
  ├─ LOW risk → Invisible pass (no visible UI)
  ├─ MEDIUM risk → Non-interactive Turnstile (background PoW)
  ├─ HIGH risk → Interactive Turnstile (checkbox/widget)
  └─ VERY HIGH risk → JavaScript challenge page (5s wait)
    ↓
Challenge completed
    ↓
qa_validation_cookie cookie issued

Что видит посетитель — по уровню риска

  1. Обычный браузер, чистый IP — ничего не видно, прохождение полностью невидимое (~90% посетителей).
  2. Новый браузер, нейтральный IP — короткий спиннер на экране (~5%).
  3. Подозрительные сигналы — чекбокс Cloudflare Turnstile (~4%).
  4. Сигналы высокого риска — страница «Проверка браузера…» (~1%).

HTML управляемого вызова

Страницы Managed Challenge используют платформу проверок Cloudflare:

<!-- Managed Challenge page (when visible) -->
<body>
    <div id="challenge-stage">
        <div id="challenge-body-text">
            Verifying you are human. This may take a few seconds.
        </div>

        <!-- Turnstile widget (when rendered) -->
        <div class="cf-turnstile"
             data-sitekey="0x4AAAAAAAC3DHQhMMQ_Rxrg">
        </div>
    </div>

    <!-- Challenge platform script -->
    <script src="/cdn-cgi/challenge-platform/h/g/orchestrate/managed/v1?ray=...">
    </script>
</body>

Подсказка: sitekey для Turnstile-виджета лежит в атрибуте data-sitekey — его можно вытащить регуляркой, не поднимая полноценный браузер.


Interactive Challenge: вызов без исключений

Interactive Challenge не оценивает риск конкретного визита — каждый посетитель видит полноэкранную CAPTCHA и обязан пройти её. Невидимого прохождения здесь не предусмотрено в принципе.

Два факта, которые стоит держать в голове при автоматизации именно этого варианта:

  • сайт может использовать его выборочно, только для отдельных маршрутов WAF-правил;
  • код решения не отличается от Managed Challenge — тот же метод turnstile, другой лишь код ответа.

Как это работает

WAF rule triggers Interactive Challenge
    ↓
Full-page CAPTCHA served (HTTP 403)
    ↓
Visitor must interact with CAPTCHA widget
    ↓
CAPTCHA solved
    ↓
qa_validation_cookie cookie issued

Единственный сценарий для посетителя

Каждый посетитель видит полностраничную задачу с виджетом, похожим на Turnstile:

<!-- Interactive Challenge page -->
<body>
    <div id="challenge-running">
        <div class="main-wrapper">
            <h2>Please verify you are human</h2>

            <!-- Always-visible challenge widget -->
            <div class="challenge-widget">
                <!-- Checkbox + verification -->
            </div>
        </div>
    </div>
</body>

Подсказка: разметка почти повторяет Managed Challenge, но виджет challenge-widget рендерится всегда, а не по результату оценки риска.

Почему Cloudflare не рекомендует его для новых правил

  • Виден всегда — 100% посетителей видят проверку.
  • Больше трения — взаимодействие обязательно для каждого.
  • Выше показатель отказов — часть пользователей уходит, не пройдя проверку.
  • Нет адаптации к риску — даже доверенные посетители проходят её.
  • Проблемы доступности — взаимодействие обязательно для всех без исключения.

Как определить тип вызова по ответу сервера

Прежде чем выбирать метод CaptchaAI, разберитесь, что именно вернул сервер, — без доступа к панели Cloudflare это единственный надёжный способ. Следующая функция классифицирует ответ по HTTP-статусу и содержимому страницы:

import requests
import re

def identify_challenge_type(url):
    """Determine if a URL uses Managed or Interactive Challenge."""
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 Chrome/120.0.0.0",
        "Accept": "text/html,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.9",
    }

    response = requests.get(url, headers=headers, timeout=15, allow_redirects=False)
    html = response.text
    status = response.status_code

    result = {
        "url": url,
        "status": status,
        "challenge_type": None,
        "cf_ray": response.headers.get("cf-ray", ""),
        "solve_method": None,
    }

    if status == 200:
        # Check for inline Turnstile widget (not a challenge page)
        if "cf-turnstile" in html:
            result["challenge_type"] = "turnstile_widget"
            result["solve_method"] = "turnstile"
        else:
            result["challenge_type"] = "none"
        return result

    if status == 503:
        # 503 indicates Managed Challenge or IUAM
        if "managed" in html or "challenge-platform" in html:
            result["challenge_type"] = "managed_challenge"
            result["solve_method"] = "turnstile"  # Managed renders as Turnstile
        elif "jschl" in html:
            result["challenge_type"] = "iuam_js_challenge"
            result["solve_method"] = "turnstile"
        else:
            result["challenge_type"] = "unknown_503"
        return result

    if status == 403:
        if "challenge" in html.lower():
            result["challenge_type"] = "interactive_challenge"
            result["solve_method"] = "turnstile"
        else:
            result["challenge_type"] = "waf_block"
            result["solve_method"] = None  # Hard block, not solvable
        return result

    return result


# Usage
info = identify_challenge_type("https://protected-site.com/login")
print(f"Challenge: {info['challenge_type']}")
print(f"Solve with: {info['solve_method']}")

Сигналы для быстрой диагностики

Четыре типа ответа различаются по сочетанию признаков:

  • Managed Challenge — HTTP 503, в HTML есть challenge-platform, путь managed в скрипте, невидимое прохождение возможно.
  • Interactive Challenge — HTTP 403, в HTML есть challenge-platform, виджет виден всегда, невидимого прохождения не бывает.
  • IUAM (устаревшая JS-проверка) — HTTP 503, в HTML есть jschl, без challenge-platform и без managed.
  • Блок WAF — HTTP 403 без единого признака проверки: это не вызов, а жёсткая блокировка.

Как решать оба типа через API CaptchaAI

Managed Challenge: какой метод вызвать

Managed Challenge почти всегда рендерится как виджет Turnstile — вызывайте метод turnstile. Если видимого виджета на странице нет, значит проверка ушла на JS-уровень, и нужен cloudflare_challenge:

import requests
import time

API_KEY = "YOUR_API_KEY"

def solve_managed_challenge(url, sitekey=None):
    """Solve Cloudflare Managed Challenge."""
    # If sitekey not provided, extract from page
    if not sitekey:
        import re
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                          "AppleWebKit/537.36 Chrome/120.0.0.0",
        }
        page = requests.get(url, headers=headers, timeout=15)
        match = re.search(
            r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']', page.text
        )
        sitekey = match.group(1) if match else None

    if not sitekey:
        # No visible Turnstile — try turnstile method
        return solve_js_challenge(url)

    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "turnstile",
        "sitekey": sitekey,
        "pageurl": url,
        "json": 1,
    })

    task_id = submit.json()["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1,
        }).json()

        if result.get("status") == 1:
            return result["request"]

    raise TimeoutError("Solve timed out")


def solve_js_challenge(url):
    """Fallback to turnstile method."""
    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "turnstile",
        "sitekey": "managed",
        "pageurl": url,
        "json": 1,
    })

    task_id = submit.json()["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1,
        }).json()

        if result.get("status") == 1:
            return result["request"]

    raise TimeoutError("Solve timed out")

Подсказка: оба вызова опрашивают res.php одним и тем же циклом — отдельная логика ретраев под каждый тип не нужна.

Interactive Challenge: тот же виджет, тот же метод

Interactive Challenge всегда показывает виджет, похожий на Turnstile, поэтому здесь тоже подходит метод turnstile:

def solve_interactive_challenge(url, sitekey):
    """Solve Cloudflare Interactive Challenge (legacy)."""
    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "turnstile",
        "sitekey": sitekey,
        "pageurl": url,
        "json": 1,
    })

    task_id = submit.json()["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1,
        }).json()

        if result.get("status") == 1:
            return result["request"]

    raise TimeoutError("Solve timed out")

Итого для Python: одна и та же пара «отправить → опросить» покрывает оба типа вызова, различается только значение method.

Пример на Node.js для обоих сценариев

const axios = require("axios");

const API_KEY = "YOUR_API_KEY";

async function solveCloudflareChallenge(url, type = "managed") {
  const method = type === "js_challenge" ? "turnstile" : "turnstile";
  const sitekey =
    type === "js_challenge" ? "managed" : await extractSitekey(url);

  const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
    params: {
      key: API_KEY,
      method,
      sitekey: sitekey || "managed",
      pageurl: url,
      json: 1,
    },
  });

  const taskId = submit.data.request;

  for (let i = 0; i < 60; i++) {
    await new Promise((r) => setTimeout(r, 5000));

    const result = await axios.get("https://ocr.captchaai.com/res.php", {
      params: { key: API_KEY, action: "get", id: taskId, json: 1 },
    });

    if (result.data.status === 1) {
      return result.data.request;
    }
  }

  throw new Error("Solve timed out");
}

async function extractSitekey(url) {
  try {
    const response = await axios.get(url, {
      headers: { "User-Agent": "Mozilla/5.0 Chrome/120.0.0.0" },
      validateStatus: () => true,
    });
    const match = response.data.match(
      /data-sitekey=["']([0-9x][A-Za-z0-9_-]+)["']/
    );
    return match ? match[1] : null;
  } catch {
    return null;
  }
}

Часто задаваемые вопросы

Пять вопросов, которые чаще всего задают при настройке автоматизации под оба типа вызова:

  • Как отличить Managed Challenge от Interactive Challenge без доступа к панели Cloudflare? Смотрите на HTTP-статус и содержимое ответа: 503 с challenge-platform или путём managed в скрипте — это Managed Challenge; 403 с видимым виджетом — Interactive Challenge. Функция обнаружения из раздела выше делает это автоматически.
  • Почему один и тот же сайт то пропускает автоматизацию невидимо, то показывает Turnstile? Managed Challenge пересчитывает риск для каждого запроса: репутация IP и поведенческие сигналы меняются, поэтому один и тот же маршрут может в одном прогоне пройти без проверки, а в другом — потребовать решения через turnstile.
  • Нужно ли увеличивать таймаут, если Managed поднимает уровень до JS-задачи? Нет — cloudflare_challenge решается в те же сроки, что и turnstile; опрашивайте res.php тем же циклом.
  • Можно ли использовать общий пул потоков CaptchaAI для доменов на Managed и Interactive одновременно? Да, тарификация идёт по потокам, а не по типу CAPTCHA или домену — один план обслуживает оба сценария.
  • Как логировать переключения типа вызова для мониторинга? Пишите в лог URL, HTTP-статус и challenge_type при каждом прогоне; рост доли видимых проверок обычно сигнализирует об изменении репутации IP.

Типичные проблемы и что с ними делать

  1. 503 без видимого виджета — Managed Challenge пройден невидимо, действий не требуется, вы уже прошли.
  2. 503 с «Проверка браузера» — Managed поднял уровень до JS-задачи, используйте метод cloudflare_challenge.
  3. 403 с видимой CAPTCHA — Interactive Challenge (наследие), используйте метод turnstile.
  4. 403 без единого признака проверки — блокировка WAF, а не вызов; смените IP или паттерн запроса.
  5. qa_validation_cookie одного типа не принимается для другого маршрута — на разных маршрутах домена могут действовать разные потоки проверки; решайте тот вызов, который показан именно сейчас.

Пример из практики: staging QA-стенд под Cloudflare

Команда QA-автоматизации тестирует staging checkout за Cloudflare из CI-раннеров в Европе. Днём ~90% прогонов проходят Managed Challenge невидимо, ночью доля видимого Turnstile растёт до 15–20% из-за смены репутации IP-диапазона провайдера. Детектор из раздела выше помечает каждый прогон типом вызова и solve_method, а CaptchaAI решает то, что реально показано, без ручного вмешательства.

Логируя содержимое страниц, собирайте только те данные, на обработку которых у вас есть основание, — для российской юрисдикции это 152-ФЗ «О персональных данных», для трансграничных команд полезно держать в уме и GDPR. Для агентств, проверяющих десятки доменов клиентов, предсказуемая стоимость по потокам CaptchaAI — например, ADVANCE ($90/мес, 50 потоков) — удобнее оплаты за каждое решение.

Краткое содержание

  • И Managed Challenge, и Interactive Challenge решаются через CaptchaAI, разница только в деталях.
  • Managed Challenge адаптивно подбирает сложность — от невидимого прохождения до полной JS-задачи; решается методом turnstile (видимый виджет) или cloudflare_challenge (JS-уровень).
  • Interactive Challenge всегда показывает видимую CAPTCHA и решается методом turnstile.
  • Оба варианта завершаются одним и тем же qa_validation_cookie, поэтому логика обработки cookie не зависит от типа вызова.

Похожие статьи

Комментарии для этой статьи отключены.