DEV Community

Cizze R
Cizze R

Posted on

How to Monitor Website Changes Automatically (Visual Diff Tutorial)

How to Monitor Website Changes Automatically

I run a few websites and need to know immediately when something breaks. A CSS regression, a broken layout, a missing section. Manual checking doesn't scale, and text-based monitoring misses visual issues.

The {{screenshot-diff}} on Apify takes two screenshots and produces a pixel-level comparison with an overlay showing exactly what changed.

How It Works

Take a baseline screenshot of the correct state. Then take a current screenshot of the live page. The actor compares pixel by pixel and returns a diff image with changed pixels highlighted, plus a percentage telling you how much changed.

import requests, time

API_TOKEN = "YOUR_APIFY_TOKEN"

def capture_screenshot(url):
    resp = requests.post(
        "https://api.apify.com/v2/acts/weeknds~website-screenshot-api/runs",
        headers={"Authorization": f"Bearer {API_TOKEN}"},
        json={"url": url, "fullPage": True}
    )
    run_id = resp.json()["data"]["id"]
    time.sleep(15)
    items = requests.get(
        f"https://api.apify.com/v2/acts/weeknds~website-screenshot-api/runs/{run_id}/dataset/items",
        headers={"Authorization": f"Bearer {API_TOKEN}"}
    ).json()
    return items[0]["screenshotUrl"]

def compare_screenshots(baseline_url, current_url):
    resp = requests.post(
        "https://api.apify.com/v2/acts/weeknds~screenshot-comparison-tool/runs",
        headers={"Authorization": f"Bearer {API_TOKEN}"},
        json={
            "baselineImageUrl": baseline_url,
            "currentImageUrl": current_url,
            "threshold": 0.01
        }
    )
    run_id = resp.json()["data"]["id"]
    time.sleep(10)
    items = requests.get(
        f"https://api.apify.com/v2/acts/weeknds~screenshot-comparison-tool/runs/{run_id}/dataset/items",
        headers={"Authorization": f"Bearer {API_TOKEN}"}
    ).json()
    return items[0]

baseline = capture_screenshot("https://mysite.com")
current = capture_screenshot("https://mysite.com")
result = compare_screenshots(baseline, current)

print(f"Difference: {result['diffPercentage']:.2f}%")
print(f"Diff image: {result['diffImageUrl']}")

if result['diffPercentage'] > 5:
    send_alert("Website changed significantly!")
Enter fullscreen mode Exit fullscreen mode

Real Uses

Deployment Verification

After every deploy, diff staging against production. If anything changed more than 2%, the deploy gets flagged before customers notice.

def verify_deploy(staging_url, production_url):
    staging_shot = capture_screenshot(staging_url)
    prod_shot = capture_screenshot(production_url)
    result = compare_screenshots(prod_shot, staging_shot)

    if result['diffPercentage'] > 2.0:
        print(f"Regression: {result['diffPercentage']:.1f}% changed")
        print(f"Diff: {result['diffImageUrl']}")
        sys.exit(1)
    else:
        print(f"Clean: {result['diffPercentage']:.1f}%")
Enter fullscreen mode Exit fullscreen mode

Competitor Monitoring

Track when competitors update their landing pages. Screenshot their site daily, diff against yesterday. Silent changes become visible.

CI/CD Pipeline

Add visual regression testing to GitHub Actions. On every deployment, screenshot the live site and compare against the pre-deploy baseline. Block the deploy if visual changes exceed threshold.

What You Can Configure

baselineImageUrl and currentImageUrl are required — just point them at your screenshots.

threshold controls sensitivity. At 0.0, every single pixel difference counts. At 0.01, the actor ignores minor anti-aliasing artifacts that don't actually matter.

What It Costs

$0.005 per comparison. With the screenshot API at $0.003 per screenshot, a full compare costs about $0.011 — two screenshots plus one diff. Running 100 comparisons a day costs around $1.10. Way cheaper than any commercial visual regression service.

Top comments (0)