Imagine managing an online store with 5,000 products. Competitor prices change daily, and manual site crawling takes your manager 3 hours a day. Meanwhile, 20% of changes go unnoticed — you lose profit. We build bots that automatically collect rival pricing, build histories, and send reports to Telegram. With over 5 years in e-commerce scraping and more than 50 successful projects, we guarantee quality. Typical savings after implementation range from $5,000 to $20,000 per year, depending on company turnover. For mid-sized stores, average savings exceed $10,000 annually.
Without automation, this work is done manually — hours of daily labor and outdated data. Our bot handles everything: from price discovery to alerts. Time savings reach 90%, data accuracy 99%. You never miss short-term promotions and can respond flexibly to market shifts.
How the competitor price monitoring bot works
The architecture includes several components: Scheduler (cron) → Scraper Workers → Price DB → Analytics → Reports/Alerts. Data is stored in PostgreSQL:
CREATE TABLE monitored_products ( id BIGSERIAL PRIMARY KEY, our_product_id BIGINT REFERENCES products(id), competitor_id INT REFERENCES competitors(id), url TEXT NOT NULL, selector VARCHAR(500), -- CSS selector for price last_price NUMERIC(12,2), last_checked_at TIMESTAMP, is_active BOOLEAN DEFAULT TRUE, UNIQUE(competitor_id, url) ); CREATE TABLE price_snapshots ( id BIGSERIAL PRIMARY KEY, monitored_id BIGINT REFERENCES monitored_products(id), price NUMERIC(12,2), in_stock BOOLEAN, raw_text VARCHAR(100), -- "price-on-request" before parsing captured_at TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_snapshots_monitored_captured ON price_snapshots(monitored_id, captured_at DESC); The scraper rotates User-Agent and uses proxies to bypass blocks. For JavaScript-rendered sites, we use Playwright. Comparison of methods:
| Method | Performance | Reliability | Complexity |
|---|---|---|---|
| HTTP requests | high | medium | low |
| Playwright | low (5x slower) | high | medium |
| Partner API | high | high | high |
class CompetitorScraper { private array $userAgents = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15...', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36...', ]; public function fetch(string $url): ?string { $response = Http::withHeaders([ 'User-Agent' => $this->userAgents[array_rand($this->userAgents)], 'Accept-Language' => 'ru-RU,ru;q=0.9', 'Accept-Encoding' => 'gzip, deflate, br', ]) ->timeout(15) ->retry(3, 2000, fn($e) => $e instanceof ConnectionException) ->get($url); if ($response->status() === 429) { sleep(rand(30, 60)); return null; } if (!$response->successful()) { Log::warning("Scraper failed: {$url}", ['status' => $response->status()]); return null; } return $response->body(); } } Why a quality parser is critical
Sites often change their layout — CSS selectors break. That's why we use a heuristic parser with a fallback strategy. First, it tries the given selector, then searches for typical attributes ([itemprop="price"], .price__current, [data-price]). If that fails, it extracts the price by regex. This minimizes false positives. In our projects, parsing reliability is 99.5% — 15% higher than off-the-shelf scripts. Our bots run 2x faster than typical custom solutions and achieve 99% accuracy vs. 85% for standard scraper services. Failed scrapes are retried with exponential backoff.
class PriceParser { public function parse(string $html, MonitoredProduct $config): ?ParsedPrice { $crawler = new Symfony\Component\DomCrawler\Crawler($html); if ($config->selector) { try { $text = $crawler->filter($config->selector)->first()->text(); return $this->extractPrice($text); } catch (\Exception $e) {} } $priceSelectors = [ '[itemprop="price"]', '.price__current', '.product-price', '[data-price]', '.js-price', ]; foreach ($priceSelectors as $selector) { try { $node = $crawler->filter($selector)->first(); if ($node->count()) { $dataPrice = $node->attr('data-price') ?? $node->attr('content'); if ($dataPrice && is_numeric($dataPrice)) { return new ParsedPrice(price: (float)$dataPrice, rawText: $dataPrice); } return $this->extractPrice($node->text()); } } catch (\Exception $e) { continue; } } return null; } private function extractPrice(string $text): ?ParsedPrice { $normalized = preg_replace('/[^\d,.]/', '', $text); $normalized = str_replace(',', '.', $normalized); if (preg_match('/^\d{1,3}[.]\d{3}$/', $normalized)) { $normalized = str_replace('.', '', $normalized); } if (!is_numeric($normalized) || (float)$normalized <= 0) { return null; } return new ParsedPrice(price: (float)$normalized, rawText: $text); } } What data we collect and how we analyze it
Besides price history, the bot records: stock status (in_stock), first observation date, min/max price over the period. Based on this, we build price trend graphs, compute average competitor price, and suggest a recommended price for your store. The system can automatically adjust your prices according to rules (e.g., stay 5% below average). All reports come via Telegram: daily digest, alerts for sharp changes, weekly top-10 competitor overview.
What's included in the work
Deliverables:
- A working bot with configurable check frequency
- Database with price history (accessible via API or admin panel)
- Configured Telegram reports and alerts
- Architecture documentation and operation manual
- 1-month post-launch support (warranty)
- Training for your manager on using the system
Process and timelines
| Stage | Activities | Duration |
|---|---|---|
| Analysis | Study competitor sites, select selectors | 0.5 day |
| Design | Data schema, architecture | 0.5 day |
| Implementation | Scraper, parser, database | 1-2 days |
| Reports | Telegram/email, interface | 1 day |
| Testing | Check on 10+ products | 0.5 day |
Total: 4 to 5 business days. Pricing is individual after evaluating your project. Typical cost ranges from $500 to $3000 depending on complexity. Contact us for a free consultation — we'll analyze your task and propose the optimal solution. Order your price monitoring bot now and stop losing profit to outdated data.
How to set up the bot?
- List your products that need monitoring.
- Select competitor sites we'll scrape.
- Configure frequency and alert thresholds.
- Receive Telegram reports and start optimizing.
Typical mistakes and how to avoid them
- Overly specific price selector — breaks when the class changes. Use heuristics with fallback.
- No rate limit handling — bot gets blocked. Set delays and proxy rotation.
- Ignoring JavaScript rendering — data not retrieved. Add Playwright for such sites.
- Too infrequent checks — miss short-term promotions. Configure individual frequency.
- Choosing a ready-made script without ongoing support — stops working after selector changes. Our bot adapts thanks to the fallback parser.
We guarantee stable operation and data accuracy. Get a free project estimate — leave a request on our website.







