PHP

Официальная лента показывала половину заказов

Охват ленты вырос с 14 карточек из 30 до 30 из 30, трафик за проход упал с 393 КБ до 39

Разработка инструмента Роль
2026 Год
PHP 5.3+, cURL, Node.js, Telegram Bot API, systemd, cron Стек

Задача

На бирже отклик номер два читают, а номер сорок — нет. Ценность не в том, чтобы видеть заказы, а в том, чтобы видеть их первым и понимать, стоит ли вообще тратить отклик. Нужен был инструмент, который сам смотрит ленты, отбирает подходящее и присылает в Telegram вместе с решающей цифрой — сколько человек уже откликнулось.

Три предположения, которые замер опроверг

Что официальная лента полна. Первая версия читала RSS — очевидное решение. Сличение со страницей раздела показало, что из 30 карточек первой страницы 16 в ленте отсутствуют: все вакансии и закреплённые объявления. Проверка через фильтр по типу подтвердила диагноз, а двенадцать минут наблюдения подряд исключили версию про задержку — пропавшие записи не появляются позже.

Что лента отдаёт заголовки кэширования. Не отдаёт ни ETag, ни Last-Modified, и генерируется заново на каждое обращение. Код, который ждал ответа 304, был мёртвым и удалён.

Что сжатие не применяется. Применяется: страница едет 39 КБ вместо 393. Это изменило расчёт нагрузки — частый опрос оказался посилен, а не расточителен.

Каждое предположение выглядело безобидным, и каждое меняло архитектуру. Проверка стоила минут, цена ошибки — половина потока заказов.

Что достали из разметки

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

Отбор

Стоп-слова проверяются только по заголовку и категории: фраза «потом ещё логотип понадобится» в теле заказа не должна убивать подходящую задачу — на живой ленте это ловилось. Но одного заголовка мало: вакансия «IT-специалист на Java» прошла отбор по слову «парсинге», а в тексте оказалось вербовочное объявление. Понадобился отдельный список стоп-фраз по тексту.

Перенос на сервер без Node

Порт на PHP написан на синтаксисе 5.3 — array() вместо коротких массивов, никаких стрелочных функций: скучный код, который запускается везде, лучше красивого, который упадёт на старой системе. Формат настроек и состояния сохранён, переезд сводится к копированию двух файлов.

Совпадение проверено сличением, а не на глаз: обе версии на одной ленте из 55 позиций отобрали одни и те же 11 заказов.

Отдельно написан разведчик окружения на синтаксисе PHP 5.2 — чтобы запуститься там, где остальное откажется, и внятно сказать почему. Он ловит два отказа, ради которых и нужен: OpenSSL старше 1.0.1 не умеет TLS 1.2, а устаревший набор корневых сертификатов рвёт соединение. Проверку сертификатов код при этом не отключает: инструмент приносит данные для решений, и подменить их не должен никто.

Что нашлось в собственном коде

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

Результат

Охват ленты вырос с 14 карточек из 30 до 30 из 30 плюс вторая площадка. Трафик за проход — 39 КБ вместо 393. Задержка до уведомления — две с половиной минуты вместо ручного просмотра. Требования к серверу — только PHP и cURL.

Срок: четыре дня, семь коммитов. Собственный проект.

Похожая задача?

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