Розробка парсера цін конкурентів для моніторингу

Ручний моніторинг цін конкурентів забирає час і не дає повної картини, а пропущена зміна ціни може коштувати продажів. Ми розробляємо парсери цін, які автоматично відстежують зміни на сайтах конкурентів та оперативно повідомляють про них. Наша команда реалізує проєкт під ключ — від аналізу структури сайтів до впровадження та подальшої підтримки, забезпечуючи надійну роботу системи.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка парсера цін конкурентів для моніторингу
Середній
~3-5 днів
Часті запитання

Ми розробляємо системи моніторингу цін конкурентів, які вирішують конкретне завдання: знати, коли і наскільки конкурент змінив ціну, раніше ніж це помітять покупці. Без автоматизації моніторингу ви ризикуєте пропустити момент зниження ціни на ключовий товар. Ручна перевірка десятків тисяч позицій нереальна, а разовий аудит дає лише миттєвий зріз. За час роботи ми запустили понад 30 таких проектів для e-commerce — від невеликих магазинів до великих маркетплейсів. Наш досвід дозволяє гарантувати стабільну роботу парсера навіть при зміні структури сайту. Якщо вам потрібен надійний інструмент, зв'яжіться з нами — ми оцінимо ваш проект і запропонуємо оптимальне рішення.

Архітектура системи моніторингу

Ключова відмінність від разового парсера — пріоритизація товарів. Популярні позиції потрібно перевіряти раз на годину, довгий хвіст каталогу — раз на добу. Це знижує навантаження на джерело і прискорює реакцію на важливі зміни. Черга завдань розподіляється за пріоритетами, що дозволяє обробляти до 10 000 товарів на хвилину без перевантаження.

[Scheduler]
├── High priority queue (топ-товари, щогодини)
└── Low priority queue (інші, раз на добу)
↓
[Fetcher] → [Parser] → [Change Detector] → [Alert Engine]
↓
[price_history table]

Change Detector порівнює нову ціну з останнім записом в історії. При зміні — запис у price_history і подія в чергу алертів. Без змін — лише оновлення last_checked_at, щоб не роздувати історію. Такий підхід дозволяє зберігати до 5 років історії при мінімальному обсязі даних.

Чому JSON-LD — найкраще джерело для парсингу цін?

Ціни на сайтах бувають представлені по-різному. В HTML — CSS-селектор .product-price або атрибут data-price. В Schema.org — надійно, не ламається при редизайні. Через XHR API — перехоплення мережевих запитів через Playwright. Динамічно через JS після завантаження — потрібен headless browser. JSON-LD — найбільш стабільне джерело: багато SEO-оптимізованих магазинів додають мікророзмітку для пошукових роботів. Помилка при парсингу через HTML може сягати 10%, а через JSON-LD — менше 0.5%.

import * as cheerio from 'cheerio';

interface PriceData {
  price: number;
  priceSale?: number;
  currency: string;
  inStock: boolean;
}

function extractPriceFromJsonLd(html: string): PriceData | null {
  const $ = cheerio.load(html);
  for (const scriptEl of $('script[type="application/ld+json"]').toArray()) {
    try {
      const data = JSON.parse($(scriptEl).html() ?? '{}');
      const product = data['@type'] === 'Product' ? data : (Array.isArray(data['@graph']) ? data['@graph'].find((n: { '@type': string }) => n['@type'] === 'Product') : null);
      if (product?.offers) {
        const offer = Array.isArray(product.offers) ? product.offers[0] : product.offers;
        return {
          price: parseFloat(offer.price),
          currency: offer.priceCurrency ?? 'USD',
          inStock: offer.availability?.includes('InStock') ?? true,
        };
      }
    } catch {
      continue;
    }
  }
  return null;
}

Обробка форматів цін у тексті: "$12–17", "$12.99", "€ 9,90" — нормалізація через regex. Зберігати як DECIMAL(10,2) з окремим полем currency. Слідкувати за трьома рівнями: ціна без знижки (price_original), ціна зі знижкою (price_sale), ціна за карткою лояльності (часто третя прихована ціна).

Джерело Стабільність Швидкість Складність
HTML Середня Висока Низька
JSON-LD Висока Висока Низька
XHR API Середня Середня Середня
Headless browser Низька Низька Висока

Механізм детектора змін

CREATE TABLE monitored_products (
    id SERIAL PRIMARY KEY,
    source VARCHAR(100) NOT NULL,
    external_id VARCHAR(255) NOT NULL,
    title TEXT,
    url TEXT NOT NULL,
    priority SMALLINT DEFAULT 5, -- 1=найвищий, 10=найнижчий
    check_interval INT DEFAULT 360, -- хвилини
    last_checked_at TIMESTAMPTZ,
    UNIQUE(source, external_id)
);

CREATE TABLE price_history (
    id BIGSERIAL PRIMARY KEY,
    product_id INT REFERENCES monitored_products(id),
    price DECIMAL(10,2),
    price_original DECIMAL(10,2),
    in_stock BOOLEAN,
    currency VARCHAR(3) DEFAULT 'USD',
    recorded_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX ON price_history(product_id, recorded_at DESC);

-- Швидкий доступ до актуальної ціни без JOIN з історією
ALTER TABLE monitored_products ADD COLUMN current_price DECIMAL(10,2), ADD COLUMN current_in_stock BOOLEAN;
async function processNewPrice(
    productId: number,
    newPrice: number,
    newInStock: boolean
): Promise<{ changed: boolean; delta?: number }> {
    const product = await db.monitoredProducts.findById(productId);
    const priceChanged = product.currentPrice !== newPrice;
    const stockChanged = product.currentInStock !== newInStock;
    if (!priceChanged && !stockChanged) {
        // Тільки оновити час перевірки
        await db.monitoredProducts.update(productId, { lastCheckedAt: new Date() });
        return { changed: false };
    }
    // Записати в історію
    await db.priceHistory.create({
        productId,
        price: newPrice,
        inStock: newInStock,
        recordedAt: new Date(),
    });
    // Оновити поточні значення
    await db.monitoredProducts.update(productId, {
        currentPrice: newPrice,
        currentInStock: newInStock,
        lastCheckedAt: new Date(),
    });
    const delta = product.currentPrice ? ((newPrice - product.currentPrice) / product.currentPrice) * 100 : 0;
    return { changed: true, delta };
}

Налаштування алертів та порогів

Конфігуровані правила спрацювання:

  • Ціна знизилася більше ніж на X% (наприклад, 5% або 10%)
  • Ціна опустилася нижче вашої ціни на аналогічний товар
  • Товар з'явився або зник з наявності
  • Ціна змінилася у N+ конкурентів одночасно (ознака ринкового зсуву)
  • Ціна досягла історичного мінімуму за останні 90 днів
async function checkAlertRules(productId: number, delta: number): Promise<void> {
    const rules = await db.alertRules.findAll({ productId, active: true });
    for (const rule of rules) {
        const triggered = (rule.type === 'price_drop_percent' && delta < -rule.threshold) || (rule.type === 'below_my_price' && await isPriceBelowMyPrice(productId)) || (rule.type === 'out_of_stock' && newInStock === false);
        if (triggered) {
            await sendAlert(rule, productId, delta);
        }
    }
}

Доставка: Telegram-бот (миттєво через Bot API), email-дайджест (раз на день), webhook у систему управління цінами (для автоматичної реакції). Пороги можна змінювати в реальному часі через дашборд.

Що всередині дашборду аналітики?

Мінімально необхідні екрани:

Таблиця моніторингу — всі відстежувані товари з поточною ціною конкурента, вашою ціною, різницею у відсотках і трендом (стрілка вгору/вниз).

Графік цін — ціна конкурента vs ваша ціна за вибраний період. Recharts LineChart з двома лініями та маркерами змін.

Стрічка алертів — останні 50 змін з фільтрацією за джерелом і типом зміни.

Швидка реалізація дашборду — Metabase, підключений до PostgreSQL. Кастомний React-інтерфейс з Recharts потрібен, якщо дашборд вбудовується в існуючу систему управління асортиментом.

Процес розробки

  1. Аналітика — вивчаємо цільові сайти, визначаємо пріоритети товарів, погоджуємо алерти та дашборд.
  2. Проектування — проектуємо архітектуру парсера, базу даних, правила алертів.
  3. Реалізація — пишемо код, налаштовуємо черги, інтеграції.
  4. Тестування — запускаємо на реальних даних, перевіряємо точність та стабільність.
  5. Деплой і підтримка — розгортаємо на вашому сервері або хмарі, передаємо документацію, навчаємо.

Що входить у роботу

  • Вихідний код парсера з відкритою документацією
  • Доступ до дашборду та API
  • Інструкція з експлуатації
  • Гарантія стабільної роботи 3 місяці
  • Підтримка при змінах структури сайтів (до 5 адаптацій на місяць)

Строки та масштаб

Масштаб Джерел Товарів Строк
Малий 1–3 до 10k 5–8 днів
Середній 3–10 10k–100k 2–3 тижні
Крупний 10+ 100k+ 4–6 тижнів

Для 100k+ товарів з історією за рік — ClickHouse замість PostgreSQL для зберігання price_history: аналітичні запити (агрегація за період, пошук мінімуму) на великих обсягах працюють на порядок швидше. PostgreSQL залишається для оперативних даних і конфігурації.

Приклад архітектури для крупного проекту Для масштабів понад 100k товарів ми використовуємо розподілені черги RabbitMQ та мікросервіси на Go для парсингу. Це дозволяє горизонтально масштабуватися до 1 млн товарів з часом оновлення не більше 1 години.

Зв'яжіться з нами для консультації — ми оцінимо ваш проект і запропонуємо оптимальне рішення. Отримайте надійний парсер цін під ключ з гарантією стабільності.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1543
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1374
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060