Налаштування відстеження цін конкурентів для 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-блоків для зберігання конкурентів, цін та історії.
- Розробка агента синхронізації з детальною обробкою помилок (логування, повтор при збоях).
- Реалізація модуля розрахунку цінової позиції з ранжуванням.
- Виведення цін конкурентів у картку товару адміністративної панелі та на вітрину (за бажанням).
- Налаштування сповіщень електронною поштою або в Бітрікс24.
- Документація з архітектури та інструкція з обслуговування.
Строки та наші гарантії
| Етап | Строк |
|---|---|
| Схема БД та репозиторії | 2 дні |
| Агент синхронізації з джерелом даних | 2 дні |
| Розрахунок позиції та агрегатів | 1 день |
| Відображення в картці товару (адмінка) | 2 дні |
| Сповіщення при змінах | 1 день |
| Тестування | 1 день |
| Разом | 9–10 днів |
Вартість розраховується індивідуально на основі обсягу каталогу та складності інтеграції. Ми гарантуємо стабільну роботу агентів протягом 6 місяців після здачі. Оцінимо проєкт безкоштовно — зв'яжіться з нами, і ми запропонуємо архітектуру під ваш бюджет. Отримайте консультацію з архітектури моніторингу цін, і ви переконаєтеся, що автоматизація окупається за перші 2 місяці.
Більше 10 років досвіду в розробці на Бітрікс та Бітрікс24, більше 50 успішних інтеграцій із системами моніторингу цін — наш досвід дозволяє вирішувати завдання будь-якої складності.







