Форма отправляется без ошибок у одних пользователей и молча блокируется у других — а на странице нет ни одного окна с капчей. Это 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 v3challenges.cloudflare.com/turnstile— Cloudflare Turnstilehcaptcha.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.