Selector-Scoped Content Change Monitor
Under maintenancePricing
$2.00 / 1,000 page checkeds
Selector-Scoped Content Change Monitor
Under maintenanceMonitor selected parts of public web pages: fetch HTML over HTTP, extract text or inner HTML by CSS selector, and report only selector-level changes after a quiet baseline.
Pricing
$2.00 / 1,000 page checkeds
Rating
0.0
(0)
Developer
kingii98
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
21 minutes ago
Last modified
Categories
Share
Monitor specific parts of public web pages and get notified only when they change. Given a set of page URLs and CSS selectors, the Actor fetches each page over plain HTTP, extracts the selected text or inner HTML deterministically, normalizes whitespace, stores a snapshot per monitorId in Apify key-value storage, and emits only selector-level changes — after a quiet first-run baseline.
This is a selector-scoped monitor, not a full-page differ: only the elements you name are extracted, hashed, and compared, and only changes are written to the dataset.
JavaScript-rendered content is not supported. Pages are fetched with plain HTTP requests only — no browser, no rendering. Content that appears only after JavaScript execution will be reported as selector-not-found (or missing/changed values).
What it detects
added— a selector matches now but did not match in the previous snapshot (or the page is new)removed— a selector matched in the previous snapshot but no longer matches (or the page was dropped from the input)changed— the extracted value's hash differs from the previous snapshotunchanged— reported only whenincludeUnchangedis enablederror— the page could not be fetched (DNS, TLS, timeout, too many redirects, redirect loop, or a redirect to a non-public address)
Page-level fetch, status, and redirect changes are surfaced through issueCodes on every selector record of the affected page: http-4xx, http-5xx, status-changed, redirect-changed, fetch-error, plus multiple-matches (selector matched more than one element; the first is used) and page-removed.
The first run of a monitorId is always a quiet baseline: it stores the snapshot and emits only the summary record, so you are not flooded with "added" records on day one.
Input
{"monitorId": "competitor-pricing","urls": ["https://example.com/pricing", "https://example.com/features"],"selectors": [{"name": "headline", "selector": "h1", "mode": "text"},{"name": "price-table", "selector": "#pricing table", "mode": "html"}],"maxPages": 100,"concurrency": 10,"timeoutSecs": 20,"maxRedirects": 5,"normalizeWhitespace": true,"includeUnchanged": false}
| Field | Description |
|---|---|
monitorId | Required. Stable monitor identifier (letters, numbers, _, -; max 64). Snapshots are stored per monitorId in a named key-value store (selector-content-<monitorId>); reuse the same ID across runs. |
urls | Public HTTP(S) page URLs, 1-1000 entries, normalized and deduplicated. Only the first maxPages are checked per run. |
selectors | 1-50 entries, each with a unique name, a CSS selector, and mode text (selected text) or html (inner HTML of the first match). Names must be unique; selector syntax is validated before any network work. |
maxPages | Cap on pages checked per run. Default 100; maximum 1,000. |
concurrency | Concurrent page fetches. Default 10; range 1-30. |
timeoutSecs | Per-request timeout. Default 20 seconds; range 2-60. |
maxRedirects | Maximum redirect hops followed per page. Default 5; range 0-10. Longer chains and loops fail the page with a fetch error. |
normalizeWhitespace | Collapse whitespace runs in extracted values to single spaces before hashing, so formatting-only changes are ignored. Enabled by default. |
includeUnchanged | Also emit records for selectors that did not change. Disabled by default. |
Invalid input (bad URLs, duplicate selector names, invalid CSS syntax, out-of-range caps) fails fast with a clear validation error before any network work.
Output
Every run writes one summary record plus one selector-result record per detected change to the default dataset.
Summary:
{"recordType": "summary","monitorId": "competitor-pricing","baseline": false,"checkedAt": "2026-08-07T09:15:00+00:00","pageCount": 2,"selectorCount": 2,"added": 0,"removed": 0,"changed": 1,"unchanged": 0,"errors": 0,"fetchErrors": 0}
Selector result:
{"recordType": "selector-result","monitorId": "competitor-pricing","baseline": false,"pageUrl": "https://example.com/pricing","selectorName": "headline","selector": "h1","mode": "text","changeType": "changed","previousValue": "Old price: $10","currentValue": "New price: $12","previousValueTruncated": false,"currentValueTruncated": false,"previousHash": "2c26b46b…","currentHash": "a665a459…","status": 200,"finalUrl": "https://example.com/pricing","redirects": [],"issueCodes": [],"checkedAt": "2026-08-07T09:15:00+00:00"}
Extracted values are capped at 100 KB per selector in the persisted snapshot; dataset record values are capped at a 10 KB preview (previousValueTruncated / currentValueTruncated flag truncation). Hashes are SHA-256 over the stored value, so change detection stays exact even when previews are truncated. Full page content is never written to the dataset.
Pricing
The Actor uses Apify pay-per-event pricing with the page-checked charge event. When monetization is enabled, users are charged $0.002 per page checked ($2 per 1,000 pages). One page-checked event corresponds to one page fetch including all of its selector extractions.
Apify platform usage (compute units and other resources consumed by the run) may still be shown to users according to their plan and Apify's pricing rules, as described in the Actor's listing.
The Actor respects the run's maximum total charge: if the remaining budget cannot cover every page, it checks only the chargeable prefix; if no page can be charged, it stops before any page checks.
Final pricing is configured in the Apify Store listing and may change subject to Apify's pricing-change notice rules.
Security and privacy
- Only public HTTP(S) targets are accepted.
- URL credentials, localhost, and non-public, loopback, link-local, multicast, unspecified, or reserved addresses are rejected.
- Every redirect target is resolved and validated before it is followed; a redirect to a private address fails that page with an error record instead of being fetched.
- URL counts, selector counts, concurrency, redirects, response bytes, extracted value sizes, and timeouts are all capped before or during network work.
- The Actor does not use a browser, proxy, LLM, external database, or third-party analytics service.
- Snapshots live in a named key-value store scoped to the
monitorId; dataset records live in the run's default dataset, subject to the retention and access settings of the Apify account running the Actor.
Do not place secrets, private URLs, or personal data in any input field.
Limitations
- JavaScript-rendered content is not supported: fetches use plain HTTP responses only, with no browser rendering. Selectors that only match client-rendered DOM will report as missing.
- If a selector matches multiple elements, the first match in document order is used and the record is flagged
multiple-matches. - The first run of each
monitorIdis a quiet baseline and reports no changes. - Network failures and rate limits are reported as per-page error records; they are not automatically retried indefinitely.
- The Actor does not send notifications itself. Use Apify schedules, webhooks, or an automation platform.
Support
For reproducible issues, open an issue from the Actor page and include the Apify run ID, sanitized input, expected result, and affected public URL. Do not include API tokens or private data.
This Actor monitors selector-scoped page content; it does not provide legal, security-audit, or uptime guarantees.