- badge and limits: requests need an X-API-Key, the demo instance test key is in the Redmine wiki; the example request sends the header - drop the "early MVP" and "Turnstile is unstable" caveats Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
131 lines
9.5 KiB
Markdown
131 lines
9.5 KiB
Markdown
---
|
|
title: "Robotex"
|
|
tagline: "Браузер для ваших ботов по API"
|
|
description: "Robotex проходит анти-бот защиту, выполняет сценарий на странице и отдает боту куки. Дальше бот работает обычными HTTP запросами."
|
|
domain: "https://robotex.sokolab.xyz/"
|
|
badge: "Бесплатно · демо-ключ в вики"
|
|
post: "/blog/robotex-browser-automation-api"
|
|
postLabel: "Как устроен Robotex"
|
|
build:
|
|
list: never
|
|
sitemap:
|
|
disable: true
|
|
|
|
nav:
|
|
- { label: "Возможности", href: "#features" }
|
|
- { label: "Как работает", href: "#how" }
|
|
- { label: "Архитектура", href: "#engine" }
|
|
- { label: "Сообщество", href: "#community" }
|
|
|
|
cta:
|
|
- { label: "Открыть API", href: "https://app.robotex.sokolab.xyz/docs", primary: true }
|
|
- { label: "Как это работает", href: "#how" }
|
|
|
|
problem:
|
|
title: "Зачем это нужно"
|
|
lead: "Каждый бот под сайт рано или поздно упирается в одну из трех проблем:"
|
|
items:
|
|
- "капча"
|
|
- "анти-бот защита"
|
|
- "сложный JS, который нужно отрендерить, чтобы отправить форму"
|
|
text: "Паук на сырых HTTP запросах тут бессилен, нужен настоящий браузер. Но браузер тяжелый, его нужно прятать от детекта и держать рядом с ботом. Robotex берет эту работу на себя: браузер включается только там, где без него никак."
|
|
|
|
features:
|
|
title: "Возможности"
|
|
items:
|
|
- title: "Сценарии"
|
|
text: "Не просто открыть страницу. Заполнить форму, кликнуть, навести мышь, дождаться элемента, забрать кусок HTML или текст."
|
|
- title: "Анти-бот страницы"
|
|
text: "Сам находит проверку Cloudflare до и во время сценария и проходит ее, Turnstile в том числе. Если она переросла в капчу с картинками, отправляет в сервис распознавания."
|
|
- title: "Капча"
|
|
text: "Шаг `captcha` в сценарии решает hCaptcha и другие капчи через 2captcha до отправки формы."
|
|
- title: "Профили"
|
|
text: "Куки, local storage и отпечаток браузера живут в одном профиле. Локаль и часовой пояс подбираются под гео прокси. Для сайта это все тот же пользователь."
|
|
- title: "Окно между задачами"
|
|
text: "Браузер может подождать следующего шага до двух часов. Следующая задача выполнится в том же окне, без перезапуска Chrome и повторной проверки, прямо на открытой странице."
|
|
- title: "Любой язык"
|
|
text: "Это сервис, а не библиотека. Боту нужен только HTTP клиент, на чем он написан, неважно."
|
|
|
|
how:
|
|
title: "Как это работает"
|
|
steps:
|
|
- "Бот с API-ключом отправляет в `POST /v2/tasks` адрес, сценарий действий и свой прокси. Задача встает в очередь, в ответ приходит ссылка на результат и кука `session_id`."
|
|
- "Свободный воркер открывает страницу в Chrome, проходит проверки и выполняет сценарий. Бот опрашивает ссылку, пока задача не станет `done`."
|
|
- "Бот получает куки и User-Agent и дальше ходит по сайту сам, **с тем же UA и через тот же прокси**."
|
|
- "Понадобится браузер снова, передаст `session_id`. Если просил подержать окно (`browser_idle_timeout`), задача выполнится в нем, можно даже без `url`. Если нет, Chrome откроется с тем же профилем."
|
|
- "Нужен ответ сразу, без опроса: `POST /v1/solve` работает как раньше, синхронно."
|
|
code:
|
|
- caption: "Задача"
|
|
body: |
|
|
POST https://app.robotex.sokolab.xyz/v2/tasks
|
|
X-API-Key: <ключ>
|
|
|
|
{
|
|
"url": "https://example.com/login",
|
|
"actions": [
|
|
{"type": "fill", "selector": "#email", "value": "user@example.com"},
|
|
{"type": "fill", "selector": "#password", "value": "..."},
|
|
{"type": "click", "selector": "#submit"},
|
|
{"type": "wait_for", "selector": ".dashboard", "timeout": 30}
|
|
],
|
|
"proxy": "http://user:pass@host:port",
|
|
"browser_idle_timeout": 10
|
|
}
|
|
|
|
→ 202 {"task_id": "0b9c…", "status": "queued", "url": "/v2/tasks/0b9c…"}
|
|
- caption: "Результат: GET /v2/tasks/0b9c…"
|
|
body: |
|
|
{
|
|
"task_id": "0b9c…",
|
|
"status": "done",
|
|
"result": {
|
|
"status": "ok",
|
|
"user_agent": "Mozilla/5.0 (X11; Linux x86_64) ... Chrome/155.0.0.0 ...",
|
|
"cookies": [
|
|
{"name": "sessionid", "value": "...", "domain": ".example.com"}
|
|
],
|
|
"actions": [
|
|
{"type": "fill", "ok": true},
|
|
{"type": "fill", "ok": true},
|
|
{"type": "click", "ok": true},
|
|
{"type": "wait_for", "ok": true}
|
|
]
|
|
}
|
|
}
|
|
|
|
engine:
|
|
kicker: "Под капотом"
|
|
title: "Архитектура v2"
|
|
lead: "Раньше браузер жил прямо в API, и когда слоты кончались, запрос получал отказ. Теперь API только принимает задачи и отдает результаты, а Chrome работает в отдельных воркерах за очередью."
|
|
items:
|
|
- "**api** на FastAPI без браузера: ставит задачи, отдает статус и результат"
|
|
- "**RabbitMQ**: задачи ждут свободного слота в очереди, а не получают `503`"
|
|
- "**worker** на dramatiq: настоящий Chrome под Patchright и Xvfb, без утечек CDP, несколько окон на воркер"
|
|
- "**Redis**: статусы и результаты задач хранятся сутки, прокси и ключ 2captcha туда не попадают"
|
|
- "Задачи сессии с открытым окном идут в личную очередь того воркера, у которого это окно"
|
|
- "`/v1/solve` работает поверх той же очереди, старые клиенты ничего не меняют"
|
|
callout:
|
|
title: "Браузер больше не одноразовый"
|
|
text: "Окно можно держать открытым от 0 до 120 минут простоя и вести в нем сценарий по шагам: залогиниться, отдать управление боту, вернуться и продолжить на той же странице. Закрыть окно раньше можно через `DELETE /v2/sessions/current`."
|
|
|
|
limits:
|
|
title: "Честно о текущем состоянии"
|
|
items:
|
|
- "**Доступ по API-ключу.** Тестовый ключ для демонстрационного инстанса лежит в [вики проекта](https://redmine.sokolab.xyz/projects/robotex/wiki), передавайте его в заголовке `X-API-Key`."
|
|
- "Открытое окно занимает слот браузера. Держите его не дольше, чем нужно."
|
|
- "Пока все воркеры работают на одном сервере."
|
|
- "**Бесплатно.** Платить нужно только за свои прокси и, если нужна, капчу в 2captcha."
|
|
- "Прокси решает многое: на грязном IP не поможет никакой отпечаток."
|
|
|
|
community:
|
|
title: "Сообщество"
|
|
lead: "Вопросы, идеи и баги принимаются в Redmine. Регистрироваться не обязательно: данные гостевого аккаунта Robotex есть в [приветственной теме](https://redmine.sokolab.xyz/boards/1/topics/1) на форуме."
|
|
links:
|
|
- { title: "Форум", text: "Вопросы, идеи и обсуждение сценариев.", href: "https://redmine.sokolab.xyz/projects/robotex/boards" }
|
|
- { title: "Баги и пожелания", text: "Что-то не работает или не хватает функции.", href: "https://redmine.sokolab.xyz/projects/robotex/issues" }
|
|
- { title: "Telegram", text: "Написать мне напрямую.", href: "https://t.me/xs0k0lx" }
|
|
- { title: "Исходники", text: "Код сервиса в моей Gitea.", href: "https://git.sokolab.xyz/s0k0l/robotex" }
|
|
|
|
footer: "Используйте Robotex только на сайтах, где у вас есть на это право."
|
|
---
|