Разработка бота-парсера цен конкурентов по расписанию

Представьте: ваш конкурент снижает цену на 15% на топ-20 позиций, а вы узнаёте об этом через неделю, когда продажи уже упали. Именно это произошло с одним из наших клиентов, потерявшим 30% маржи за месяц. Чтобы исключить такие ситуации, мы разрабатываем автоматические боты-парсеры цен, которые работ

Разработка и обслуживание любых видов сайтов:

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

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

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

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

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1422
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1287
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    984
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1249
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    986
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    999

Представьте: ваш конкурент снижает цену на 15% на топ-20 позиций, а вы узнаёте об этом через неделю, когда продажи уже упали. Именно это произошло с одним из наших клиентов, потерявшим 30% маржи за месяц. Чтобы исключить такие ситуации, мы разрабатываем автоматические боты-парсеры цен, которые работают по расписанию, хранят историю и могут самостоятельно корректировать ваши цены по гибким правилам. Мы занимаемся мониторингом цен более 7 лет и реализовали 40+ проектов для e-commerce — от одежды до электроники. Гарантируем корректную работу парсера на всех этапах, от сбора до авторепрайсинга. Свяжитесь с нами, чтобы мы разработали систему под ваш каталог.

Почему ручной мониторинг цен неэффективен?

  • Устаревшие данные: вы проверяете цены раз в неделю, а конкуренты меняют их ежедневно. К моменту вашей реакции вы уже потеряли часть продаж или маржи.
  • Антиблокировочные меры: конкуренты используют Cloudflare, капчи, динамические селекторы. Ручной сбор не справляется, нужен headless-браузер с ротацией прокси.
  • Нормализация: цены приходят в разном формате: с налогом, без налога, в разных валютах, с пробелами и символами. Без нормализации сравнивать их бесполезно.

Как мы строим систему мониторинга?

Мы используем Laravel 11 на PHP 8.3, PostgreSQL для хранения, Redis для очередей и Playwright для парсинга динамики. Архитектура микросервисная — каждый конкурент обрабатывается независимо.

Scheduler → ScrapeCompetitorPrices Job (per competitor) → CompetitorScraper (HTTP/Playwright) → PriceNormalizer → PriceHistoryRepository (INSERT) → PriceChangeDetector → AlertDispatcher (если изменение > порога) → RepricingEngine (если включён autoprice) 

Модель данных

// database/migrations/create_competitor_prices_table.php Schema::create('competitor_prices', function (Blueprint $table) { $table->id(); $table->foreignId('product_id')->constrained(); $table->foreignId('competitor_id')->constrained(); $table->string('competitor_sku')->nullable(); $table->string('competitor_url'); $table->decimal('price', 12, 2); $table->decimal('sale_price', 12, 2)->nullable(); $table->boolean('in_stock')->default(true); $table->timestamp('scraped_at'); $table->timestamps(); $table->index(['product_id', 'competitor_id', 'scraped_at']); }); // История для графиков и аналитики Schema::create('competitor_price_history', function (Blueprint $table) { $table->id(); $table->foreignId('product_id')->constrained(); $table->foreignId('competitor_id')->constrained(); $table->decimal('price', 12, 2); $table->boolean('in_stock'); $table->date('recorded_date'); $table->timestamps(); $table->unique(['product_id', 'competitor_id', 'recorded_date']); }); 

Конфигурация конкурентов

// config/competitors.php return [ 'competitor_a' => [ 'name' => 'Shop A', 'base_url' => 'https://shop-a.ru', 'selectors' => [ 'price' => '.current-price', 'in_stock' => '.in-stock-badge', ], 'price_regex' => '/[\d\s]+/', 'url_pattern' => 'https://shop-a.ru/product/{sku}', 'requires_js' => false, 'request_delay' => [1000, 3000], // ms ], 'wildberries' => [ 'name' => 'Wildberries', 'type' => 'api', 'scraper' => WildberriesPriceScraper::class, 'request_delay' => [500, 1500], ], ]; 

Базовый скрапер цен

// app/Services/PriceMonitor/CompetitorPriceScraper.php class CompetitorPriceScraper { public function __construct( private Client $httpClient, private array $config ) {} public function scrapePrice(string $url): ?PriceData { try { $html = $this->fetch($url); $crawler = new Crawler($html); $priceText = $crawler->filter($this->config['selectors']['price']) ->first() ->text(''); $price = $this->extractPrice($priceText); if ($price === null) return null; $salePrice = null; if (!empty($this->config['selectors']['sale_price'])) { $salePriceText = $crawler->filter($this->config['selectors']['sale_price']) ->first()->text(''); $salePrice = $this->extractPrice($salePriceText); } $inStock = true; if (!empty($this->config['selectors']['in_stock'])) { $inStock = $crawler->filter($this->config['selectors']['in_stock'])->count() > 0; } return new PriceData( price: $price, salePrice: $salePrice, inStock: $inStock, ); } catch (\Exception $e) { Log::warning("Price scrape failed for {$url}: {$e->getMessage()}"); return null; } } private function extractPrice(string $text): ?float { $cleaned = preg_replace('/[^\d,.]/', '', str_replace(' ', '', $text)); $cleaned = str_replace(',', '.', $cleaned); return is_numeric($cleaned) ? (float) $cleaned : null; } } 

Job с детектором изменений

// app/Jobs/MonitorCompetitorPrice.php class MonitorCompetitorPrice implements ShouldQueue { public int $tries = 3; public array $backoff = [60, 120, 300]; public function __construct( private int $productId, private int $competitorId, private string $competitorUrl ) {} public function handle( CompetitorPriceScraper $scraper, PriceChangeDetector $detector, RepricingEngine $repricer ): void { $config = Competitor::find($this->competitorId)->config; $priceData = $scraper->scrapePrice($this->competitorUrl); if ($priceData === null) return; // Сохранение текущей цены $record = CompetitorPrice::updateOrCreate( [ 'product_id' => $this->productId, 'competitor_id' => $this->competitorId, ], [ 'price' => $priceData->price, 'sale_price' => $priceData->salePrice, 'in_stock' => $priceData->inStock, 'scraped_at' => now(), ] ); // Сохранение в историю (один раз в день) CompetitorPriceHistory::firstOrCreate( [ 'product_id' => $this->productId, 'competitor_id' => $this->competitorId, 'recorded_date' => today(), ], [ 'price' => $priceData->price, 'in_stock' => $priceData->inStock, ] ); // Детект изменений if ($record->wasChanged('price')) { $change = $detector->analyze($record); if ($change->isSignificant()) { Notification::route('mail', config('monitoring.alert_email')) ->notify(new CompetitorPriceChangedNotification($record, $change)); } // Автоперейценка if (config('repricing.enabled')) { $repricer->recalculate($this->productId); } } } } 

Настройка расписания мониторинга

Расписание настраивается под ваши задачи. Высокоприоритетные товары — каждые 2 часа, массовые — раз в день ночью. Планировщик Laravel предотвращает наложение задач.

Для агрегации истории цен мы запускаем ежедневный артефакт, который сводит данные за день в одну запись — это экономит место и ускоряет запросы графиков.

Автоматический парсер обрабатывает 1000 товаров за 10 минут, что в 40 раз быстрее ручного сбора.

Какие данные сохраняются в истории цен?

Сохраняется цена, цена со скидкой, признак наличия на складе и дата. История ведётся по дням — это позволяет строить графики трендов и анализировать сезонность. Например, вы можете увидеть, что каждую зиму конкурент снижает цены на 10% на определённые категории, и подготовиться заранее.

Стратегии автоматического перейценивания

Стратегия Описание Когда применять
beat_lowest Установить цену на N рублей ниже минимальной Агрессивный захват доли, если есть запас маржи
match_lowest Сравнять с минимальной ценой конкурента Удержание позиций в высококонкурентных нишах
beat_average Цена на N рублей ниже средней цены конкурентов Баланс между маржой и конкурентоспособностью
percentile Цена на заданном перцентиле (например, 25-й) Сохранение позиционирования (премиум или бюджет)

Каждая стратегия учитывает минимальное изменение в 0.5%, чтобы избежать скачков цен.

Дашборд мониторинга

Ключевые метрики для отображения:

Метрика Описание
Товары, где мы дороже Количество и % от каталога
Средняя дельта к минимуму Средний % разницы с lowest price
Товары с изменением > 5% Требуют ручной проверки
Товары вне остатков у конкурентов Потенциал для повышения цены

Дашборд позволяет быстро выявлять аномалии, например, внезапное изменение цены у крупного конкурента.

Типичные ошибки при внедрении мониторинга цен

  • Игнорирование изменения селекторов. Если сайт конкурента меняет вёрстку — парсер падает. Всегда используйте fallback-селекторы и алерты при сбоях.
  • Слишком частые запросы. Защита Cloudflare блокирует IP. Выдерживайте задержки и используйте ротацию прокси.
  • Отсутствие порогов в автоперейценке. Без минимального процента изменения вы будете менять цену на копейки, что раздражает покупателей и теряет доверие.

Что входит в работу

  • Документация: описание архитектуры мониторинга, инструкция по добавлению нового конкурента, настройка правил репрайсинга.
  • Доступы: предоставляем доступ к серверу, очередям, дашборду.
  • Обучение: проводим демо-сессию дашборда и правил для вашей команды.
  • Поддержка: бесплатная поддержка в течение 1 месяца после запуска.

Сроки и стоимость

Разработка базовой системы (1 конкурент + история + алерты) занимает 4–6 рабочих дней. Полная система с автоперейценкой и дашбордом для 5+ конкурентов — 10–14 дней. Стоимость рассчитывается индивидуально, исходя из числа конкурентов, сложности парсинга и требуемых интеграций. Закажите индивидуальную разработку системы мониторинга цен — свяжитесь с нами для оценки вашего проекта.