Files
robotex/docs/Usage.md
T
protokeyandClaude Opus 5.5 7b511d5d38 feature: архитектура v2 — api + очередь + worker, удержание окна браузера (#78)
- Сервис api (FastAPI, без Chrome): POST /v2/tasks, GET /v2/tasks/{id} (доступ по cookie
  сессии), DELETE /v2/sessions/current; /v1/solve — прежний контракт поверх очереди.
- Сервис worker (dramatiq + RabbitMQ): слоты браузера, окна сессий между задачами
  (browser_idle_timeout 0–120 мин, простой — TTL ключа в Redis), heartbeat.
- Маршрутизация задач сессии в персональную очередь воркера с открытым окном.
- Redis: задачи, результаты (RESULT_TTL_HOURS), окна, воркеры. Прокси и ключ 2captcha
  в Redis не сохраняются.
- Движок: AsyncStealthySession.run() — действия на текущей странице без навигации.
- Два образа (robotex-api, robotex-worker), compose с rabbitmq и redis,
  make up/down/logs/smoke, релиз собирает все образы.
- Тесты: api + worker в одном процессе (fakeredis), настоящий воркер dramatiq на
  StubBroker, браузерные тесты на новой схеме, smoke для запущенного стенда.
- Документация: README, API (v2), Deployment, Usage.

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

126 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Использование API: практики для клиентов
Как встроить Robotex в свой парсер или бота, чтобы антибот проходился стабильно, а полученные cookies работали.
Справочник по полям и ответам — [API.md](API.md).
## Основной сценарий
Robotex проходит антибот в настоящем браузере и отдаёт то, с чем клиент дальше ходит на сайт **своим HTTP-клиентом**:
1. `POST /v1/solve` с `url`, своим `proxy` и `captcha_type`.
2. Из ответа взять `cookies` (среди них `cf_clearance`) и **`user_agent`**.
3. Дальше ходить на сайт своим HTTP-клиентом:
- с **тем же User-Agent**, что пришёл в ответе;
- через **тот же прокси** (тот же exit-IP);
- с полученными cookies.
4. Когда сайт снова отвечает челленджем (обычно `403` и страница «Just a moment…») или истекает `cf_clearance`
(поле `expires` у cookie) — повторить `/v1/solve` **в той же сессии** (cookie `session_id`).
`cf_clearance` выдаётся конкретному браузеру: Cloudflare связывает его с User-Agent и, как правило, с IP. С другим UA
или через другой прокси cookie не сработает, и сайт снова покажет челлендж.
## Что задаёт сервис, а не клиент
User-Agent, размер окна и экран, отпечаток браузера **не настраиваются запросом** — их определяет сам браузер.
Клиент подстраивается под ответ, а не наоборот.
Почему так: подменить можно только часть признаков. Строка UA меняется, но `navigator.userAgentData`, client hints и
поведение движка остаются от реального Chrome, и Cloudflare видит расхождение. Замер на Chrome 155 / Linux:
| User-Agent в браузере | Cloudflare |
|---|---|
| родной (Linux Chrome 155) | пройден 3 из 3, 7–9 с |
| Linux Chrome 147 | не пройден, 3 из 3 |
| Windows Chrome 155 | не пройден |
Поэтому параметр `user_agent` убран из запроса (передача даёт `422`). Раньше по той же причине был убран параметр
размера окна. Каждому профилю сервис сам генерирует правдоподобный отпечаток (экран и `devicePixelRatio` из
реального распределения) и применяет его средствами Chrome.
UA в ответе может измениться, когда на сервере обновится Chrome. Не храните UA у себя навсегда — берите его из
последнего ответа.
## Сессии
- Ответ ставит cookie `session_id`. Передавайте её в следующих запросах: профиль браузера сохраняется (cookies,
localStorage, отпечаток), и повторно проходить антибот обычно не нужно — запрос заметно быстрее.
- Одна сессия — один «человек»: держите для неё **один и тот же прокси**. Смена exit-IP внутри сессии выглядит
подозрительно и обнуляет `cf_clearance`.
- Задачи одной сессии выполняются по очереди: вторая ждёт, пока закончится первая.
- Для параллельной работы заводите несколько сессий, каждую со своим прокси.
## Синхронно или через задачи
- `/v1/solve` — проще: один запрос, один ответ. Держите соединение открытым до 3–4 минут (см. «Таймауты»).
- `/v2/tasks` — запрос возвращается сразу, результат забираете по ссылке `GET /v2/tasks/{id}` с той же cookie
`session_id`. Подходит, когда соединение нельзя держать долго, и для многошаговых сценариев.
Многошаговый сценарий (войти, затем несколько раз что-то сделать на сайте) — с удержанием окна:
1. `POST /v2/tasks` с `url` и `browser_idle_timeout`: окно останется открытым на это число минут простоя.
2. Следующие задачи с той же cookie `session_id` и тем же `proxy` выполняются в открытом окне: без запуска Chrome
и повторного антибота. Без `url` — на текущей странице.
3. В конце — `DELETE /v2/sessions/current` или задача с `browser_idle_timeout: 0`: окно закроется и освободит слот.
Открытое окно занимает слот браузера, поэтому ставьте простой не больше, чем пауза между вашими шагами.
## Cookies
- Переданные в запросе `cookies` **заменяют** cookies профиля целиком. Не передали — профиль сохраняет свои.
- Для постоянных cookies указывайте `expires` (unix-время). Cookie без `expires` — сессионная и пропадёт, как
только закроется окно браузера (после задачи без `browser_idle_timeout`).
- Обычно передавать cookies не нужно: профиль сам хранит то, что выдал сайт. Передавайте, только если сайт ведёт
себя по-разному в зависимости от cookies (например, авторизация, полученная вне Robotex).
## Ошибки и повторы
| Ответ | Что делать |
|---|---|
| `503`, `code: no_slots` | `/v1/solve`: все браузеры заняты — повторить через `Retry-After` секунд. Задачи v2 в этом случае ждут в очереди |
| `challenge_failed` | антибот не пройден за отведённое время: повторить в той же сессии; при повторных неудачах — сменить прокси (и сессию) |
| `action_failed` | упало действие: смотрите `error` и `actions[].result`; для отладки повторите с `"screenshot": true` |
| `request_failed` | навигация не удалась: обычно прокси недоступен или сайт не отвечает |
| `422` | ошибка в запросе: описание в `detail` |
Успех — строго `status == "ok"`.
## Таймауты
Прохождение антибота может занять до 2 минут, плюс навигация (`timeout`) и действия. Таймаут вашего HTTP-клиента
к Robotex ставьте не меньше `timeout` + 120 с + сумма таймаутов действий. Так же настройте reverse proxy перед сервисом.
## Пример (Python, httpx)
```python
import httpx
ROBOTEX = "https://app.robotex.sokolab.xyz"
PROXY = "http://user:pass@host:port"
robotex = httpx.Client(base_url=ROBOTEX, timeout=300)
def solve(url: str) -> dict:
resp = robotex.post("/v1/solve", json={
"url": url,
"proxy": PROXY,
"captcha_type": "cloudflare",
}) # session_id сохраняется в cookies клиента robotex и уходит в следующих запросах
data = resp.json()
if data.get("status") != "ok":
raise RuntimeError(f"{data.get('code')}: {data.get('error')}")
return data
solution = solve("https://freelancehunt.com/projects")
site = httpx.Client(
proxy=PROXY, # тот же прокси
headers={"User-Agent": solution["user_agent"]}, # тот же UA
cookies={c["name"]: c["value"] for c in solution["cookies"]},
)
page = site.get("https://freelancehunt.com/projects")
if page.status_code == 403:
solution = solve("https://freelancehunt.com/projects") # та же сессия, обновить cf_clearance
```