Skip to main content
Home
E-commerce · Price intelligence Pricewatch

Pricewatch: competitor price intelligence that runs every night

A scheduled collector reads public retailer pages under strict politeness rules, a tiered matcher pairs the same products across stores, and every morning there is a defensible comparison: an outreach-grade spreadsheet and a read-only dashboard.

Pricewatch: system architectureEvery night a scheduled collector visits public retailer product pages, obeying robots.txt with a jittered delay per host. A tiered matcher pairs the same product across retailers, a reviewer confirms the uncertain pairs, and every observation is kept in SQLite. The prospect artifact and the dashboard both read from that history; drift detection raises alerts when a site changes shape.Public sitesEvery nightWhat you getRetailer product pagesCollector (Playwright)Tiered matcher + reviewerSQLite: full historyProspect artifact (.xlsx)Dashboard + alertsrobots.txt + 2–3 s per hostThe path to followAutomatic data flowScheduled or async
Pricewatch: system architecture
165 products tracked
Collector stats, 2026-09-02
4 retailers, every night
Collector stats, 2026-09-02
Pattern: Claims only from matches we can defend

Challenge

Checking competitor prices by hand means someone opens the same product pages every morning, types numbers into a spreadsheet, and misses the day a rival undercuts a bestseller. It does not scale past a few dozen products, and the spreadsheet is stale the moment it is finished.

Approach

Pricewatch collects public product pages from a configured set of retailers every night, matches the same product across stores in tiers (exact barcode, then title and size, then a reviewer-confirmed pair), stores every observation with its history, and produces two outputs from the same data: a prospect-grade spreadsheet that only shows claims it can defend, and a dashboard with prices, changes, stock, and alerts.

Pricewatch is a demo Bravko built to answer one question a prospect always asks: what does the output actually look like? It runs every night against real public retail sites, so the answer is a real spreadsheet and a real dashboard, not a slide.

The problem. A team that sells online wants to know when a competitor moves. The manual version is a person opening the same forty product pages each morning, copying prices into a spreadsheet, and guessing at stock. It is slow, it is wrong by lunchtime, and it stops the moment that person is on holiday. The day a rival drops a bestseller by two pounds is the day nobody checked.

What we built. A configuration file lists a brand store and its competitors. Each night a collector visits their product pages, reads the structured data the pages already carry (JSON-LD first, the store platform’s own product endpoints for variant barcodes, a selector fallback last), and stores one observation per product per run with the full history kept. A tiered matcher then pairs the same product across stores: exact barcode sets first, then title plus size, then “closest” proposals that a reviewer accepts or rejects from the command line. Accepted pairs come back as confirmed matches on every later run; rejected pairs are never proposed again.

Two things read from that history. The artifact exporter writes an .xlsx with a Summary tab for outreach, which lists only claim-grade matches, headline counts, the brand’s own price, one short flag per competitor, and rows sorted by price gap, and a Data tab with everything including match confidence. The dashboard is a read-only page with prices, changes, stock, and alerts, and a stats strip computed live from the database.

The decisions that mattered. Product pages on the usual store platforms carry one barcode per variant, so a product stores the whole set and the exact tier matches on any overlap; without that, two stores’ pages for the same product rarely share the “first” barcode. A shared brand name is never enough for a match: after the brand tokens are stripped, two titles must still share a product-specific word, which removed a chain of junk matches on the first real run. Some stores strip their structured data from the page after it loads, so the collector reads the raw server response before the browser touches it. And uncertain matches never drive a claim: they appear in grey for context, get no cheaper or pricier flag, and are excluded from the prospect spreadsheet even inside rows that qualify through another competitor.

Politeness rules. robots.txt is fetched once per host with a descriptive user agent and obeyed; a disallowed page is skipped and recorded. Every two requests to the same host are separated by two to three seconds of jittered delay, and a larger crawl delay in robots.txt wins. Listing pages are paginated only while each new page adds a product not seen before. Sites that block bots, put a password on their catalogue, or serve wholesale prices were rejected during feasibility rather than worked around.

Drift detection. A run that extracts no product URLs from a listing, a product count that halves against the previous run, or a robots.txt that changes its answer all raise an alert on the dashboard. Automation that silently reports wrong numbers is worse than none, so the system says when it is unsure.

How it is built. Python 3.12 with Playwright for collection, SQLite with the complete observation history, FastAPI and Jinja for the dashboard (no JavaScript on the page), openpyxl for the artifact. It runs as a systemd timer on a small server, one process, with retries and backoff. 115 unit tests and one live smoke test cover it.

Where it stands. Pricewatch is running nightly against four retailers. The numbers on this page come from the collector’s own stats, updated automatically once the demo publishes them; nothing here is estimated.

Technologies

  • Python 3.12
  • Playwright
  • SQLite
  • FastAPI
  • Jinja
  • openpyxl
  • systemd

Tags

  • Browser Automation
  • Data Pipeline
  • Price Monitoring
  • Demo

Send us one manual process

Email us the most repetitive data job your team does. We will reply within one working day with how we would automate it, what it costs, and how long it takes. If it is not worth automating, we will tell you that too.

or write to info@bravko.com