Comparisons

Сравнение reCAPTCHA v3 Enterprise и Standard

Разница между версиями видна не пользователю, а тому, кто пишет интеграцию. Обе работают невидимо и возвращают score от 0,0 (бот) до 1,0 (человек), но Enterprise добавляет коды причин, пороги под каждое действие, управление через проекты Google Cloud и Account Defender. В запросе к CaptchaAI всё это сводится к одному флагу: enterprise=1.

Ниже — как определить версию в разметке, что меняется в вызове API и почему action при Enterprise критичен.


Как отличить Enterprise v3 от Standard за минуту

Смотреть нужно на три места в разметке страницы:

  1. Подключаемый скрипт: api.js?render=KEY — это Standard, enterprise.js?render=KEY — Enterprise.
  2. Вызов в коде: grecaptcha.execute() против grecaptcha.enterprise.execute().
  3. Значение action рядом с вызовом — его нужно забрать точно в том виде, в каком оно записано.

Ключ сайта у v3 берётся из параметра render=, а не из data-sitekey, как у v2, — это самая частая причина ошибки ERROR_WRONG_GOOGLEKEY.

import requests
import re

def detect_v3_version(url):
    html = requests.get(url).text

    if "enterprise.js" in html:
        version = "enterprise"
    elif "recaptcha/api.js" in html and "render=" in html:
        version = "standard"
    else:
        return None

    # Extract sitekey
    key_match = re.search(r'render[=:]\s*["\']?([A-Za-z0-9_-]{40})', html)
    sitekey = key_match.group(1) if key_match else None

    # Extract action
    action_match = re.search(r'action["\']?\s*[:=]\s*["\'](\w+)', html)
    action = action_match.group(1) if action_match else None

    return {"version": version, "sitekey": sitekey, "action": action}

То же на Node.js, если проверка встроена в пайплайн автотестов:

const axios = require("axios");

async function detectV3Version(url) {
  const { data: html } = await axios.get(url);

  const version = html.includes("enterprise.js")
    ? "enterprise"
    : html.includes("recaptcha/api.js") && html.includes("render=")
      ? "standard"
      : null;

  const keyMatch = html.match(/render[=:]\s*['"]?([A-Za-z0-9_-]{40})/);
  const actionMatch = html.match(/action['"]?\s*[:=]\s*['"](\w+)/);

  return {
    version,
    sitekey: keyMatch?.[1],
    action: actionMatch?.[1],
  };
}

Решение обеих версий через API CaptchaAI

Метод отправки один — userrecaptcha. Меняется только набор параметров.

Standard v3

import requests
import time

resp = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "version": "v3",
    "googlekey": sitekey,
    "action": "login",
    "pageurl": page_url
})
task_id = resp.text.split("|")[1]

for _ in range(60):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY", "action": "get", "id": task_id
    })
    if result.text.startswith("OK|"):
        token = result.text.split("|")[1]
        break

Enterprise v3

Отличие одно — enterprise: 1. Остальное, включая опрос res.php, не меняется.

import requests
import time

# Only difference: enterprise=1
resp = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "version": "v3",
    "enterprise": 1,
    "googlekey": sitekey,
    "action": "login",
    "pageurl": page_url
})
task_id = resp.text.split("|")[1]

for _ in range(60):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY", "action": "get", "id": task_id
    })
    if result.text.startswith("OK|"):
        token = result.text.split("|")[1]
        break

Версия с автоопределением

Жёстко зашивать версию не стоит: сайт может переключиться на Enterprise между релизами, и интеграция начнёт получать отказы. Проверка на каждый запрос стоит дешевле разбора инцидента.

class V3AutoSolver:
    def __init__(self, api_key):
        self.api_key = api_key

    def solve(self, page_url, action=None):
        import re
        html = requests.get(page_url).text

        is_enterprise = "enterprise.js" in html
        key_match = re.search(r'render[=:]\s*["\']?([A-Za-z0-9_-]{40})', html)
        if not key_match:
            raise Exception("No v3 sitekey found")

        if not action:
            act_match = re.search(r'action["\']?\s*[:=]\s*["\'](\w+)', html)
            action = act_match.group(1) if act_match else "verify"

        params = {
            "key": self.api_key,
            "method": "userrecaptcha",
            "version": "v3",
            "googlekey": key_match.group(1),
            "action": action,
            "pageurl": page_url
        }
        if is_enterprise:
            params["enterprise"] = 1

        resp = requests.get("https://ocr.captchaai.com/in.php", params=params)
        if not resp.text.startswith("OK|"):
            raise Exception(f"Submit failed: {resp.text}")

        task_id = resp.text.split("|")[1]
        for _ in range(60):
            time.sleep(5)
            result = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": self.api_key, "action": "get", "id": task_id
            })
            if result.text.startswith("OK|"):
                return result.text.split("|")[1]
            if result.text != "CAPCHA_NOT_READY":
                raise Exception(f"Solve error: {result.text}")
        raise Exception("Timed out")

Таблица различий: Standard v3 и Enterprise v3

Признак Standard v3 Enterprise v3
Невидимая работа Да Да
Score (0,0–1,0) Да Да
Параметр action Обязателен Обязателен
Коды причин Нет Да
Свои пороги под каждое действие Нет Да (через Cloud Console)
Проверка утечки пароля Нет Да
Account Defender Нет Да
Метки Fraud Prevention Нет Да
Связка с многофакторной аутентификацией Нет Да
Конечная точка проверки siteverify (бесплатно) recaptchaenterprise.googleapis.com
Месячная квота 1 млн оценок бесплатно Оплата за оценку
JS-файл api.js?render=KEY enterprise.js?render=KEY
Параметры CaptchaAI version=v3 version=v3 + enterprise=1

Пороги score: почему action важнее, чем кажется

Standard v3 опирается на одну глобальную модель. Enterprise надстраивает над ней слой настроек владельца сайта.

Аспект оценки Standard Enterprise
Базовая модель Глобальная модель Google Глобальная модель Google + собственные сигналы
Пороги по действиям Один порог на все действия Свой порог на каждое (login = 0,7, checkout = 0,9)
Адаптивное обучение Базовое Учитывает профиль трафика конкретного сайта
Детализация score 0,0–1,0, два знака после запятой Тот же диапазон, больше сигналов
Ложные срабатывания Ручная подстройка порога Разбор по кодам причин

Отсюда практический вывод: если вы шлёте action=verify, а форма ждёт action=checkout, токен формально валиден, но сверяется не с тем порогом. Забирайте action из разметки.


Коды причин Enterprise: что они значат

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

Код Значение Что проверить со своей стороны
AUTOMATION Трафик распознан как автоматический Согласуйте тестовый контур и доступ с владельцем ресурса
UNEXPECTED_ENVIRONMENT Нетипичное окружение браузера Проверьте конфигурацию браузера в headless-режиме
TOO_MUCH_TRAFFIC Большой объём запросов с одного источника Ограничьте частоту запросов до согласованных лимитов
UNEXPECTED_USAGE_PATTERNS Нехарактерная последовательность действий Сверьте сценарий автотеста с реальным пользовательским путём
LOW_CONFIDENCE_SCORE Данных для уверенной оценки не хватило Убедитесь, что скрипт reCAPTCHA успевает отработать до отправки формы
SUSPECTED_CARDING Признаки платёжного фрода К задачам автоматизации обычно не относится
SUSPECTED_CHARGEBACK Признаки возвратных платежей К задачам автоматизации обычно не относится

Примечание. Коды причин — инструмент владельца сайта, а не клиента API. Через CaptchaAI вы получаете токен, а оценивает его бэкенд ресурса.


Сценарий: миграция формы входа в команде из Алматы

Ситуация, знакомая командам в Казахстане, Беларуси и России: на staging-контуре SaaS-продукта ночная регрессия гоняет вход и оформление заказа. Поставщик формы переводит проект на reCAPTCHA v3 Enterprise — и прогоны падают на шаге авторизации.

Разбор занимает полчаса: в разметке появился enterprise.js, а сборка по-прежнему шлёт запрос без enterprise=1. Добавили флаг, вытащили action из вызова grecaptcha.enterprise.execute() — прогон снова зелёный.

Нагрузка тут скромная: две формы, около 40 прогонов за ночь, один-два потока параллельно. Тарификация у CaptchaAI идёт по числу одновременных потоков, а не по количеству решений, поэтому сценарий закрывается тарифом BASIC ($15/мес, 5 потоков) — фиксированная сумма в USD предсказуемее оплаты за каждое решение.


Разбор частых ошибок

Симптом Вероятная причина Что сделать
Сайт отклоняет токен на странице с Enterprise В запросе нет enterprise=1 Проверьте наличие enterprise.js и добавьте флаг
Токен принят, но score низкий Неверный action Возьмите точное значение из вызова grecaptcha.enterprise.execute()
На staging работает, на проде — нет Разные ключи сайта и разные пороги в проектах Сверьте sitekey и согласуйте лимиты прогонов с владельцем ресурса
ERROR_WRONG_GOOGLEKEY Ключ v3 взят из data-sitekey Ищите значение в параметре render= в URL скрипта
CAPCHA_NOT_READY дольше обычного Слишком частый опрос res.php Опрашивайте с интервалом около 5 с, как в примерах выше

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

Нужен ли отдельный метод API для Enterprise v3?

Нет. Метод остаётся userrecaptcha, схема «отправить задачу в in.php → опрашивать res.php» та же. Добавляется только enterprise=1.

Что будет, если отправить неверный action?

Токен вернётся корректным, но сайт сверит его с порогом другого действия и, скорее всего, отклонит. Внешне это похоже на «низкий score», хотя причина в рассогласовании параметров.

Сколько потоков нужно под регрессию с reCAPTCHA v3?

Считайте по числу задач, выполняемых одновременно, а не по их количеству за сутки. Пяти потоков тарифа BASIC ($15/мес) хватает ночной регрессии небольшой команды; параллельные прогоны нескольких стендов — это уже STANDARD ($30/мес, 15 потоков) и выше.

Может ли сайт переключиться со Standard на Enterprise?

Да, и это происходит регулярно: Google продвигает Enterprise ради расширенной аналитики. Поэтому версию стоит определять на каждый запрос, а не фиксировать в конфиге.

Что делать, если сайт заменит reCAPTCHA на hCaptcha?

Через CaptchaAI такую страницу закрыть не получится: hCaptcha и FunCaptcha не поддерживаются, GeeTest v4 — только в планах. Поддерживаются reCAPTCHA v2 и v3 (включая Enterprise), Cloudflare Turnstile и Challenge, GeeTest v3, image/OCR, grid-image и BLS CAPTCHA; CaptchaFox, Friendly Captcha и Lemin — в статусе beta.


Связанные материалы

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