Скоуп руководства: ниже описана диагностика собственной или явно авторизованной QA-, staging- и production-среды — как убедиться, что ваша CAPTCHA-интеграция ведёт себя одинаково на всех окружениях. Ни один пример не предназначен для сторонних сайтов и несанкционированных сценариев.
Если reCAPTCHA или Turnstile ведёт себя по-разному на staging и в проде, быстрее всего разобраться не через полноценный e2e-тест, а через Chrome DevTools Protocol (CDP): открываете сеть на уровне протокола и видите, какой sitekey реально ушёл в запросе, что вернул CaptchaAI и как отреагировал ваш собственный backend.
CDP полезнее полноценного браузерного теста, когда:
- проблема воспроизводится только на одном окружении, а причина неочевидна;
- нужно быстро понять, чей это баг — фронтенда, backend-валидации или самого solver'а;
- гонять целый Selenium/Playwright-сценарий ради одной проверки sitekey избыточно.
CDP — это протокол, через который сам Chrome общается со своими инструментами разработчика: DevTools, Puppeteer и Playwright используют один и тот же WebSocket-канал. Для QA это значит, что можно подписаться на сетевые события напрямую, без обёртки WebDriver, и увидеть ровно те запросы, которые формирует виджет CAPTCHA на вашей форме.
Локальный пример: распределённая QA-команда и общий CI-дашборд
Команда, разнесённая между Москвой и Алматы, гоняет такую диагностику на странице оформления заказа при каждом merge request. Контейнер поднимает Chrome с открытым CDP-портом, скрипт фиксирует sitekey, время решения через CaptchaAI и код ответа backend, а результат уходит в общий дашборд. Так расхождения между окружениями видно сразу — а не после жалобы пользователя из другого часового пояса, когда воспроизвести баг уже сложнее.
Типичные проблемы CDP + CaptchaAI: с чего начать разбор
Прежде чем разбирать шаги по порядку, сверьтесь с быстрой таблицей симптомов — часто она экономит полчаса возни с кодом:
| Симптом | Что проверить |
|---|---|
| Токен валиден, backend не принимает | Сверьте secret и домен верификации |
| sitekey не находится | Проверьте, действительно ли виджет рендерится на staging |
| CDP не подключается | Закройте старые процессы Chrome — порт может быть занят |
| Задача висит в pending | Проверьте баланс и число доступных потоков в аккаунте CaptchaAI |
| Виджет виден, но sitekey не находится обычным querySelector | Ищите разметку CAPTCHA внутри Shadow DOM |
Если ни один из симптомов не подошёл — переходите к диагностике по шагам ниже.
Подключение к Chrome через CDP на staging-странице
Поднимите Chrome с открытым CDP-портом на своей staging-странице — порт 9222 подключается любым клиентом: websockets, pychrome, встроенный API Puppeteer или Playwright.
chrome --remote-debugging-port=9222 \
--user-data-dir=./qa-profile \
https://staging.example.com/captcha-demo
Здесь важно ограничить область диагностики: слушайте только трафик собственной страницы и запросы к вашему backend-эндпоинту верификации — сторонний трафик в эту диагностику не входит.
Как найти sitekey reCAPTCHA или Turnstile на тестовой странице
На staging-версии формы sitekey почти всегда лежит прямо в DOM как атрибут — быстрее всего вытащить его обычным запросом и регулярным выражением, не поднимая браузер целиком:
import re, requests
html = requests.get('https://staging.example.com/captcha-demo').text
sitekey = re.search(r'data-sitekey="([^"]+)"', html).group(1)
print('sitekey:', sitekey)
Сохраните значение sitekey в конфигурации тестов отдельно от production. Расхождение между sitekey на staging и в проде — одна из самых частых причин, почему CAPTCHA «работает у разработчика», но падает в CI.
Проверка sitekey через API CaptchaAI из QA-скрипта
Дальше тот же sitekey и pageurl передаются в CaptchaAI напрямую — без браузера, только запросом к API. Это позволяет отделить проблему на уровне solver'а от проблемы на уровне самой формы:
import os, requests, time
API_KEY = os.environ['CAPTCHAAI_KEY']
PAGE = 'https://staging.example.com/captcha-demo'
def solve(sitekey: str) -> str:
r = requests.post('https://ocr.captchaai.com/in.php', data={
'key': API_KEY, 'method': 'userrecaptcha',
'googlekey': sitekey, 'pageurl': PAGE, 'json': 1,
}).json()
tid = r['request']
for _ in range(40):
time.sleep(3)
res = requests.get('https://ocr.captchaai.com/res.php', params={
'key': API_KEY, 'action': 'get', 'id': tid, 'json': 1,
}).json()
if res['status'] == 1:
return res['request']
raise TimeoutError(tid)
Функция опрашивает res.php каждые 3 секунды и возвращает готовый токен, как только status становится 1. Если задача висит дольше пары минут — почти всегда дело не в CaptchaAI, а в том, что sitekey или pageurl не совпадают с реальной страницей. Учтите также: пока скрипт ждёт ответа от res.php, он занимает один поток CaptchaAI. Если диагностика гоняется в CI на каждый pull request, закладывайте план с запасом по потокам — например, ADVANCE ($90/мес, 50 потоков), а не самый маленький тариф, иначе параллельные прогоны будут вставать в очередь друг за другом.
Передайте полученный токен на свой QA-backend и убедитесь, что серверная проверка действительно подтверждает успех, а не просто принимает любое непустое значение. Если backend отвечает не 200 — почти всегда виноват несовпадающий secret, домен или pageurl верификации, а не сам solver.
Структурированные логи и метрики P90/P99
Чтобы сравнивать поведение CAPTCHA между релизами, а не полагаться на ощущения, каждую попытку стоит логировать в едином формате:
import json, time, logging
log = logging.getLogger('captcha-qa')
def record(event: str, **fields) -> None:
payload = {'ts': time.time(), 'event': event, **fields}
log.info(json.dumps(payload, ensure_ascii=False))
Минимальный набор полей: slug, captcha_type, task_id, wait_seconds, verify_status, env. Этого достаточно для дашборда медианы, P90 и P99 по типу CAPTCHA и по окружению.
Не сохраняйте в логах реальные данные тестовых пользователей: по духу 152-ФЗ «О персональных данных» (и аналогично для GDPR, если в команде есть коллеги за пределами РФ) в диагностические логи должны попадать только синтетические тестовые значения.
Перед тем как доверять диагностике целиком, пройдитесь по короткому чек-листу:
- Запросы уходят только на собственные или явно авторизованные endpoints.
- Тестовые аккаунты, заказы и платежи помечены как фиктивные.
- Токен CAPTCHA проверяется на вашем backend, а не принимается на веру на клиенте.
- В логах есть
task_id, тип CAPTCHA, время ожидания и итоговый статус. - Скрипт возвращает корректный exit code, чтобы CI мог принять решение автоматически.
FAQ
Можно ли использовать этот подход на сторонних сайтах?
Нет. Описанные сценарии применимы только к собственным или явно авторизованным средам. Для чужих ресурсов сначала запрашивайте письменное разрешение владельца.
Что делать, если CaptchaAI вернул ошибку при отправке задачи?
Логируйте task_id, тип CAPTCHA и текст ошибки, повторяйте запрос с экспоненциальной задержкой и следите за долей ошибок на дашборде. Устойчивый рост ошибок — повод перепроверить sitekey и саму страницу, а не считать это сбоем solver'а.
Как сравнивать результаты решения CAPTCHA между релизами?
Храните логи в одном формате и стройте отчёт по медиане, P90 и P99 на сопоставимом наборе сценариев. Сравнивать имеет смысл только выборки из одной и той же собственной среды, а не staging с продом вперемешку.
Можно ли подключить Playwright или Puppeteer к тому же CDP-сеансу, что и диагностический скрипт?
Да — оба инструмента работают поверх CDP и умеют переиспользовать уже открытую сессию через её WebSocket-адрес. Это удобно, когда диагностика нужна как дополнительный слой поверх уже существующих браузерных тестов, а не вместо них.
Почему CDP не видит sitekey, хотя виджет CAPTCHA точно отображается на странице?
Скорее всего разметка спрятана внутри Shadow DOM, а обычный document.querySelector туда не заглядывает. Используйте DOM.describeNode с обходом shadow-root'ов или инструменты, которые явно поддерживают pierce-режим для Shadow DOM.
Для дальнейшего чтения см. быстрый старт CaptchaAI, авторизованное QA-тестирование CAPTCHA, тестирование CAPTCHA API на собственных формах и разбор ситуации, когда браузерный тест падает, а API проходит. Пошаговые руководства по конкретным типам: reCAPTCHA v2 через API, Cloudflare Turnstile через API, GeeTest v3 через API.
Хотите такую диагностику в собственном CI? Подключите CaptchaAI и добавьте проверку sitekey и backend в пайплайн уже на этой неделе.