Skip to main content

pagemon

Monitor web pages for changes from your terminal.

PyPI version Python versions License: MIT CI

Why pagemon?

  • CLI-first -- designed for developers who live in the terminal
  • Lightweight -- pure Python, no Docker, no browser engine, no background daemon
  • Smart diffing -- strips HTML noise (scripts, nav, timestamps) so you only see real content changes
  • CSS selectors -- watch a specific element instead of the whole page
  • Webhook notifications -- POST JSON to Slack, Discord, or any HTTP endpoint when something changes
  • Zero config -- works out of the box with sensible defaults and a local SQLite database

Features

  • Add, remove, and list monitored URLs
  • Check one or all targets for changes on demand
  • CSS selector support to monitor specific page elements
  • Colored unified diffs in the terminal (via Rich)
  • Snapshot history with content hashes
  • Smart noise filtering (whitespace, timestamps, dates)
  • Webhook notifications on change (Slack, Discord, custom)
  • JSON and CSV export
  • JSON output mode for scripting (--json)
  • Python API for programmatic use
  • SQLite storage -- single file, no server needed

Installation

pip install pagemon

Requires Python 3.10+.

Quick Start

Add a page to monitor:

$ pagemon add https://example.com/pricing --name "Pricing Page" --interval 60
Added: https://example.com/pricing
  Selector: -
  Interval: every 60m

Monitor a specific element with a CSS selector:

$ pagemon add https://example.com/status --name "Status" --selector "div.status-banner"
Added: https://example.com/status
  Selector: div.status-banner
  Interval: every 30m

Check all targets for changes:

$ pagemon check --all
  NEW      Pricing Page
  NEW      Status

After subsequent checks, changed pages show a diff:

$ pagemon check --all
  OK       Pricing Page
  CHANGED  Status
--- previous
+++ current
@@ -1,3 +1,3 @@
-All systems operational
+Degraded performance on API endpoints

List monitored pages:

$ pagemon ls
        Monitored Pages
┌────┬──────────────┬────────────────────┬──────────┐
│ ID │ Name / URL   │ Selector           │ Interval │
├────┼──────────────┼────────────────────┼──────────┤
│  1 │ Pricing Page │ -                  │      60m │
│  2 │ Status       │ div.status-banner  │      30m │
└────┴──────────────┴────────────────────┴──────────┘

View snapshot history:

$ pagemon history https://example.com/status --limit 5
           History: https://example.com/status
┌────┬─────────────────────┬──────────────┬────────┬───────┐
│ ID │ Timestamp           │ Hash         │ Status │  Size │
├────┼─────────────────────┼──────────────┼────────┼───────┤
│  3 │ 2026-03-29T14:30:00 │ a1b2c3d4e5f6 │    200 │   482 │
│  2 │ 2026-03-29T14:00:00 │ f6e5d4c3b2a1 │    200 │   471 │
│  1 │ 2026-03-29T13:30:00 │ 9e8d7c6b5a4f │    200 │   471 │
└────┴─────────────────────┴──────────────┴────────┴───────┘

CLI Reference

pagemon [OPTIONS] COMMAND [ARGS]

pagemon add URL

Add a URL to monitor.

Option Short Default Description
--name -n -- Friendly name for display
--selector -s -- CSS selector to watch a specific element
--interval -i 30 Check interval in minutes

pagemon rm URL

Remove a URL from monitoring.

pagemon ls

List all monitored URLs.

Option Description
--json Output as JSON

pagemon check [URL]

Check for changes. Checks a single URL, or all targets if no URL is given.

Option Short Description
--all -- Check all targets
--json -- Output as JSON
--webhook -w Webhook URL for notifications (or set PAGEMON_WEBHOOK)

pagemon diff URL

Show the latest diff between the two most recent snapshots for a URL.

pagemon history URL

Show snapshot history for a URL.

Option Short Default Description
--limit -l 10 Number of snapshots to show

pagemon export

Export all targets and their latest snapshots.

Option Default Description
--format json Output format: json or csv

pagemon --version

Print the installed version.

Python API

from pathlib import Path
from pagemon.core import PageMon

# Initialize with defaults (SQLite at ~/.pagemon/pagemon.db)
mon = PageMon()

# Or with custom settings
mon = PageMon(
    db_path=Path("/tmp/my-monitor.db"),
    webhook_url="https://hooks.slack.com/services/T.../B.../xxx",
    timeout=15.0,
)

# Add a target
target = mon.add(
    "https://example.com/pricing",
    name="Pricing",
    selector="div.pricing-table",
    interval=60,
)

# Check all targets
results = mon.check_all()
for result in results:
    print(f"{result.target.url}: {result.status.value}")
    if result.diff_text:
        print(result.diff_text)

# Check a single target
result = mon.check(target)

# Get snapshot history
snapshots = mon.get_history("https://example.com/pricing", limit=5)

# Get the latest diff
diff = mon.get_diff("https://example.com/pricing")

# List all targets
targets = mon.list_targets()

# Remove a target
mon.remove("https://example.com/pricing")

# Always close when done
mon.close()

Configuration

pagemon works with zero configuration. All settings can be overridden via environment variables or CLI options.

Variable CLI Option Default Description
PAGEMON_DB --db ~/.pagemon/pagemon.db Path to the SQLite database
PAGEMON_WEBHOOK --webhook / -w -- Webhook URL for POST notifications

The webhook sends a JSON payload on every detected change:

{
  "url": "https://example.com/status",
  "name": "Status",
  "status": "changed",
  "diff": "--- previous\n+++ current\n@@ ...",
  "timestamp": "2026-03-29T14:30:00.000000"
}

How It Works

pagemon follows a simple pipeline for each monitored URL:

Fetch --> Extract --> Diff --> Notify
  1. Fetch -- HTTP GET via httpx with configurable timeout and custom headers
  2. Extract -- HTML is parsed with BeautifulSoup; scripts, styles, nav, and footer elements are stripped. If a CSS selector is set, only matching elements are extracted
  3. Diff -- Content is hashed (SHA-256) for fast comparison. If the hash differs, a normalization pass filters out whitespace and timestamp noise. Only meaningful changes produce a unified diff
  4. Notify -- Changed results are sent to the configured webhook (or printed to the console)

All snapshots are stored in a local SQLite database for history and diffing.

Contributing

Contributions are welcome. To get started:

git clone https://github.com/Ltbltbltbltb/pagemon.git
cd pagemon
pip install -e ".[dev]"
pytest
ruff check src/ tests/

Please open an issue before submitting large changes.

License

MIT -- see LICENSE for details.

Metadata

Release files for pagemon 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pagemon 0.1.0
File Size Uploaded
pagemon-0.1.0.tar.gz 20.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pagemon 0.1.0
File Interpreter ABI Platform
pagemon-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.3 kB

Release files / pagemon-0.1.0.tar.gz

Download URL pagemon-0.1.0.tar.gz
Size 20.4 kB
Tags Source
SHA-256 checksum
How to use checksums
ceeac846f447091b75f3d2420e12ed270cb6742fad165712681ed591781629f9
BLAKE2b-256 checksum
How to use checksums
ccb931b064194b148d777c8a8465c44f8fc9d51bf338089fda20fcfec8cf531b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / pagemon-0.1.0-py3-none-any.whl

Download URL pagemon-0.1.0-py3-none-any.whl
Size 13.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2182b01d80aafde305fe8647332c8218ec33b0e0ac8b2329f94cff18b23f2ede
BLAKE2b-256 checksum
How to use checksums
9ef8cf7e9ef7475ce60226e80f4cc332b2c9c1708125418ab611de698a5e1fe1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page