Page Change Monitor avatar

Page Change Monitor

Pricing

from $0.25 / 1,000 results

Go to Apify Store
Page Change Monitor

Page Change Monitor

Monitor web pages for content changes. Diffs each run against the previous snapshot and emits structured change records with added/removed lines — ideal for price, job, docs, and competitor monitoring.

Pricing

from $0.25 / 1,000 results

Rating

0.0

(0)

Developer

Cynix Dev

Cynix Dev

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Watch web pages for content changes and get structured change records with the actual added and removed lines. Diffs each run against the previous snapshot — for price, stock, docs, policy and competitor monitoring.

What it does

Give it URLs and it snapshots each page, then compares every later run against the stored snapshot and reports what changed. Records tell you unchanged, changed or first_snapshot, and when something changed you get a diff summary plus the added and removed lines themselves.

The hard part of change monitoring is false positives — rotating ads, timestamps, view counters and CSRF tokens make a page look different on every load. Three mechanisms deal with that: mainContentOnly strips navigation and chrome via readability extraction, cssSelector narrows the watch to one element, and ignoreRegex suppresses known-noisy patterns.

Features

  • Real diffs — added and removed lines, not just "something changed".
  • Noise suppressionmainContentOnly, cssSelector, and ignoreRegex to kill false positives.
  • Targeted alertingregexFilters fires only when the diff matches patterns you care about.
  • Isolated monitors — separate snapshotStoreName values keep independent watchlists apart.
  • Signed webhooks — POST change events with an HMAC-SHA256 X-Signature.
  • Event selection — fire on changed, first_snapshot or error.
  • Optional screenshots on change, stored in the key-value store.
  • Content hashingcontentHash and previousHash make change provable and auditable.

What people use it for

  • Price and stock monitoring — watch a product page's price element only.
  • Competitor tracking — get notified when a rival updates pricing, features or positioning.
  • Policy and compliance — detect edits to terms of service, privacy policies or regulations.
  • Documentation and API monitoring — catch breaking changes in a provider's docs.
  • Job and listing watch — spot new openings on a careers page with no feed.

Eliminating false positives

Most pages contain content that changes on every load. Work through these in order:

  1. Keep mainContentOnly on. Readability extraction drops nav, footers, sidebars and most ads.
  2. Narrow with cssSelector. Watching a price? .price or #product-price beats watching a whole page.
  3. Suppress the rest with ignoreRegex. Timestamps, view counts, "last updated" strings and session tokens are the usual culprits.
  4. Then filter positively with regexFilters if you only care about certain changes — for example \\$[0-9] to alert only when a dollar figure appears in the diff.

The first run is a baseline

There's nothing to compare against on the first run, so every URL comes back as first_snapshot. From the second run onward you get real diffs. If you want the baseline to fire a webhook too, include first_snapshot in webhookEvents.

Keeping monitors separate

Snapshots live in the store named by snapshotStoreName. Give each logical monitor its own name — otherwise two tasks watching different URL sets can trample each other's state.

Input

urls is required. mainContentOnly is on by default because it removes most false positives; add cssSelector when you want to watch one element precisely.

FieldTypeDefaultWhat it does
urls (required)array[{"url": "https://example.com"}]Public pages to watch for content changes.
cssSelectorstringWatch only the element matching this selector (e.g. '.price', '#content'). Leave empty for whole page.
mainContentOnlybooleantrueStrip navigation/ads via readability extraction before comparing. Reduces false positives.
includeDiffTextbooleantrueInclude the actual added/removed lines in change records.
maxDiffLinesinteger200Cap on added/removed lines stored per record. Range 1–5000.
snapshotStoreNamestringpage-change-monitor-snapshotsNamed key-value store holding previous snapshots. Use different names to keep separate monitors isolated.
regexFiltersarray[]Only trigger change alerts if the diff matches at least one of these regex patterns. Useful for filtering out noise (timestamps, counters, etc.).
ignoreRegexarray[]Suppress change alerts if the diff matches these patterns (e.g. timestamps, view counts, ads).
webhookUrlstringPOST change events to this URL. Payload includes the full change record.
webhookEventsarray["changed"]When to fire webhook: 'changed' (content changed), 'first_snapshot' (baseline), 'error' (fetch failed).
webhookSecretstringHMAC-SHA256 secret for verifying webhook payloads. If set, X-Signature header is included.
takeScreenshotbooleanfalseCapture a screenshot when a change is detected (stored in Apify key-value store). Requires Apify Proxy.
proxyConfigurationobjectsee belowApify Proxy configuration for screenshots and blocked sites.

Input example

{
"urls": [
{
"url": "https://example.com"
}
],
"mainContentOnly": true,
"includeDiffText": true,
"maxDiffLines": 200,
"snapshotStoreName": "page-change-monitor-snapshots",
"webhookEvents": [
"changed"
],
"takeScreenshot": false
}

Output

One record per URL per run. status is unchanged, changed or first_snapshot; diffSummary describes the change in words, with addedLines / removedLines carrying the detail.

Every dataset record contains: url, title, status, contentHash, checkedAt, previousHash, previousCheckedAt, addedLines, removedLines, diffSummary.

Output example

A real record from a run of this Actor:

{
"url": "https://example.com/",
"title": "Example Domain",
"status": "unchanged",
"contentHash": "a80242055d7489b4ce56b3193e7521cd92ef34fdc5b6aa666d7bef8cc29ccfd5",
"checkedAt": "2026-08-20T02:32:46.711Z",
"previousHash": "a80242055d7489b4ce56b3193e7521cd92ef34fdc5b6aa666d7bef8cc29ccfd5",
"previousCheckedAt": "2026-08-14T18:18:47.105Z",
"addedLines": null,
"removedLines": null,
"diffSummary": "No change."
}

Export the dataset as JSON, CSV, Excel, XML or JSONL from the Console, or pull it programmatically through the Apify API and any of the official clients.

How to use it

  1. Click Try for free (or Start if you already have an Apify account).
  2. Fill in the input fields described above — the defaults already produce a working run.
  3. Press Start and watch the log; results stream into the dataset as they are found.
  4. When the run finishes, open the Output/Storage tab and export as JSON, CSV or Excel.

Runs can be scheduled (hourly, daily, weekly) and wired into Slack, Google Sheets, Zapier, Make, webhooks or your own backend through Apify integrations. Everything the Console does is also available over the Apify API.

Proxy configuration

This Actor accepts a standard Apify proxy configuration object. Residential proxy is the default because the target site rate-limits datacenter IP ranges; you can select a specific exit country or supply your own proxy URLs.

{
"proxyConfiguration": {
"useApifyProxy": true,
"apifyProxyGroups": [
"RESIDENTIAL"
]
}
}

FAQ

How often should it run?

Match the page's real update rate: hourly for prices and stock, daily for docs and policies, weekly for slow-moving corporate pages. Runs where nothing changed are cheap.

Why does a page report changes every single run?

Something dynamic is inside the watched region — a timestamp, counter, rotating ad or CSRF token. Narrow with cssSelector and add the offending pattern to ignoreRegex.

Can I monitor pages behind a login?

Not in this version — it fetches pages anonymously. Public pages, including most pricing, docs and careers pages, work fine.

How do I verify webhook payloads?

Set webhookSecret and the request carries X-Signature, an HMAC-SHA256 of the body. Recompute it server-side with your secret and compare before trusting the payload.

What exactly does contentHash cover?

The extracted, normalised content actually being compared — after mainContentOnly and cssSelector are applied. That's why it's stable across cosmetic page noise.

Do screenshots cost extra?

They add runtime and storage, and require proxy configuration. Leave takeScreenshot off unless you need visual evidence of changes.

Other Actors by cynix_dev

ActorWhat it does
Website to RAG ChunksCrawl any website and turn its pages into clean, chunked, metadata-rich Markdown records ready for RAG pipelines, vector stores, …
Dataset Drift & QA MonitorStop finding out your scrapers broke three days late. Point this actor at any Apify dataset or JSON endpoint and it watches the …
OpenStreetMap GeocoderForward and reverse geocoding via the free Komoot Photon / OpenStreetMap service. No API key, no scraping, ODbL data.
News & Press Release MonitorWatch company newsrooms, blogs, and press pages and get one clean record per article — with new-item detection between runs, so a …
Dataset Drift & QA MonitorStop finding out your scrapers broke three days late. Point this actor at any Apify dataset or JSON endpoint and it watches the …

This Actor collects only publicly available information. You are responsible for how you use the data, including compliance with the target site's Terms of Service, robots directives, copyright, and data protection law such as GDPR and CCPA. Do not use it to gather personal data without a lawful basis.

Support and feedback

Found a bug, hit a site change, or need an extra field? Open a ticket on the Issues tab of this Actor — issues are read and fixed. Feature requests and custom-scraper enquiries are welcome through the same channel.