Skip to main content

Script to monitor website changes — or skip the script

If you're Googling 'python script to monitor website changes' or 'node monitor webpage', you already know the shape: fetch a URL, hash it, compare to last run, alert on change. This page shows you the short version in both languages — and then shows you the managed webhook alternative that replaces the script in production.

The script below works for about a week. Then a CSS class changes, the laptop sleeps, the cron job dies silently, the Slack webhook URL gets rotated, and nobody knows the monitor stopped firing. DiffHook is the version where somebody else owns the infrastructure, the webhook is HMAC-signed, and the delivery log survives a laptop reboot.

Python

Python script to monitor a website

A dozen lines of Python is enough to poll a page, hash the response, and detect a change. The 'then what' part is where real scripts grow — retries, deduplication, signed delivery, logs.

monitor.py
import hashlib, time, urllib.request

URL = "https://example.com/pricing"
last = None
while True:
    html = urllib.request.urlopen(URL).read()
    h = hashlib.sha256(html).hexdigest()
    if last and h != last:
        print("changed")  # then… what?
    last = h
    time.sleep(300)

This works for a single page during a demo. For anything production, you'll want: timeouts, a User-Agent header, error handling, a database (or at least a file) to store the last hash, and a delivery layer that doesn't crash the script.

Node

Or: POST a monitor to DiffHook

The equivalent in Node — except instead of maintaining the polling loop, this creates a managed monitor that runs in DiffHook's infrastructure and fires a webhook on change.

monitor.ts
await fetch("https://api.diffhook.com/v1/monitors", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    type: "page",
    url: "https://example.com/pricing",
    interval_seconds: 300,
    deliveries: [{ type: "webhook", url: hookUrl }],
  }),
})

No cron, no VPS, no 'did my laptop sleep?' The webhook is signed with HMAC-SHA256 and retried on failure. Delivery logs are queryable via the API so you can prove a change was shipped.

Why replace the script

What a managed monitor actually buys you

There's a reason nobody leaves their Python polling script in production. These six are the failure modes that turn into weekend pages.

No silent failures

When DiffHook's monitor can't fetch a page, you get a notification — not a quiet cron job that's been misfiring for three weeks.

Signed webhooks

Every delivery carries an HMAC-SHA256 signature header so your receiver can verify the POST came from DiffHook and hasn't been tampered with.

Retries built-in

Failed deliveries retry with exponential backoff. A flaky receiver doesn't cost you events.

Diff history

Past changes are stored and replayable. Your script would need a database — DiffHook ships the history as part of the product.

JS rendering

Client-rendered pages, SPAs and dashboards work out of the box. Headless Chromium is managed for you — no Playwright install to maintain.

Team access

Teammates can view monitors, pause them, inspect delivery logs. Your shell script on one laptop doesn't do that.

FAQ

Scripts vs managed monitors

Should I write my own script instead of using DiffHook?
For a throwaway one-off or a personal hobby monitor, a script is fine and DiffHook is overkill. The day you need it to survive a laptop restart, verify authenticity on the receiver, handle retries, or give a teammate access — that's the day the script stops paying for itself.
Can I keep my script and just use DiffHook for delivery?
Yes. Some teams keep a custom scraper (for a gnarly login flow, say) and POST the diff to a DiffHook webhook endpoint that then signs and fans out the delivery. DiffHook's incoming webhook API accepts arbitrary payloads and you keep the delivery guarantees.
Does DiffHook work for JSON API monitoring too?
Yes. DiffHook has a native JSON API monitor type — point at an endpoint, provide a JSONPath, and get a webhook when the value changes. You can replace the Python/Node polling loop for JSON the same way.
What does the DiffHook webhook payload look like?
Every change fires a JSON POST with: event type (page.changed, json.changed, rss.new_item), monitor ID, target URL, timestamp, before/after snapshots or diff, and delivery metadata. All payloads are HMAC-SHA256 signed — you can verify authenticity in six lines of code.

Related

Related resources

Retire the polling script

3 free monitors, HMAC-signed webhooks, delivery logs you can replay, full REST API. No credit card required.