css_extractor.
Uses: Extract (extract=auto), Fetch with css_extractor, Batch scheduled jobs
How it works
- Extract or Fetch reads each price. Prepared retailers go through
extract=auto, which returns the product and its pricing as JSON. Other stores go through Fetch withmode=autoand acss_extractorthat names the title and price elements. - SQLite stores the history. Every check adds one row per product: URL, name, price and time.
- Your code detects drops. Each new price is compared with the last stored one. A lower price triggers an alert.
- The alert goes out. The script posts to a Slack incoming webhook when
SLACK_WEBHOOK_URLis set, and prints to the console otherwise. - A schedule runs it daily. Run the script from cron, or let Zenrows run the requests as a scheduled Batch job and read the results.
Ask your AI agent
With the Zenrows MCP server connected to Claude, Cursor or any MCP client, paste this prompt. Your agent picks the right Zenrows tools and settings on its own.Read one price
Try the request on its own first. On a prepared retailer,extract=auto returns the product in parsed.product and its prices in parsed.pricing. proxy_country=us shows the prices a US shopper sees:
Response (trimmed)
GET https://api.zenrows.com/v1/extract/domains lists every domain Extract covers. To add a new one, see Extract endpoints.
Run the monitor
Save this asmonitor.py, set your key, and run python monitor.py. Each run checks every product, stores the prices in prices.db and alerts on drops.
Python (Requests)
Run it every day
With cron. Run the script on your own server once a day, at 08:00:pip install zenrows), save this as batch_monitor.py next to monitor.py, and run python batch_monitor.py schedule once:
Python (SDK)
python batch_monitor.py check <job-id>. A check after setting the tee’s stored price to 30.00 to simulate a drop:
check from your webhook handler, see Batch webhooks.
Example output
Output ofmonitor.py. The first run stores a baseline for each product:
prices.db (sqlite3 prices.db "SELECT name, price, checked_at FROM prices"):
Customize it
Troubleshooting
No price found today: the price element moved or the selector doesn’t match. Open the page, inspect the price, update thecss_extractor, and test it with one request.- A request returns
422: the page wasn’t retrieved. Keepmode=autoon store requests so Zenrows escalates to JavaScript rendering and premium proxies when a page needs them, see error codes. - The script stops with a timeout: set the HTTP client timeout to 180 seconds or more, as in the samples.
- Every run alerts on the same product: the store shows a different price per visitor or region. Pin the region with
proxy_country.
Related recipes
Detect changes on any page and get alerted
Watch any page or field, not only prices.
Turn a whole catalog into a structured dataset
Collect every product of a store to choose what to monitor.
Run a Batch job on a schedule
Every schedule option for Batch jobs.
Move an existing scraper to Zenrows
Keep your parser and swap the request layer.