Take offline snapshots of any website and restore them locally
Project description
snapshot — offline website snapshots
Take a fast offline copy of any public website, then serve it locally.
Install
One-liner (macOS / Linux / WSL):
curl -fsSL https://raw.githubusercontent.com/codingsushi79/Snapshot/main/install.sh | bash
One-liner (Windows PowerShell):
irm https://raw.githubusercontent.com/codingsushi79/Snapshot/main/install.ps1 | iex
Universal fallback (requires Python 3.10+):
python3 -m pip install --user git+https://github.com/codingsushi79/Snapshot.git
From PyPI (once published):
pip install web-snapshot-cli
Then run:
snapshot https://example.com ./mirror
Other install methods
# With pipx (recommended for CLI tools)
pipx install web-snapshot-cli
# or from git:
pipx install git+https://github.com/codingsushi79/Snapshot.git
# From a local clone
git clone https://github.com/codingsushi79/Snapshot.git
cd Snapshot
pip install -e .
Usage
Snapshot a single page
snapshot https://example.com ./mirror
Crawl an entire site
snapshot --crawl https://docs.example.com ./docs --max-pages 200 --depth 4
Save pages as Markdown
snapshot https://example.com ./mirror --lang md
Crawl with filters and politeness
snapshot --crawl --include '/docs/*' --exclude '/docs/drafts/*' \
--crawl-delay 1 --robots https://docs.example.com ./docs
Authenticated pages
snapshot --cookie session=abc123 --header "Authorization: Bearer TOKEN" \
https://app.example.com ./mirror
Sitemap-based crawl
snapshot --crawl --sitemap https://example.com ./mirror --max-pages 500
Resume an interrupted snapshot
snapshot --resume --crawl https://example.com ./mirror
Dry run (no writes)
snapshot --dry-run --verbose --crawl https://example.com ./mirror
Extra args (positional)
Any key=value pairs after the output directory are merged into options:
snapshot https://example.com ./mirror crawl=true max-pages=100 lang=html concurrency=32
Restore locally
snapshot -restore ./mirror
This starts a local HTTP server (default http://127.0.0.1:8080) and opens your browser.
snapshot -restore ./mirror --port 3000 --no-open
Options
| Flag | Description |
|---|---|
--crawl, -c |
Follow same-origin links and download all pages |
--lang, -l |
Output format: html (default) or md |
--max-pages |
Max pages when crawling (default: 50) |
--depth |
Max crawl depth (default: 3) |
--no-assets |
Skip CSS, JS, images, fonts |
--timeout |
HTTP timeout in seconds (default: 15) |
--concurrency |
Parallel downloads (default: 16) |
--same-origin / --no-same-origin |
Restrict crawl to same origin (default: on) |
--user-agent |
Custom User-Agent header |
--cookie |
Cookie as name=value (repeatable) |
--header |
Extra HTTP header (repeatable) |
--include |
Only fetch URLs matching glob (repeatable) |
--exclude |
Skip URLs matching glob (repeatable) |
--robots / --no-robots |
Respect robots.txt (default: on) |
--crawl-delay |
Seconds to wait after each request (default: 0) |
--sitemap |
Seed crawl from sitemap.xml |
--resume |
Skip pages/assets already saved |
--verbose, -v |
Detailed log output |
--dry-run |
Fetch without writing files |
-restore DIR |
Serve a saved snapshot from DIR |
--port |
Port for restore (default: 8080) |
--host |
Host for restore (default: 127.0.0.1) |
--no-open |
Don't open a browser on restore |
How it works
- snapshot fetches pages with async HTTP (httpx), rewrites links to local paths, and downloads linked assets in parallel.
- A
.snapshot.jsonmanifest is written to the output folder with metadata for restore. - snapshot -restore serves the saved files and maps
/back to the original root page.
Output layout
mirror/
.snapshot.json
example.com/
index.html
about/
index.html
_assets/
...
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file web_snapshot_cli-0.1.0.tar.gz.
File metadata
- Download URL: web_snapshot_cli-0.1.0.tar.gz
- Upload date:
- Size: 18.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77771e4a21cb10e7f3350be14626f5c5bb45833602db90314471f0d85579e6ff
|
|
| MD5 |
03dd6c9d27762b885da29cf8047c883d
|
|
| BLAKE2b-256 |
1bd108c5169d9d88337414ff008458130a4e7aef446ac934bf68c0542a6a3e2a
|
Provenance
The following attestation bundles were made for web_snapshot_cli-0.1.0.tar.gz:
Publisher:
publish.yml on codingsushi79/Snapshot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
web_snapshot_cli-0.1.0.tar.gz -
Subject digest:
77771e4a21cb10e7f3350be14626f5c5bb45833602db90314471f0d85579e6ff - Sigstore transparency entry: 2091649372
- Sigstore integration time:
-
Permalink:
codingsushi79/Snapshot@345a1718eb102ffab1a839963c627bcc51b4cda7 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/codingsushi79
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@345a1718eb102ffab1a839963c627bcc51b4cda7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file web_snapshot_cli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: web_snapshot_cli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cce883b231ba65f2594b78ad37ca7375e1a1cd2445953e3dd38481dc2aaab8d
|
|
| MD5 |
e97e6c40fc0afcaf28c86f83b40e139b
|
|
| BLAKE2b-256 |
87b9a9f09887396cc742a53bca665a1f67b57a592b4f29ed3e500a253ad7f90b
|
Provenance
The following attestation bundles were made for web_snapshot_cli-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on codingsushi79/Snapshot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
web_snapshot_cli-0.1.0-py3-none-any.whl -
Subject digest:
8cce883b231ba65f2594b78ad37ca7375e1a1cd2445953e3dd38481dc2aaab8d - Sigstore transparency entry: 2091649517
- Sigstore integration time:
-
Permalink:
codingsushi79/Snapshot@345a1718eb102ffab1a839963c627bcc51b4cda7 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/codingsushi79
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@345a1718eb102ffab1a839963c627bcc51b4cda7 -
Trigger Event:
release
-
Statement type: