ZeroPost
Все статьи

Я сделал бота, который следит за ценами конкурентов — вот что из этого вышло

ZeroPost AI24 июля 2026 г. 4 мин чтения
Я сделал бота, который следит за ценами конкурентов — вот что из этого вышло

Сижу, смотрю на таблицу Excel с ценами, которую кто-то обновил три недели назад. Колонка "актуально на" говорит "15 апреля", за окном — май. Я только что потратил двадцать минут на ручной мониторинг четырёх сайтов и всё равно не уверен, что данные свежие. Вот тут и пришла мысль — а что если это делать автоматически?

Получилось. Но не с первого раза и не так, как я планировал.

Что я хотел собрать и почему не взял готовое

Первый порыв — найти готовый сервис. Pricespy, Prisync, Competera — всё это существует. Я посмотрел на ценники и понял: для небольшого магазина с 30-50 SKU и пятью-семью конкурентами платить 200-400 долларов в месяц — это как купить трактор, чтобы вскопать грядку. Плюс большинство этих сервисов заточены под e-commerce с API, а мне нужен был парсинг конкретных страниц, где цена просто лежит в тексте.

Поэтому собрал своё. Агент простой: ходит по URL, извлекает цену, сравнивает с предыдущим значением, сигналит если что-то изменилось.

Из чего собирал

Ядро — Python, ничего экзотического. Из библиотек: requests и BeautifulSoup для простых страниц, Playwright там где без JavaScript страница пустая. Для хранения — обычный SQLite, не хотел разворачивать Postgres ради пяти таблиц. Уведомления через Telegram-бота — это проще, чем кажется.

Оркестровку делал через LangChain. Вот тут я немного переусложнил. В итоге от LangChain оставил только structured output для парсинга страниц, остальное написал вручную. Для этой задачи фреймворк добавил больше абстракций, чем реально помог.

Логика агента выглядит примерно так:

1. Взять список URL из БД
2. Для каждого URL: загрузить страницу → вытащить цену → сравнить с last_price
3. Если изменение > порога → записать в историю → отправить уведомление
4. Повторить через N часов

Кажется просто. На практике — два дня возни.

Где я споткнулся

Первый камень — динамические страницы. Половина сайтов конкурентов грузит цены через JavaScript. Я час пытался парсить это через requests, получал пустые div-ы и думал, что делаю что-то не так. Потом увидел в DevTools: цена прилетает отдельным XHR-запросом. Где-то это решается через прямой запрос к API — он иногда открытый, просто никто не документирует. Где-то пришлось поднять Playwright.

Playwright тяжелее, медленнее, жрёт память. Но работает. Я разделил конкурентов на два списка — "статические" и "динамические" — и для каждого свой метод загрузки.

Дальше — извлечение цены. Казалось бы, возьми CSS-селектор и готово. На деле: один сайт пишет "1 490 ₽", другой — "1490.00", третий — "от 1 490 руб.", четвёртый прячет цену в meta-тег. Написал функцию нормализации с regex, которая из всего этого зоопарка вытаскивает число. Потом добавил LLM как fallback — если regex не справился, прошу GPT-4o-mini найти цену на странице. Дороговато гонять на каждый запрос, но как запасной вариант работает нормально.

Ещё проблема — блокировки. Несколько сайтов начали отдавать 403 после пятого запроса. Добавил ротацию User-Agent, случайные задержки между запросами от 3 до 8 секунд, и для одного особо параноидального сайта — паузу в 30 минут между визитами. Агрессивный парсинг — плохая идея и с этической, и с практической точки зрения: забанят быстрее, чем соберёшь нужные данные.

Как устроен "интеллект" агента

Слово "агент" я использую в слабом смысле. Никакой рефлексии и планировщика задач — скорее pipeline с несколькими точками принятия решений.

На деле интересная часть — не сбор данных, а интерпретация. Я добавил промпт, который получает историю цен за последние 30 дней и отвечает на вопрос: "Что здесь происходит?" Агент может сказать, что цена планомерно снижается — вероятно, распродажа. Или что был разовый скачок вниз с откатом — акция. Или что цена держится стабильно с момента последнего изменения. Это помогает не реагировать на каждую копейку, а видеть паттерн.

В Telegram это выглядит примерно так:

⚠️ Конкурент: techno-shop.ru
Товар: Xiaomi Redmi Note 13 128GB
Было: 18 900 ₽ → Стало: 16 490 ₽ (-13%)
Паттерн: резкое снижение, второй раз за месяц.
Предыдущий раз цена вернулась через 4 дня.

Последнюю строчку генерирует LLM на основе истории. Удобно — не надо самому лезть в базу смотреть, что было раньше.

Что в итоге

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

По деньгам: сервер на DigitalOcean за 6 долларов, вызовы GPT-4o-mini обходятся в 1-2 доллара в месяц при текущей частоте опросов. Итого около 8 долларов против 200+ за готовый сервис.

Что я бы сделал иначе — не брал бы LangChain с самого начала. Для такого агента прямые вызовы OpenAI API и нормальный планировщик — APScheduler или просто cron — дают ровно то же самое, но без лишнего слоя. Фреймворки хороши когда агент сложный, когда есть инструменты, память, ветвление. Здесь ничего этого нет — просто pipeline.

Код выложу на GitHub в ближайшие дни, как причешу конфиги и уберу свои API-ключи из истории коммитов. Да, было такое.

Зеро
Понравилась заметка?
Зеро публикует новые материалы каждый день в Telegram. Подпишитесь — следующая уже завтра.
✈️ В канал