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

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

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

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

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

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

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

Етапи розробки

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

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розробка бота-парсера цін конкурентів по розпорядженню

Моніторинг цін конкурентів — основа динамічного ціноутворення. Бот збирає ціни по розпорядженню, зберігає історію змін та може автоматично корегувати ваші ціни за заданими правилами.

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

Scheduler → ScrapeCompetitorPrices Job
         → CompetitorScraper (HTTP/Playwright)
         → PriceNormalizer
         → PriceHistoryRepository (INSERT)
         → PriceChangeDetector
             → AlertDispatcher (якщо зміна > порогу)
             → RepricingEngine (якщо autoprice увімкнено)

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

class CompetitorPriceScraper
{
    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;

            $inStock = $crawler->filter($this->config['selectors']['in_stock'])
                ->count() > 0;

            return new PriceData(price: $price, inStock: $inStock);
        } catch (\Exception $e) {
            Log::warning("Price scrape failed: {$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 з детектором змін

class MonitorCompetitorPrice implements ShouldQueue
{
    public int $tries = 3;

    public function handle(
        CompetitorPriceScraper $scraper,
        PriceChangeDetector $detector,
        RepricingEngine $repricer
    ): void {
        $priceData = $scraper->scrapePrice($this->competitorUrl);
        if (!$priceData) return;

        // Збереження поточної ціни
        $record = CompetitorPrice::updateOrCreate(
            ['product_id' => $this->productId, 'competitor_id' => $this->competitorId],
            ['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);
            }
        }
    }
}

Рушій автоматичного перейценування

class RepricingEngine
{
    public function recalculate(int $productId): void
    {
        $product = Product::with('competitorPrices', 'repricingRule')->findOrFail($productId);
        $rule = $product->repricingRule;

        if (!$rule || !$rule->is_active) return;

        $competitorPrices = $product->competitorPrices
            ->where('in_stock', true)->pluck('price');

        if ($competitorPrices->isEmpty()) return;

        $newPrice = match ($rule->strategy) {
            'beat_lowest'  => $competitorPrices->min() - $rule->delta,
            'match_lowest' => $competitorPrices->min(),
            'beat_average' => $competitorPrices->avg() - $rule->delta,
            default        => null,
        };

        if (!$newPrice) return;

        $newPrice = max($newPrice, $rule->min_price ?? 0);
        $newPrice = min($newPrice, $rule->max_price ?? PHP_FLOAT_MAX);

        $currentPrice = $product->price;
        if (abs($newPrice - $currentPrice) / $currentPrice < 0.005) return;

        $product->update(['price' => round($newPrice, 2)]);
    }
}

Налаштування розпорядження

protected function schedule(Schedule $schedule): void
{
    $schedule->command('monitor:prices --priority=high')
        ->everyTwoHours()->withoutOverlapping();

    $schedule->command('monitor:prices --all')
        ->dailyAt('02:00')->withoutOverlapping();
}

Строк розробки: моніторинг 1 конкурента + історія + алерти — 4-6 робочих днів. Система з автоперейценкою та дашбордом для 5+ конкурентів — 10-14 днів.