Explainers

Объяснение невидимых систем CAPTCHA: как они работают

Форма отправляется без ошибок у одних пользователей и молча блокируется у других — а на странице нет ни одного окна с капчей. Это invisible CAPTCHA: проверка идёт в фоне через JavaScript, анализирующий поведение браузера, сигналы устройства и репутацию сети, и решение принимается ещё до клика по кнопке. Ни чекбокса, ни сетки картинок, ни текстового поля — только код ответа сервера.

Для автоматизации это самый неприятный тип защиты: скрипт не видит, что именно его блокирует, — форма просто перестаёт работать. Дальше — как устроены основные invisible-системы (reCAPTCHA v3, Turnstile, reCAPTCHA v2 Invisible, hCaptcha Passive, Apple PAT) и как получать для них токены через API CaptchaAI.


Общая механика: как работает проверка без окна

Все invisible-системы CAPTCHA работают по одной и той же схеме, независимо от поставщика:

Page loads → CAPTCHA JavaScript injected
    ↓
Script runs in background, collecting signals:
  ├─ Browser сигналы браузера (canvas, WebGL, fonts, plugins)
  ├─ Behavioral data (mouse, keyboard, scroll, timing)
  ├─ Network data (IP reputation, TLS сигналы браузера)
  ├─ Device data (screen, GPU, CPU cores, memory)
  └─ History data (cookies, previous CAPTCHA completions)
    ↓
Signals sent to CAPTCHA provider's risk engine
    ↓
Risk score computed
    ↓
Response varies by score:
  ├─ Low risk  → Token issued silently (user sees nothing)
  ├─ Medium    → Light challenge shown (checkbox, simple click)
  └─ High risk → Full challenge (image grid) or block
Категория сигнала Что анализируется
Поведение движения мыши, скорость набора, скролл
Устройство canvas/WebGL, шрифты, память, ядра CPU
Сеть репутация IP, TLS

Главное отличие от классической CAPTCHA: проверка идёт непрерывно с момента загрузки, а не только в момент клика по чекбоксу.


Какие invisible-системы CAPTCHA встречаются чаще всего

1. reCAPTCHA v3

  • Поставщик: Google
  • Релиз: 2018 год
  • Доля рынка: самая высокая среди invisible-систем

reCAPTCHA v3 возвращает число с плавающей точкой от 0,0 до 1,0 для каждого действия на странице. Что делать с этой оценкой — решает сам сайт, Google готового вердикта не даёт.

Как собираются сигналы:

<!-- reCAPTCHA v3 integration -->
<script src="https://www.google.com/recaptcha/api.js?render=SITE_KEY"></script>
<script>
  grecaptcha.ready(function() {
    grecaptcha.execute('SITE_KEY', { action: 'login' }).then(function(token) {
      // Token sent to server for verification
      document.getElementById('captcha-token').value = token;
    });
  });
</script>

Вызов execute() запускает отправку сигналов по требованию, но сбор идёт с момента загрузки скрипта, а не с момента вызова.

Как читать оценку:

На проде порог обычно ставят в районе 0,5–0,7 и снижают только после анализа логов, а не наугад.

Оценка Что означает Типичное действие
0,9 почти наверняка человек пропустить
0,7 вероятно человек пропустить, но логировать
0,5 неопределённо запросить дополнительную проверку
0,3 вероятно бот заблокировать или показать reCAPTCHA v2
0,1 почти наверняка бот заблокировать

Что стоит логировать вместе с оценкой:

  • task_id запроса
  • имя action
  • саму оценку и итоговое решение

Как найти reCAPTCHA v3 в исходном коде страницы:

import requests
import re

def detect_recaptcha_v3(url):
    html = requests.get(url, timeout=10).text
    indicators = {
        "recaptcha_v3": False,
        "site_key": None,
        "actions": [],
    }

    # Check for v3 script
    if "recaptcha/api.js?render=" in html:
        indicators["recaptcha_v3"] = True
        match = re.search(r"render=([A-Za-z0-9_-]+)", html)
        if match:
            indicators["site_key"] = match.group(1)

    # Find action names
    actions = re.findall(r"action:\s*['\"](\w+)['\"]", html)
    indicators["actions"] = actions

    return indicators

print(detect_recaptcha_v3("https://staging.example.com/qa-login"))

2. Cloudflare Turnstile

  • Поставщик: Cloudflare
  • Релиз: 2022 год
  • Доля рынка: заметно растёт год к году

Turnstile проверяет пользователя через многоступенчатый конвейер и не требует сбора персональных данных.

Этапы проверки:

Этап Что происходит
1. Проверка Private Access Token Если браузер поддерживает Apple PAT, проверка завершается мгновенно
2. Неинтерактивная задача Браузер решает лёгкую криптографическую задачу типа proof-of-work
3. Управляемая проверка Cloudflare выбирает режим по сигналам риска из своей сети (20 %+ трафика интернета)
4. Интерактивная проверка Показывается только при высоком риске: пользователь видит виджет с чекбоксом

Как подключить:

<!-- Turnstile widget -->
<div class="cf-turnstile" data-sitekey="0x4AAAAAAAC3DHQhMMQ_Rxrg"></div>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>

Как определить Turnstile на странице:

def detect_turnstile(url):
    html = requests.get(url, timeout=10).text
    indicators = {
        "turnstile": False,
        "site_key": None,
    }

    if "challenges.cloudflare.com/turnstile" in html or "cf-turnstile" in html:
        indicators["turnstile"] = True
        match = re.search(r'data-sitekey="([^"]+)"', html)
        if match:
            indicators["site_key"] = match.group(1)

    return indicators

3. reCAPTCHA v2 Invisible

  • Поставщик: Google
  • Релиз: 2017 год

Это reCAPTCHA v2, запускаемый программно при отправке формы: чекбокс не отображается, проверка идёт в фоне. При высокой оценке риска во всплывающем окне появляется сетка изображений.

Как подключить:

<button class="g-recaptcha"
        data-sitekey="SITE_KEY"
        data-callback="onSubmit"
        data-size="invisible">
    Submit
</button>

Главное отличие от v3: v2 Invisible всё ещё может показать видимую проверку рискованным пользователям. v3 никогда не показывает окно — сайту приходится самому решать, что делать с оценкой.

4. hCaptcha Passive (Enterprise)

  • Поставщик: Intuition Machines
  • Доступность: только тариф Enterprise

Пассивный режим hCaptcha Enterprise оценивает пользователя без виджета: визуальная проверка — только для самых подозрительных. CaptchaAI hCaptcha пока не решает.

5. Apple Private Access Tokens

  • Поставщик: Apple
  • Доступность: iOS 16+, macOS Ventura+

Это не поставщик CAPTCHA, а механизм, позволяющий пропускать её вовсе: устройства Apple подтверждают подлинность через аппаратную аттестацию.

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

Device attestation:

  1. Website requests a challenge from a token issuer
  2. Device proves it is genuine without revealing identity
  3. Token issuer generates a blind-signed token
  4. Website verifies token → CAPTCHA skipped

Поддержана Cloudflare, Fastly и другими CDN.


Сравнение invisible-систем CAPTCHA

Особенность reCAPTCHA v3 Cloudflare Turnstile reCAPTCHA v2 Invisible hCaptcha Passive
Видимая проверка Никогда Редко Иногда (запасной вариант) Редко
Приватность Собирает данные о просмотре Не собирает персональные данные Собирает данные о просмотре Собирает данные о взаимодействии
Стоимость Бесплатно (1 млн/мес) Бесплатно, без лимита Бесплатно (1 млн/мес) Только Enterprise
Оценка возвращается Да (0,0–1,0) Нет (pass/fail) Нет (pass/fail) Да (Enterprise)
Запасная видимая проверка Решает сайт Управляет Cloudflare Всплывающая сетка изображений Всплывающая сетка изображений
Поддержка CaptchaAI Да (токен v3, метод userrecaptcha) Да (токен, метод turnstile) Да (токен, метод userrecaptcha) ❌ не поддерживается

Как решить invisible CAPTCHA через API CaptchaAI

invisible-системы всё равно генерируют токен для отправки формы. Решатели на основе API получают этот токен извне — поднимать реальный браузер не требуется.

Типичный пример: QA-команда в Алматы или Минске гоняет regression-тесты против staging (staging.example.com/qa-login в примерах ниже). CI-раннер с headless-браузером получает низкую оценку, и отправка молча падает — без ошибки CAPTCHA в логах, просто 4xx от бэкенда. Логируя такие сигналы, собирайте только данные, на которые есть основание, — это актуально для команд, ориентирующихся на 152-ФЗ или GDPR.

Решение reCAPTCHA v3

Запрос отправляется в in.php с методом userrecaptcha и version=v3, результат забирается через res.php по task_id:

import requests
import time

API_KEY = "YOUR_API_KEY"

submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": "6LdKlZEpAAAAAAOQjzC2v_d36tWxCl6dWsozdSy9",
    "pageurl": "https://staging.example.com/qa-login",
    "version": "v3",
    "action": "login",
    "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:
        token = result["request"]
        print(f"reCAPTCHA v3 token received (score ≥ 0.9)")
        break

Решение Cloudflare Turnstile

Для Turnstile меняется только метод (turnstile) и параметр sitekey — остальной обмен запрос/ответ идентичен:

submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "turnstile",
    "sitekey": "0x4AAAAAAAC3DHQhMMQ_Rxrg",
    "pageurl": "https://example.com/signup",
    "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:
        turnstile_token = result["request"]
        print(f"Turnstile token received")
        break

Node.js — решение reCAPTCHA v3

Тот же принцип на Node.js через axios, с ручным опросом res.php:

const axios = require("axios");

async function solveRecaptchaV3(siteKey, pageUrl, action) {
    const API_KEY = "YOUR_API_KEY";

    // Submit
    const { data: submit } = await axios.post(
        "https://ocr.captchaai.com/in.php",
        new URLSearchParams({
            key: API_KEY,
            method: "userrecaptcha",
            googlekey: siteKey,
            pageurl: pageUrl,
            version: "v3",
            action: action,
            json: 1,
        })
    );

    const taskId = submit.request;

    // Poll
    for (let i = 0; i < 60; i++) {
        await new Promise((r) => setTimeout(r, 5000));
        const { data: result } = await axios.get(
            "https://ocr.captchaai.com/res.php",
            {
                params: {
                    key: API_KEY,
                    action: "get",
                    id: taskId,
                    json: 1,
                },
            }
        );

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

    throw new Error("Solve timeout");
}

solveRecaptchaV3("SITE_KEY", "https://staging.example.com/qa-login", "login")
    .then((token) => console.log("Token:", token.substring(0, 50) + "..."));

Как определить invisible CAPTCHA на странице

Собрать сигнатуры всех основных типов сразу можно в одном скрипте:

import requests
import re

def detect_invisible_captcha(url):
    """Detect all invisible CAPTCHA types on a page."""
    html = requests.get(url, timeout=10).text

    results = []

    # reCAPTCHA v3
    if "recaptcha/api.js?render=" in html:
        key = re.search(r"render=([A-Za-z0-9_-]+)", html)
        results.append({
            "type": "reCAPTCHA v3",
            "site_key": key.group(1) if key else "unknown",
            "solver_method": "userrecaptcha (version=v3)",
        })

    # reCAPTCHA v2 invisible
    if 'data-size="invisible"' in html and "g-recaptcha" in html:
        key = re.search(r'data-sitekey="([^"]+)"', html)
        results.append({
            "type": "reCAPTCHA v2 Invisible",
            "site_key": key.group(1) if key else "unknown",
            "solver_method": "userrecaptcha (invisible=1)",
        })

    # Cloudflare Turnstile
    if "challenges.cloudflare.com/turnstile" in html:
        key = re.search(r'data-sitekey="([^"]+)"', html)
        results.append({
            "type": "Cloudflare Turnstile",
            "site_key": key.group(1) if key else "unknown",
            "solver_method": "turnstile",
        })

    # hCaptcha (passive mode detected by script without visible widget)
    if "hcaptcha.com/1/api.js" in html and 'data-size="invisible"' in html:
        results.append({
            "type": "hCaptcha Passive",
            "solver_method": "hcaptcha",
        })

    if not results:
        results.append({"type": "none detected"})

    return results

for item in detect_invisible_captcha("https://example.com"):
    print(item)

Как настраивать политику по оценке риска

  • Определите заранее, что происходит на высокой, средней и низкой оценке — до того, как логика попадёт в продакшен-трафик.
  • Средние оценки — повод запросить дополнительную проверку, а не сразу считать запрос ботом.
  • Логируйте распределение оценок во времени: так сдвиг порога на стороне провайдера станет заметен раньше, чем упадёт конверсия.

Частые вопросы

Сколько стоит решение invisible captcha через API?

CaptchaAI тарифицирует по потокам, а не по числу решений:

Что важно Значение
Тариф BASIC — $15/мес, 5 потоков
Лимит решений без ограничений на поток
Разница по типам reCAPTCHA v3 и Turnstile тарифицируются одинаково

Стоимость не зависит от того, какой именно тип invisible CAPTCHA вы решаете.

Как понять, что на странице установлена невидимая CAPTCHA?

Видимого виджета не будет, поэтому единственный надёжный способ — открыть DevTools и поискать в исходном коде или сетевых запросах:

  • recaptcha/api.js?render= — reCAPTCHA v3
  • challenges.cloudflare.com/turnstile — Cloudflare Turnstile
  • hcaptcha.com/1/api.js с data-size="invisible" — пассивный hCaptcha

Что делать, если reCAPTCHA v3 присваивает низкую оценку легитимным пользователям?

Чаще всего дело в слишком строгом threshold, а не в самом reCAPTCHA.

v3 с порогом 0,7+ плюс v2 как запасной вариант для пограничных оценок даёт меньше ложных блокировок, чем один только v3.

Нужен ли токен, если на странице не видно виджета CAPTCHA?

Да. Токен уходит в скрытое поле формы или в параметр запроса.

Отсутствие видимого виджета не означает отсутствие проверки — сервер всё равно ждёт валидный токен.

Отличается ли решение invisible captcha от решения обычной CAPTCHA технически?

Нет. Через API CaptchaAI набор параметров тот же:

  • эндпоинты in.php/res.php
  • метод userrecaptcha (reCAPTCHA) или turnstile (Cloudflare)
  • тот же sitekey/action и тот же формат токена в ответе

Разница лишь в отсутствии взаимодействия с видимым элементом.


Итоги

Invisible CAPTCHA проверяет пользователя фоновым JavaScript — сигналами браузера, поведением и репутацией сети — без видимого элемента.

Основные системы — reCAPTCHA v3 и Turnstile, причём Turnstile растёт быстрее за счёт бесплатной модели и упора на приватность. Для автоматизации это не меняет главного: токен всё равно нужен. Получить его можно через CaptchaAI — reCAPTCHA v3 методом userrecaptcha с version=v3, Turnstile методом turnstile.

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

  1. Geetest против Cloudflare Turnstile: что выбрать
  2. Ошибка 403 в Cloudflare Turnstile после исправления токена
  3. Режимы виджета Cloudflare Turnstile: объяснение
Комментарии для этой статьи отключены.