Files
robotex/docs/API.md
T
protokeyandClaude Opus 5.5 fe509c25c3 feature!: параметр user_agent убран, UA всегда родной; docs/Usage.md
- user_agent в запросе → 422 с подсказкой брать UA из ответа: UA, отличный от реального
  Chrome, расходится с userAgentData и движком, Cloudflare такой браузер не пропускает
  (замер: родной 3/3, Chrome 147 и Windows — 0) (#87)
- профиль хранит только отпечаток (экран, DPR), UA не подменяется (#89)
- docs/Usage.md: практики для клиентов API — тот же UA и прокси, что у браузера, сессии,
  cookies, ошибки и повторы, таймауты, пример на httpx
- README, docs/API.md, docs/Introduction.md; тесты под новый контракт

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 18:19:08 +04:00

11 KiB
Raw Blame History

API

Как встраивать API в свой клиент (UA, прокси, сессии, повторы) — Usage.md.

Основной эндпоинт: POST /v1/solve. Открывает страницу в Chrome (через прокси клиента, если он задан), при необходимости проходит антибот (Cloudflare Turnstile, reCAPTCHA), выполняет список действий и возвращает cookies, результаты действий и, по запросу, HTML и скриншот.

GET /health (и GET /) — {"status": "ok", "browser_slots": N, "free_slots": M}.

X-API-Key пока не проверяется (#4).

Запрос

POST /v1/solve
Content-Type: application/json
X-API-Key: <key>
Cookie: session_id=<id>        # необязательно, см. «Сессии»

{
	"url": "https://freelancehunt.com/projects",
	"proxy": "http://user:pass@host:port",
	"captcha_type": "cloudflare",
	"actions": [
		{"type": "wait_for", "selector": "a[href*=\"/project/\"]", "timeout": 60}
	],
	"html": true,
	"timeout": 120
}
Поле Тип По умолчанию Описание
url string — обязательно. Страница, которую открываем
proxy string null scheme://[user:pass@]host:port, схема http, https или socks5 (Chrome не поддерживает socks5 с логином/паролем). По exit-IP прокси выставляются locale и timezone браузера; без прокси — настройки браузера по умолчанию
actions array — обязательно, может быть пустым. Действия, см. ниже
captcha_type string null провайдер антибота: cloudflare или recaptcha. Без него шаг антибота пропускается — для сайтов за Cloudflare обязательно
captcha string null ключ сервиса распознавания (2captcha), если антибот не проходится без решения капчи
captcha_detect_locator string null локатор, по которому определяется, что на странице антибот
captcha_success_locator string null локатор, по которому определяется, что антибот пройден
html bool false вернуть HTML страницы после выполнения действий
screenshot bool false вернуть скриншот видимой области (PNG, base64) после действий — в том числе при ошибке действия или антибота
timeout int, с 60 таймаут навигации
cookies array null cookies для установки до навигации, формат Playwright: {name, value, domain, path, expires, httpOnly, secure, sameSite} или {name, value, url}. Заменяют cookies профиля: перед установкой все cookies профиля удаляются ([] — просто очистить). Без поля cookies профиля сохраняются
disable_resources bool false не грузить картинки, шрифты, медиа
blocked_domains array null домены, запросы к которым блокируются
retries int 1 попыток навигации
retry_delay float, с 1.0 пауза между попытками
wait int, мс 0 пауза после загрузки страницы
google_search bool false выставить Referer как переход из поиска Google

Действия

Выполняются по порядку после прохождения антибота. Если антибот не пройден, действия не выполняются (code: challenge_failed). На первой ошибке действия выполнение останавливается.

Обязательные поля проверяются до запуска браузера: неизвестный type, нет selector/value, captcha без ключа в запросе, неверный proxy — ответ 422 с описанием в detail (стандартный формат FastAPI).

type Поля Что делает
wait_for selector, timeout (1–7200 с, по умолчанию 30) ждёт появления элемента; при таймауте — ошибка действия
click selector клик по элементу
submit selector клик и ожидание навигации
fill selector, value вставка значения в поле
mouse_move selector наведение курсора на элемент; нет элемента — ошибка selector not found
delay value (секунды строкой, 0–600) пауза
inner_html selector возвращает HTML элемента в result; нет элемента — ошибка selector not found
captcha selector, value (тип: cloudflare, recaptcha, hcaptcha) решить капчу внутри страницы через 2captcha, нужен captcha в запросе
pass_challenge selector (локатор успеха, необязательно) повторно пройти антибот, например после перехода на другую страницу; если не пройден — ошибка действия

Ответ

Формат один для всех случаев: status — "ok" или "err", при ошибке — code и error. Поля без значения не возвращаются.

Успех (антибот пройден, действия выполнены), HTTP 200:

{
	"status": "ok",
	"user_agent": "Mozilla/5.0 (X11; Linux x86_64) ... Chrome/155.0.0.0 Safari/537.36",
	"cookies": [{"name": "cf_clearance", "value": "...", "domain": ".freelancehunt.com", "...": "..."}],
	"actions": [
		{"type": "wait_for", "ok": true, "duration_ms": 14}
	],
	"html": "<head>...</head><body>...</body>",
	"duration_ms": 6405
}
Поле Описание
status "ok" — антибот пройден и все действия выполнены, иначе "err"
code при "err": причина, см. таблицу ниже
error при "err": текст ошибки; для упавшего действия — <type>: <текст>
user_agent родной UA браузера, с которым проходили антибот. Используйте его в своём HTTP-клиенте вместе с cf_clearance (см. Usage.md)
cookies все cookies контекста
actions по элементу на выполненное действие: type, ok, result (результат или текст ошибки), duration_ms
html только при "html": true
screenshot только при "screenshot": true: PNG в base64
duration_ms общее время обработки запроса
code HTTP Когда Что ещё есть в ответе
no_slots 503 + Retry-After все браузеры заняты (BROWSER_SLOTS), запрос не ставится в очередь —
request_failed 200 ошибка до действий: навигация, прокси, неизвестный captcha_type actions: []
challenge_failed 200 антибот не пройден за отведённое время, действия не выполнялись cookies, html, screenshot
action_failed 200 упало действие, выполнение остановлено на нём cookies, html, screenshot, actions до упавшего включительно

Примеры:

{"status": "err", "code": "action_failed", "error": "inner_html: selector not found: #missing",
 "actions": [{"type": "inner_html", "ok": false, "result": "selector not found: #missing", "duration_ms": 26}], "...": "..."}
{"status": "err", "code": "challenge_failed", "error": "cloudflare not passed: timeout (stage: checkbox)", "actions": [], "...": "..."}
{"status": "err", "code": "no_slots", "error": "No slots available"}

Сессии

Ответ ставит cookie session_id (UUID). Если передать её в следующем запросе, браузер откроется с тем же профилем (extra/user_data_dir/<session_id>): cookies, localStorage и отпечаток сохраняются, повторно проходить Cloudflare обычно не нужно. Без cookie или с некорректным значением (не UUID) запрос получает новый профиль.

Отпечаток профиля генерируется при первом запросе сессии и дальше не меняется (robotex_session.json в каталоге профиля): размер экрана и devicePixelRatio десктопного Chrome на Linux из реального распределения (browserforge). Применяется нативной эмуляцией Chrome, без JS-подмены (она ломала прохождение Cloudflare); DPR влияет и на хеш canvas. Ограничение: canvas, WebGL и hardwareConcurrency у всех профилей одинаковые, поэтому примерно половина профилей совпадает по отпечатку.

User-Agent и размер окна запросом не задаются — это родные значения браузера (почему — Usage.md). Поле user_agent в запросе даёт 422.

Один профиль нельзя использовать в двух запросах одновременно: Chrome заблокирует каталог профиля.

Производительность

Каждый запрос запускает отдельный Chrome: около 0,6 ГБ памяти и до 3–4 ядер на пике при прохождении Cloudflare. Замеры и рекомендации по лимитам — в Deployment.md.