Яндекс не даёт партнёрам API заявок. Мы завели серверу отдельный браузер — и забрали 791 ставку по 207 городам без единой ручной выгрузки

У нашего курьерского парка два крупных агрегатора доставки, с которыми нужно сверяться каждый день: сколько платят по городам, сколько новых заявок от соискателей, кто откликнулся на вакансию курьера. С одним каналом, Telegram-ботом, всё просто — там у нас свой API. А вот у личных кабинетов партнёров агрегаторов официального API для таких данных нет вообще. Есть только веб-интерфейс, в который должен зайти живой человек.
У нашего курьерского парка два крупных агрегатора доставки, с которыми нужно сверяться каждый день: сколько платят по городам, сколько новых заявок от соискателей, кто откликнулся на вакансию курьера. С одним каналом, Telegram-ботом, всё просто — там у нас свой API. А вот у личных кабинетов партнёров агрегаторов официального API для таких данных нет вообще. Есть только веб-интерфейс, в который должен зайти живой человек.

До этой недели это значило одно: кто-то из команды открывает кабинет руками, листает таблицу ставок по городам, копирует цифры в файл, повторяет на следующей неделе. Ставки по курьерской доставке меняются регулярно — отстать на пару недель значит две недели предлагать курьерам не ту доставку.

Как увидели задачу

Мы считали ручную выгрузку временным решением с самого начала — вопрос был только в том, как её снять, не нарушая правил площадки и не теряя доступ. Самый быстрый путь — скрипт, который сам логинится паролем и парсит HTML страницы. Мы его не стали делать: пароль в коде — это постоянный риск блокировки по подозрению в автоматизации, а разбор HTML ломается от любой правки вёрстки на стороне агрегатора.

Решение, которое выбрал Роман: завести отдельный браузер, который живёт на сервере постоянно и держит одну сессию входа. Входит в него человек, через собственный VNC-экран, который видно только владельцу. А дальше код внутри страницы, уже залогиненной, обращается не к HTML, а к внутреннему API кабинета — тому же, которым пользуется сам фронтенд агрегатора, когда отрисовывает таблицы на экране у человека. Для площадки это выглядит как обычный пользователь, который открыл свою страницу и подождал, пока она прогрузится.

Как решили

Первый контейнер с браузером встал на прод 21.10 — ровно для одной задачи: держать сессию живой и отдавать запросы изнутри страницы. Второй слой — два модуля синхронизации: один забирает заявки соискателей, второй — таблицу ставок по городам.

Тут и нашлась настоящая развилка. Пока мы разведывали, какие разделы кабинета вообще отдают нужные данные, один из открытых разделов сам — без нашей команды — отправил запрос на изменение избранного с пустым списком. Страница просто выполнила свой обычный фронтенд-код при открытии, и этот код умел не только читать, но и писать. Если бы мы не заметили это в логе запросов, автоматический обход кабинета мог молча стереть реальные пользовательские настройки Романа в его собственном аккаунте.

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

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

Результат

Синхронизация заявок соискателей идёт каждые 30 минут, ставки по городам — по понедельникам в начале недели. На первом полном проходе получили 172 заявки (с телефоном — только у свежих, по старым площадка отдаёт отказ в доступе, это её ограничение, не наше) и 791 ставку по 207 городам, причём названия городов теперь приходят на русском, а не кодами, как раньше в ручных выгрузках. Второй агрегатор, с которым у нас похожая история, подключили к той же инфраструктуре браузера на следующий день — делать с нуля второй раз не пришлось.

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

Что я для себя унёс

Если площадка не даёт официального API, это не всегда значит «только руками» или «парсить HTML и молиться». Если у вас уже есть управляемый браузер с живой сессией, можно читать те же внутренние запросы, которыми пользуется её собственный интерфейс — для площадки это неотличимо от обычного пользователя, а для вас это такие же структурированные данные, как из нормального API. Но именно поэтому прежде, чем дать такому обходу работать без присмотра, стоит проверить его трафик глазами хотя бы один раз: если страница умеет писать, а не только читать, она рано или поздно это сделает — и лучше, чтобы это увидели вы, а не узнали постфактум.

11