Коробка — это Parreq, работающий у вас. Один бинарник поднимает на вашей машине свой Chrome и отвечает тем же API, что и api.parreq.com. Страницы собираются и разбираются на месте; наружу уходит только снятие капчи, потому что ключ решателя обязан оставаться у нас. Раздел с загрузками появляется в кабинете после того, как мы откроем вам право на коробку. Напишите нам, если его там нет.
Меняется ровно один адрес: вместо https://api.parreq.com вы указываете http://127.0.0.1:8123. Тела запросов, ответы, коды ошибок и заголовки те же, ваш код правки не требует. Библиотекам нужна версия 1.5 или новее — в ней появились разбор по селекторам и живые вкладки.

Зачем

Данные остаются у вас

Разметка страниц, запросы и извлечённые поля не покидают вашу машину. Разбор идёт на месте — и выдачи Google, и полей по вашим селекторам.

Дешевле

Половина облачной цены, а базовый Fetch и работа с живыми вкладками бесплатны: считает ваше железо.

Без сроков жизни

Вкладка живёт, пока вы её не закроете. Ни простоя в 60 секунд, ни потолка в две минуты, как в облаке.

Наши адреса выхода

Прокси и снятие капчи остаются нашими: сайты видят наши адреса, а не ваш сервер.

Установка

1

Скачайте

В кабинете, раздел «Коробка». Есть сборки для Linux (x86-64 и ARM), macOS (Apple silicon и Intel) и Windows.
2

Задайте ключ

Ключ тот же, что и для облака. Записывается в файл с правами 0600 рядом с настройками.
3

Запустите

Коробка подключится к нашим серверам и заведёт заявку. До подтверждения она на связи, но запросов не обслуживает.
4

Дождитесь подтверждения

Мы видим заявку сразу: какой ключ, какая почта, какая машина. Подтверждение доезжает в уже открытый канал — перезапускать ничего не нужно.
5

Переключите свой код

Библиотеки версии 1.5 и старше умеют и разбор по селекторам, и живые вкладки: client.fetch(url, fields={…}), client.browser_open(url); с 1.6 — анкету целиком: client.browser_form(tab, {...}, submit=…). Прежние версии работают с поиском, Fetch и обходом, но про коробку не знают — обновитесь.

Чем коробка выходит в сеть

Три способа. Какие из них вам доступны, решаем мы; какой взять из доступных — решаете вы. Настраивается в config.json коробки:
Или переменными: PARREQ_BOX_EGRESS=own, PARREQ_BOX_PROXY=.... После правки перезапустите коробку. Запись прокси принимается в тех же видах, что и у нас: host:port, host:port:логин:пароль, логин:пароль@host:port, со схемой http://, https://, socks5:// впереди или без неё.
Режим parreq доступен всегда, own и direct открываем по просьбе. Если выбрать неоткрытый режим, коробка не станет молчать и не подменит адрес втихую: она скажет об этом в журнале и продолжит работать через наши адреса. Так же она поступит, если запись своего прокси не разобралась.
Что сейчас используется, видно в состоянии:
allowed — что открыто вам, via — что работает прямо сейчас. Свой адрес показывается, наш — нет: он наш ресурс.
Со своим адресом капча становится вашей заботой в том смысле, что решаем её мы, но привязываем токен к тому адресу, с которого пришёл запрос. Свежий адрес без истории Google встречает заслоном чаще нашего — это не поломка коробки, а свойство адреса.

Чем коробка представляется сайту

Тем же, чем и облако: настоящим Chrome под Windows, с той же версией, что у двоичного файла на вашей машине, с правдоподобной видеокартой, числом ядер и часовым поясом страны выхода. Отпечаток правится до первого скрипта страницы — позже поздно, страница исходные значения уже прочитала.
Так было не всегда. Коробка представлялась HeadlessChrome на X11; Linux x86_64, без WebGL и с navigator.webdriver, и сайты под защитой отвечали ей «Forbidden» — в том числе через наши адреса выхода, по которым облако ту же страницу забирало с первого раза. Если у вас коробка старее 1.3.4 и защищённый сайт её не пускает, дело в этом; обновитесь.
Устройство, страну и язык задаёт запрос — теми же полями, что и в облаке:
Меняется не одна строка заголовка, а вся обстановка: размер окна, плотность пикселей, касания, Client Hints, часовой пояс и языки. Витрины отдают телефону другую вёрстку, и параметр, меняющий только User-Agent, вводил бы в заблуждение.
Окно по-прежнему безоконное: на сервере окна нет, а на рабочей станции мелькающее окно браузера — это чужая машина, на которой что-то само двигается. Два признака, которыми headless выдаёт себя, закрыты иначе: строка — подменой, отсутствие WebGL — программным рендерером и подменой вендора.

Браузер

Коробке нужен Chrome или Chromium. Она сама разберётся, откуда его взять:
  1. Уже установленный в системе — берётся первым. Он собран под вашу систему и обновляется её же средствами.
  2. Если системного нет, коробка скачивает Chrome for Testing себе в каталог.
На Alpine и других musl-системах второй путь не работает: Chrome for Testing собран под glibc и на musl не запускается вовсе. Коробка это видит и не тратит минуты на бесполезную загрузку, а просит поставить браузер системой:
После этого она возьмёт /usr/bin/chromium-browser и запустится. Проверено: браузер поднимается, страницы собираются, разбор по селекторам работает.

Как запускать службой

Одна команда на любой системе: коробка сама смотрит, чем на машине поднимают службы, и ставит себя в нужном виде.
Во всех вариантах настроен перезапуск после выхода, и это обязательно: обновление коробка ставит сама и выходит нулём, ожидая, что её поднимут. Служба без перезапуска превратила бы обновление в остановку.
Если система не опознана, коробка честно скажет об этом и не станет делать вид, что установилась. Тогда запускайте parreq-box run своим способом — но позаботьтесь, чтобы её кто-то поднимал после выхода. Снять службу: sudo ./parreq-box uninstall. Настройки и профиль браузера останутся на месте. Проверить, что коробка видит систему правильно:
На минимальных образах (Alpine, debian:slim) может не оказаться корневых сертификатов, и коробка не достучится до нас. Лечится одной командой: apk add ca-certificates либо apt install ca-certificates. Коробка скажет об этом прямо, а не «ошибкой TLS».

Что доступно

Почему база бесплатна: вычисления идут на вашей машине, а профиль, которым браузер ходит, разогрет нашей капчей — она уже оплачена отдельной строкой. Платите за то, что несёт нашу работу: разбор выдачи, снятие защиты и надстройки вроде скриншота.

Разбор страницы по селекторам

В коробке разбор ручной: поля задаёте вы, извлекает их браузер на вашей машине. Языковой модели здесь нет — иначе текст страницы уезжал бы к нам, а весь смысл коробки в обратном.
Один селектор — одно значение; несколько совпадений приходят списком. У meta берётся content, у картинок src, у полей ввода их значение.
Чего коробка не сделала — она называет. Попросите include=iframe или extract — в ответе будет unsupported: [...] и объяснение в note, а не ответ, который выглядит полным и таковым не является. До 1.3.4 js, css и network тоже выбрасывались молча; теперь они собираются на месте — те же поля и те же пределы, что в облаке.

Живые вкладки

Вкладки нумеруются с единицы, и номер — это всё, что нужно помнить.

Анкета целиком

Оформление заказа — это шесть-семь полей и кнопка. Отдельными вызовами fill это семь обращений; ручка form делает то же за одно, по порядку списка, и сразу нажимает кнопку отправки:
Что писать в value, решает вид поля — он приходит в списке элементов полем kind: В ответе filled — что просили и что вправду легло в поле: маску телефона и отказ витрины видно именно там. Промах по одному полю не отменяет остальных.
Переключатели на витринах спрятаны: сам input нулевого размера, а кружок нарисован стилями. В список они всё равно попадают — по видимой подписи, — и у выбранного стоит checked. Нажимать уже выбранный не надо: нажатие его снимет. Радиокнопку снять нельзя вовсе, её отменяет выбор соседней в той же группе (group в списке).
Вкладок по умолчанию три, и закрываются они только по вашей команде. Когда свободных нет, open отвечает 429 tabs_busy и говорит, какие заняты, — а не закрывает чужую работу молча. Нужно больше вкладок — попросите нас, потолок меняется на лету, без переустановки.

Несколько браузеров

По умолчанию коробка держит один Chrome и работает вкладками в нём: один профиль, одни куки, одна снятая капча на всех. Когда задач много или нужна изоляция, задайте потолок браузеров:
Или PARREQ_BOX_BROWSERS=4. Браузеры поднимаются лениво — по мере того, как задачи вправду приходят, — и не сверх того, что позволяет память: коробка измеряет, сколько занимает живой браузер (PSS всего дерева процессов, не константа), и не поднимает новый, если свободной памяти машины останется меньше гигабайта. Простоявший двадцать минут браузер гасится; первый (p0) живёт всегда — в нём живые вкладки и прогретый профиль. Что происходит, видно в состоянии:
Профили лежат рядом с настройками: profile у первого браузера (так было и раньше — прогретые куки не теряются при обновлении) и profiles/p1, profiles/p2… у остальных.

Коробка как воркер облака

Для наших собственных коробок — тех, что стоят рядом со службой, — есть режим воркера: облако раздаёт им задачи поиска и Fetch тем же протоколом, что домашним агентам, а отвечает клиенту само. Включается настройкой worker в панели, на лету; ёмкость воркера — число браузеров коробки (browsers), и координатор назначает профиль по имени: p0, p1… — тот, что уже прогрет под нужный движок. У заказчиков этот режим выключен и включать его мы не будем: коробка куплена для его задач, а не для наших. Без настройки коробка на задачу отвечает отказом словами, а не молчанием — координатор тут же уходит на резерв.

Если агент живёт в контейнере

Локальный API коробки слушает только петлю: она обслуживает свою машину, и ключ на петле не спрашивается — кто до неё добрался, тот и так здесь. Но у контейнера своя петля, и до вашей он не дотянется. Тогда нужно назвать адреса, которым можно, и слушать не только петлю. В config.json рядом с настройками коробки:
Или переменными окружения: PARREQ_BOX_LISTEN=0.0.0.0:8123 и PARREQ_BOX_ALLOW=172.17.0.0/16. После правки перезапустите коробку. 172.17.0.0/16 — обычная сеть Docker. Свою можно посмотреть так:
Изнутри контейнера коробка будет доступна по адресу шлюза, обычно 172.17.0.1. В настройках MCP тогда указывается он:
С любого адреса, кроме петли, коробка спрашивает ключ — тот же, с которым работает она сама. Иначе сосед по сети контейнеров тратил бы ваши кредиты: локальный API денег не проверяет, он их списывает. Мост MCP передаёт ключ сам, ничего дополнительно делать не надо.
Открывать коробку шире, чем нужно, не стоит. Список allow — это именно список: ["172.17.0.0/16", "10.8.0.5"] понимает и сети, и отдельные адреса.

Состояние

Прогрев идёт сам, раз в полминуты: профиль должен быть готов раньше вашего первого запроса, иначе он платит холодным стартом. Если прогрев упирается в капчу, мы её снимаем, и она списывается как капча.

Нет связи — нет работы

Коробка держит постоянный канал с нашими серверами. На них лицензия, адреса выхода и решатель капчи, поэтому без связи она не может выполнить запрос — и честно об этом говорит, а не отдаёт неполный результат. Все они приходят с кодом 503 (кроме tabs_busy — 429) и объяснением словами.

Безопасность

Канал шифруется поверх TLS отдельным слоем: эфемерные ключи на каждое соединение, ChaCha20-Poly1305, счётчик против повторов. Внутри едут учётные данные прокси, готовый скрипт снятия капчи и настройки лицензии — то, что незачем видеть даже на вашем собственном сетевом оборудовании. Ключ решателя капчи и список прокси в коробку не попадают никогда. Локальный API слушает только петлю: он обслуживает вашу машину, а не сеть.