Scraping Central is reader-supported. When you buy through links on our site, we may earn an affiliate commission.

Tutorial

Building a Price Monitoring Service with Web Scraping

Learn how to build a price monitoring and tracking service using web scraping. Covers architecture, alerts, dashboards, and monetization.

Price monitoring is one of the most commercially viable applications of web scraping. E-commerce businesses, retailers, and resellers all need to track competitor prices. Here is how to build a price monitoring service.

Core Architecture

Scheduler → Scraping Queue → ScraperAPI → Parser → Database → Alert Engine → Dashboard
  (cron)      (Redis/SQS)                                        (Email/Slack)

Step 1: Price Scraper

import requests
from bs4 import BeautifulSoup
import re
from datetime import datetime

SCRAPERAPI_KEY = "YOUR_SCRAPERAPI_KEY"

def scrape_price(url):
    """Scrape the current price from a product URL."""
    response = requests.get(
        "http://api.scraperapi.com",
        params={"api_key": SCRAPERAPI_KEY, "url": url}
    )

    soup = BeautifulSoup(response.text, "html.parser")

    # Try JSON-LD first (most reliable)
    import json
    ld_script = soup.find("script", type="application/ld+json")
    if ld_script:
        try:
            data = json.loads(ld_script.string)
            if "offers" in data:
                offers = data["offers"]
                if isinstance(offers, list):
                    offers = offers[0]
                return {
                    "price": float(offers.get("price", 0)),
                    "currency": offers.get("priceCurrency", "USD"),
                    "availability": offers.get("availability", ""),
                    "scraped_at": datetime.utcnow().isoformat()
                }
        except (json.JSONDecodeError, ValueError):
            pass

    # Fallback: look for common price patterns
    price_patterns = [
        soup.find("meta", {"property": "product:price:amount"}),
        soup.find(attrs={"data-price": True}),
        soup.find(class_=re.compile(r"price", re.I))
    ]

    for element in price_patterns:
        if element:
            price_text = element.get("content") or element.get("data-price") or element.get_text()
            price_match = re.search(r"[\d,.]+", price_text)
            if price_match:
                return {
                    "price": float(price_match.group().replace(",", "")),
                    "currency": "USD",
                    "scraped_at": datetime.utcnow().isoformat()
                }

    return None

Step 2: Price Database

import sqlite3

def init_db():
    conn = sqlite3.connect("prices.db")
    conn.execute("""
        CREATE TABLE IF NOT EXISTS price_history (
            id INTEGER PRIMARY KEY,
            product_url TEXT,
            product_name TEXT,
            price REAL,
            currency TEXT,
            scraped_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    """)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS alerts (
            id INTEGER PRIMARY KEY,
            product_url TEXT,
            alert_type TEXT,
            threshold REAL,
            email TEXT,
            active BOOLEAN DEFAULT 1
        )
    """)
    return conn

def save_price(conn, url, name, price, currency):
    conn.execute(
        "INSERT INTO price_history (product_url, product_name, price, currency) VALUES (?, ?, ?, ?)",
        (url, name, price, currency)
    )
    conn.commit()

Step 3: Alert System

def check_price_alerts(conn, url, current_price):
    """Check if any alert thresholds have been triggered."""
    alerts = conn.execute(
        "SELECT * FROM alerts WHERE product_url = ? AND active = 1",
        (url,)
    ).fetchall()

    for alert in alerts:
        alert_type = alert[2]
        threshold = alert[3]
        email = alert[4]

        triggered = False
        if alert_type == "below" and current_price < threshold:
            triggered = True
            message = f"Price dropped to {current_price} (below {threshold})"
        elif alert_type == "change":
            # Get previous price
            prev = conn.execute(
                "SELECT price FROM price_history WHERE product_url = ? ORDER BY scraped_at DESC LIMIT 1 OFFSET 1",
                (url,)
            ).fetchone()
            if prev:
                change_pct = abs(current_price - prev[0]) / prev[0] * 100
                if change_pct > threshold:
                    triggered = True
                    message = f"Price changed by {change_pct:.1f}%"

        if triggered:
            send_alert(email, message)

Monetization

Price monitoring services typically charge:

  • $29-99/month for small businesses (50-500 products)
  • $199-499/month for mid-market (500-5,000 products)
  • $999+/month for enterprise (unlimited products, API access, custom integrations)

The key differentiator is data accuracy and speed of detection. Using ScraperAPI ensures reliable scraping across protected e-commerce sites, which is critical for a monitoring service customers depend on.