Playwright или API: как работает автоотклик

Разбираем, чем браузерная автоматизация откликов отличается от API: сессии, JavaScript, защита от прямых запросов, ресурсы и цена параллельных откликов.

· 10 мин чтения
#работные сайты#playwright#api#автоотклик#браузерная автоматизация

В коде автоотклика есть соблазнительная развилка. Можно сделать один HTTP-запрос и получить компактный JSON, а можно поднять Chromium, дождаться загрузки страницы, найти кнопку и пройти форму. Первый вариант выглядит быстрее и дешевле. Второй — сложнее почти по всем инженерным метрикам.

Но для работных сайтов это не две взаимозаменяемые реализации одной функции. API работает по заранее определённому контракту, а браузер обслуживает живой пользовательский сценарий со сессией, JavaScript, проверками и изменяющимися формами. Поэтому современный автоотклик нельзя свести к замене page.click() на requests.post(). Общая механика сервиса разобрана в полном руководстве по автоотклику на вакансии; здесь разберём именно техническую границу между подходами.

Выбор влияет не только на архитектуру, но и на то, что увидит пользователь. API-клиент может принять успешный сетевой ответ за готовый отклик, хотя площадка вернула дополнительный вопрос. Браузер способен заметить неактивную кнопку, капчу и финальное подтверждение, зато требует ресурсов и постоянной поддержки селекторов. Ниже сравним авторизацию, состояние и рендер, разберём причины 403 у прямых запросов, посчитаем цену параллелизма и переведём всё это в понятные критерии выбора сервиса. После этого обещание «работаем через API» или «используем реальный браузер» можно будет оценить по содержанию, а не по ярлыку.

API и браузер решают разные задачи

API — это отдельный вход в систему. Клиент отправляет запрос на документированный endpoint, передаёт параметры, а сервер возвращает структурированный ответ. Если контракт разрешает действие, не нужно загружать шрифты, строить DOM и ждать анимацию. Поиск двадцати вакансий занимает один запрос, а результат уже разложен по полям.

Браузер идёт по другому пути. Он открывает страницу площадки, получает HTML и JavaScript, хранит cookies, исполняет клиентский код и показывает то же состояние, которое увидел бы человек. Playwright не «скачивает сайт» — он управляет полноценным Chromium и взаимодействует с элементами после рендера.

Разница видна на простом сравнении:

API-запросPlaywright в Chromium
АвторизацияТокен и права приложенияПользовательская сессия и cookies
ДанныеГотовый JSON по контрактуHTML, DOM и состояние интерфейса
JavaScriptНе исполняетсяИсполняется как в обычном браузере
Форма откликаТолько если есть подходящий методПроход по фактическим шагам формы
ИзмененияВерсионирование или обновление документацииСелекторы и сценарий могут измениться сразу
Цена одного действияНизкаяВыше: память, CPU, сеть и время рендера
Неожиданный ручной шагОбычно ошибка APIМожно показать пользователю окно и продолжить вручную

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

Почему requests и curl не заменяют браузерную сессию

В официальной документации API работных сайтов по-прежнему описаны вакансии, резюме и отклики. Из этого легко сделать неверный вывод: достаточно скопировать URL в curl, добавить User-Agent и получить те же данные, что видны на сайте.

На практике доступ проходит через несколько независимых слоёв. Endpoint сначала видит IP и заголовки клиента, затем защиту от автоматических запросов, авторизацию и права конкретного приложения или пользователя. Только после этого выполняется бизнес-метод. Ответ 403 Forbidden на первом слое ничего не говорит о том, правильно ли собраны параметры поиска: до них запрос мог вообще не дойти.

Именно это происходит с прямым серверным поиском JobTurbo. В коде сохранился API-путь, но запросы с серверных адресов стабильно получают 403 от защитного слоя. Свежие браузерные cookies иногда дают больше контекста, однако не превращают API в надёжный основной канал. Поэтому рабочая схема быстро переключается на поиск через страницу, не заставляя пользователя ждать несколько повторов заведомо закрытого запроса.

С откликом проблема ещё шире. Между вакансией и кнопкой «Отправить» могут появиться обязательное сопроводительное, вопрос работодателя, тест, подтверждение телефона или капча. Один POST-запрос должен заранее знать весь набор полей и внутренние идентификаторы текущей формы. Браузер видит их после рендера и может принять решение по фактическому состоянию.

Не путать с обратным проектированием фронтенда. В DevTools действительно можно увидеть внутренний fetch, который отправляет форма. Но этот URL не становится публичным API: он может зависеть от CSRF-токена, одноразового состояния, cookies и версии интерфейса. Площадка вправе поменять его без миграционного периода, потому что единственный официальный клиент такого запроса — собственная страница.

Что даёт рендер JavaScript

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

Playwright ждёт не строку в ответе, а наблюдаемое состояние:

  1. Страница открылась и не перекинула на логин.
  2. Карточка вакансии отрисовалась.
  3. Кнопка отклика видима и доступна.
  4. Форма приняла сопроводительное и обязательные ответы.
  5. После отправки появился признак успешного отклика.

Последний пункт особенно важен. HTTP 200 означает лишь успешную обработку сетевого запроса. Он не всегда равен отправленному отклику: сервер мог вернуть новую форму, предупреждение или страницу проверки. В браузерном сценарии подтверждением служит изменившийся интерфейс — например, статус «Вы откликнулись». Если подтверждения нет, результат нельзя записывать как успех.

Тот же принцип нужен для капчи. Автоматизация не должна пытаться «продавить» страницу. Она останавливается, показывает видимое окно пользователю и продолжает только после ручного решения. Это медленнее идеального API-вызова, но честнее ложного успешного статуса.

Цена браузерного подхода

Chromium заметно тяжелее HTTP-клиента. Один контекст держит движок JavaScript, DOM, сетевой кэш и состояние вкладок. Если бездумно запустить по браузеру на каждый отклик, закончится память, а десятки одновременных страниц создадут неестественный всплеск действий.

Поэтому масштабируется не число процессов, а очередь:

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

Для пользователя из этого следует полезное ограничение: браузерный автоотклик не должен обещать тысячу заявок за минуту. Такая цифра означает либо пустые API-вызовы, либо десятки одновременно открытых сессий без контроля. В поиске работы скорость важна на уровне часов, а не миллисекунд. Гораздо важнее успевать отвечать на приглашения и не расходовать отклики на нерелевантные вакансии. Практический выбор темпа есть в разборе количества откликов в день.

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

Как JobTurbo использует Playwright

JobTurbo хранит не «секретный API площадки», а состояние браузерной сессии. Пользователь входит на площадку сам, после чего Playwright открывает поиск и вакансии в авторизованном контексте. Для серверных запусков работа идёт с российских адресов; в десктоп-приложении — с компьютера и подключения самого пользователя.

Дальше задачи разделены:

  • браузер читает выдачу, открывает карточку и проходит фактическую форму;
  • фильтры проверяют должность, регион, формат работы, зарплату и исключения до отклика;
  • AI формирует письмо из текста вакансии и резюме, а не из одного шаблона;
  • движок подтверждает результат по состоянию страницы и отдельно сообщает ручные шаги;
  • ограничитель нагрузки не запускает больше Chromium-контекстов, чем выдерживает текущий хост.

Посмотреть этот путь без технических деталей можно на странице «Как работает JobTurbo». А почему персональное письмо остаётся важным даже при исправной автоматизации, разобрано в руководстве по AI-сопроводительным.

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

Итог

API выигрывает там, где есть доступный и достаточный официальный контракт. Playwright выигрывает там, где результат зависит от живой сессии, JavaScript и формы, которую нужно пройти до видимого подтверждения.

На работном сайте прямой curl может закончиться на 403 ещё до поиска, а один внутренний POST не покрывает вопросы работодателя, тесты и капчу. Поэтому браузерный подход дороже по ресурсам и сопровождению, но даёт главное: автоматизация видит то же состояние, что пользователь, и не записывает незавершённый отклик как успешный.

Частые вопросы

Чем Playwright отличается от API площадки?

API возвращает структурированные данные по HTTP и требует соблюдать правила конкретного метода. Playwright управляет браузером: загружает страницу, исполняет JavaScript и работает внутри пользовательской сессии с её cookies.

Почему прямой запрос к API площадки через curl возвращает 403?

Сам URL и правильный User-Agent не гарантируют доступ. Прямой запрос может остановить защитный слой площадки по IP, состоянию сессии или другим сигналам; в такой ситуации повторение того же curl-запроса не превращает его в браузерную сессию.

Значит ли это, что API площадок больше не существует?

Нет. Документация и часть методов существуют, особенно для работодателей и интеграций. Но наличие метода в документации не означает, что анонимный серверный запрос подходит для полного кандидатского сценария от поиска до отправки отклика.

Можно ли отправлять отклики обычными requests-запросами?

Надёжно воспроизвести весь сценарий одними requests-запросами нельзя: отклик зависит от авторизации, состояния страницы, обязательных полей, тестов и защитных проверок. Незадокументированные внутренние запросы фронтенда также могут меняться без предупреждения.

Playwright всегда медленнее API?

Один HTTP-запрос дешевле загрузки страницы, но сравнивать нужно весь сценарий. Браузер тратит больше CPU и памяти, зато проходит тот же интерфейс, видит валидацию формы и может корректно остановиться на ручном шаге.

Защищает ли реальный браузер от ограничений площадки?

Нет. Браузерная автоматизация не отменяет правила и ограничения площадки. Она лишь работает через тот же интерфейс, что и пользователь; релевантность, умеренный темп и корректная обработка капчи всё равно обязательны.

Запустите автоотклик бесплатно

До 25 успешных откликов за скользящие 24 часа — без оплаты и привязки карты. AI подготовит сопроводительное под каждую подходящую вакансию.

Подключить JobTurbo →