- docker-compose: cpus/mem_limit через API_CPUS/API_MEM_LIMIT, прокси gost в профиле loadtest - tests/loadtest.py: параллельные запросы к /v1/solve + пики docker stats - docs/API.md: справочник по запросу, действиям, ответу и сессиям - docs/Deployment.md: результаты замеров и правило подбора BROWSER_SLOTS Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7.5 KiB
API
Один эндпоинт: POST /v1/solve. Открывает страницу в Chrome через прокси клиента, при необходимости проходит
антибот (Cloudflare Turnstile, reCAPTCHA), выполняет список действий и возвращает cookies, результаты действий и,
по запросу, HTML.
Запрос
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 | — | обязательно. 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 страницы после выполнения действий |
timeout |
int, с | 60 |
таймаут навигации |
user_agent |
string | null |
свой User-Agent; без него берётся UA установленного Chrome |
cookies |
array | null |
cookies для установки до навигации, формат Playwright: {name, value, domain, path, expires, httpOnly, secure, sameSite} |
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 |
Действия
Выполняются по порядку после прохождения антибота. На первой ошибке выполнение останавливается.
type |
Поля | Что делает |
|---|---|---|
wait_for |
selector, timeout (1–7200 с) |
ждёт появления элемента; при таймауте — ошибка действия |
click |
selector |
клик по элементу |
submit |
selector |
клик и ожидание навигации |
fill |
selector, value |
вставка значения в поле |
mouse_move |
selector |
наведение курсора на элемент |
delay |
value (секунды строкой) |
пауза |
inner_html |
selector |
возвращает HTML элемента в result |
captcha |
selector, value (тип: cloudflare, recaptcha, hcaptcha) |
решить капчу внутри страницы через 2captcha, нужен captcha |
pass_challenge |
selector (локатор успеха, необязательно) |
повторно пройти антибот, например после перехода на другую страницу; если не пройден — ошибка действия |
Ответ
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}
],
"html": "<head>...</head><body>...</body>"
}
| Поле | Описание |
|---|---|
status |
"ok" — все действия выполнены, "err" — одно из действий упало (выполнение на нём остановлено) |
user_agent |
UA браузера, с которым проходили антибот (нужен клиенту вместе с cf_clearance) |
cookies |
все cookies контекста |
actions |
по элементу на выполненное действие: type, ok, result (результат или текст ошибки) |
html |
только при "html": true |
error |
при status: "err": <type>: <текст ошибки> упавшего действия |
Ошибка с упавшим действием:
{
"status": "err",
"actions": [{"type": "wait_for", "ok": false, "result": "Page.wait_for_selector: Timeout 3000ms exceeded. ..."}],
"error": "wait_for: Page.wait_for_selector: Timeout 3000ms exceeded. ..."
}
Ошибка до выполнения действий (навигация, прокси, неизвестный captcha_type):
{"status": false, "error": "unknown captcha_type 'datadome', expected one of: recaptcha, cloudflare"}
Нет свободных браузеров (лимит BROWSER_SLOTS):
{"ok": false, "error": "No slots available"}
Форматы ошибок пока не унифицированы (тех. долг):
statusбывает"ok"/"err"/false, а при занятых слотах поляstatusнет вовсе. Успех — строгоstatus == "ok".
Сессии
Ответ ставит cookie session_id. Если передать её в следующем запросе, браузер откроется с тем же профилем
(extra/user_data_dir/<session_id>): cookies, localStorage и отпечаток сохраняются, повторно проходить Cloudflare
обычно не нужно. Без cookie каждый запрос получает новый профиль.
Один профиль нельзя использовать в двух запросах одновременно: Chrome заблокирует каталог профиля.
Производительность
Каждый запрос запускает отдельный Chrome: около 0,6 ГБ памяти и до 3–4 ядер на пике при прохождении Cloudflare. Замеры и рекомендации по лимитам — в Deployment.md.