Настройка отслеживания цен конкурентов для 1С-Битрикс
Мы работали с крупным онлайн-ритейлером бытовой техники, где цены конкурентов менялись до 15 раз в день. Ручной мониторинг отнимал 2 часа у менеджера ежедневно, а задержка реакции на снижение цены составляла до суток. Результат — потери в маржинальности до 5% по отдельным позициям. Решение — автоматическое отслеживание цен конкурентов прямо внутри 1С-Битрикс.
Отслеживание цен строится одним из двух способов: через готовый сервис мониторинга (Competera, Metacommerce, Priceva) или через собственный парсер. Готовый сервис — проще, надёжнее, но дорого при каталоге от 10 000 SKU. Собственный парсер — гибко, дёшево в эксплуатации, но требует регулярного обслуживания при изменениях на сайтах конкурентов. Задача настройки в обоих случаях одинакова: собрать данные, сохранить в Битрикс, показать менеджеру в удобном виде.
Сравнение подходов: сервис vs парсер
| Критерий | Готовый сервис | Собственный парсер |
|---|---|---|
| Скорость внедрения | 1-2 дня | 3-5 дней |
| Зависимость от внешнего API | Есть (ключ, лимиты) | Нет (но зависит от структуры сайта) |
| Стоимость эксплуатации | Высокая (подписка) | Низкая (только сервер) |
| Стабильность | Высокая | Средняя (риск слома парсера) |
| Объём каталога | Ограничен тарифом | Без ограничений |
Выбор зависит от вашего бюджета и объёма. Для каталога более 50 000 товаров чаще выгоднее парсер.
Почему нельзя хранить цены конкурентов в инфоблоках?
Инфоблоки Битрикс не предназначены для частых массовых обновлений. При каталоге в 10 000 товаров и 5 конкурентах получаем 50 000 записей, которые перезаписываются каждый час. ORM инфоблоков генерирует лишние события (OnBeforeIBlockElementUpdate), сбрасывает кэш, тормозит админку. Решение — использовать HL-блоки или отдельные таблицы в БД. Мы отдаём предпочтение таблицам — они быстрее, не имеют накладных расходов на события и версионность.
Архитектура хранения данных
Независимо от источника данных (сервис или парсер), структура хранения одинакова. Создаём две основные таблицы:
Конкуренты bl_price_competitors:
CREATE TABLE bl_price_competitors ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, domain VARCHAR(255) UNIQUE, active BOOLEAN DEFAULT true, logo_url VARCHAR(512) ); Цены конкурентов bl_competitor_prices:
CREATE TABLE bl_competitor_prices ( id SERIAL PRIMARY KEY, product_id INT NOT NULL, -- b_iblock_element.ID competitor_id INT REFERENCES bl_price_competitors(id), price NUMERIC(12,2) NOT NULL, url VARCHAR(512), -- URL страницы конкурента in_stock BOOLEAN DEFAULT true, checked_at TIMESTAMP NOT NULL DEFAULT NOW(), UNIQUE (product_id, competitor_id) -- одна актуальная цена ); CREATE INDEX idx_comp_prices_product ON bl_competitor_prices(product_id, checked_at DESC); История bl_competitor_prices_history — партиционированная по месяцам таблица для хранения изменений без раздувания основной. При каждом обновлении актуальной цены предыдущее значение перемещается в историю.
Интеграция через API сервиса мониторинга
При использовании готового сервиса агент запрашивает данные и записывает в bl_competitor_prices:
function SyncCompetitorPrices(): string { $client = new PriceMonitoringClient(MONITORING_API_KEY); $data = $client->getPrices(['date' => date('Y-m-d')]); foreach ($data['products'] as $item) { $productId = ProductMapper::findBySku($item['sku']); if (!$productId) continue; foreach ($item['competitors'] as $comp) { $competitorId = CompetitorTable::getOrCreateByDomain($comp['domain']); // Сохраняем в историю перед обновлением $current = CompetitorPriceTable::getByProductAndCompetitor($productId, $competitorId); if ($current && $current['PRICE'] != $comp['price']) { CompetitorPriceHistoryTable::add([ 'PRODUCT_ID' => $productId, 'COMPETITOR_ID' => $competitorId, 'PRICE' => $current['PRICE'], 'RECORDED_AT' => $current['CHECKED_AT'], ]); } CompetitorPriceTable::addOrUpdate([ 'PRODUCT_ID' => $productId, 'COMPETITOR_ID' => $competitorId, 'PRICE' => $comp['price'], 'URL' => $comp['url'], 'IN_STOCK' => $comp['in_stock'], 'CHECKED_AT' => new \Bitrix\Main\Type\DateTime(), ]); } } return __FUNCTION__ . '();'; } Расчёт ценовой позиции и агрегатов
При каждом обновлении считаем агрегаты и позицию в bl_product_price_position:
-- Обновляется триггером или агентом после синхронизации INSERT INTO bl_product_price_position (product_id, our_price, min_comp, avg_comp, max_comp, rank, updated_at) SELECT cp.product_id, bcp.PRICE as our_price, MIN(cp.price) as min_comp, ROUND(AVG(cp.price), 2) as avg_comp, MAX(cp.price) as max_comp, (SELECT COUNT(*) + 1 FROM bl_competitor_prices cp2 WHERE cp2.product_id = cp.product_id AND cp2.price < bcp.PRICE) as rank, NOW() FROM bl_competitor_prices cp JOIN b_catalog_price bcp ON bcp.PRODUCT_ID = cp.product_id AND bcp.CATALOG_GROUP_ID = 1 GROUP BY cp.product_id, bcp.PRICE ON CONFLICT (product_id) DO UPDATE SET our_price = EXCLUDED.our_price, min_comp = EXCLUDED.min_comp, avg_comp = EXCLUDED.avg_comp, rank = EXCLUDED.rank, updated_at = NOW(); Как настроить оповещения при изменении цен конкурентов?
Агент сравнивает новые цены с предыдущими и отправляет уведомление менеджерам при значимых изменениях — например, когда конкурент только что стал дешевле нас:
foreach ($priceChanges as $change) { if ($change['new_price'] < $change['our_price'] && $change['old_price'] >= $change['our_price']) { $message = sprintf( 'Конкурент %s снизил цену на %s до %s руб. (наша: %s руб.)', $change['competitor_name'], $change['product_name'], number_format($change['new_price'], 2, ',', ' '), number_format($change['our_price'], 2, ',', ' ') ); \Bitrix\Main\Mail\Event::send([ 'EVENT_NAME' => 'COMPETITOR_PRICE_ALERT', 'LID' => SITE_ID, 'C_FIELDS' => ['MESSAGE' => $message], ]); } } Типичные ошибки при настройке мониторинга
- Использование инфоблоков для хранения — приводит к деградации производительности при >20 000 записей.
- Отсутствие индексов по полям
product_idиchecked_at— агент синхронизации выполняется часами вместо минут. - Парсеры без обработки ошибок — при падении сайта конкурента агент падает с Exception, и синхронизация прерывается до ручного вмешательства.
- Слишком редкое обновление — при частоте раз в сутки вы пропускаете дневные колебания, которые могут составлять до 30%.
Что входит в работу по настройке нашего сервиса?
- Анализ вашего каталога и выбор оптимального источника данных (сервис или парсер).
- Создание таблиц или HL-блоков для хранения конкурентов, цен и истории.
- Разработка агента синхронизации с детальной обработкой ошибок (логирование, повтор при сбоях).
- Реализация модуля расчёта ценовой позиции с ранжированием.
- Вывод цен конкурентов в карточку товара административной панели и на витрину (по желанию).
- Настройка уведомлений по email или в Битрикс24.
- Документация по архитектуре и инструкция по обслуживанию.
Сроки и наши гарантии
| Этап | Срок |
|---|---|
| Схема БД и репозитории | 2 дня |
| Агент синхронизации с источником данных | 2 дня |
| Расчёт позиции и агрегатов | 1 день |
| Отображение в карточке товара (админка) | 2 дня |
| Оповещения при изменениях | 1 день |
| Тестирование | 1 день |
| Итого | 9–10 дней |
Стоимость рассчитывается индивидуально на основе объёма каталога и сложности интеграции. Мы гарантируем стабильную работу агентов в течение 6 месяцев после сдачи. Оценим проект бесплатно — свяжитесь с нами, и мы предложим архитектуру под ваш бюджет. Получите консультацию по архитектуре мониторинга цен, и вы убедитесь, что автоматизация окупается за первые 2 месяца.
Более 10 лет опыта в разработке на Битрикс и Битрикс24, более 50 успешных интеграций с системами мониторинга цен — наш опыт позволяет решать задачи любой сложности.







