No description
  • Python 61.7%
  • HTML 19.7%
  • CSS 14.5%
  • JavaScript 3.4%
  • Just 0.4%
  • Other 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-15 22:10:08 -04:00
alembic hooks: add webhook sink app recording deliveries to sqlite 2026-09-01 14:17:36 -04:00
docs templates: shared theme, dev bar and per-app site headers 2026-09-04 17:03:06 -04:00
scrapecraft things: template-routed extractors for the st-things bundle 2026-09-15 21:14:25 -04:00
src/scraper_tester things: Printshelf app and st-things multi-template bundle 2026-09-15 20:08:03 -04:00
tests things: Printshelf app and st-things multi-template bundle 2026-09-15 20:08:03 -04:00
.gitignore scaffold project 2026-06-20 15:13:32 -04:00
alembic.ini add request log model and alembic migrations 2026-06-20 15:22:25 -04:00
justfile sync: importer creates input sets and attaches them 2026-09-14 07:27:57 -04:00
pyproject.toml add request log model and alembic migrations 2026-06-20 15:22:25 -04:00
README.md docs: bundle format describes input sets 2026-09-14 07:28:27 -04:00
uv.lock add request log model and alembic migrations 2026-06-20 15:22:25 -04:00

scraper-tester

A local server of small test "websites" for developing and testing web scrapers — with a live admin dashboard showing exactly what your scraper sent, at what rate, and what it got back.

Quick start

uv sync
just run          # migrates the sqlite db, starts http://localhost:8900
                  # (:8900 because ScrapeCraft's API owns :8000; override
                  # with SCRAPER_TESTER_PORT)

Test apps

URL Tests
/profile/ Parsing page sections (lists, tables, spans) and downloading images
/search/ Form submission — direct GET or headless-browser click
/headers/ Header/proxy verification — echoes your request (HTML or ?format=json)
/shop/ Extraction mini-site: paginated listings (rel=next), A/B card layouts, detail pages, carousels for grouped extraction, JSON API, sitemap index + URL feed
/paginate/ Every next-link style (rel / text / class / id) plus a 60-page chain for depth caps
/trouble/ Failures & validation: statuses, flaky-then-recover, slow, oversize, empty, mislabeled content-type, redirect chains, marker phrases, a 429 rate limiter
/crawl/ Interlinked mini-wiki: keep/ tree with chains and cycles, skip/ for deny rules, robots-disallowed private/, dead links, external links, a 100-link page
/hooks/ Webhook sink — records every POST to /hooks/sink (headers, signature, body) for webhook-delivery verification
/js/ JS-only content: client-side/delayed rendering, load-more, infinite scroll, and an action gauntlet (type → Enter → select → hover → click_all → scroll → click)
/botwall/ Challenge page whose pass cookie only JS can mint, with a short server TTL — bot_trigger validation and the browser-warms-cookie-for-httpx session-refresh flow
/login/ Form + JS login (scraper / tester-pass-1337) guarding account pages — LoginConfig, session pools, generator warming with credentials

/robots.txt disallows /crawl/private/ and /trouble/ for robots-compliance scrapers (it's advisory — the server never blocks anything itself).

ScrapeCraft test scrapers

scrapecraft/ holds committed scraper/extractor/parser definitions that exercise these apps — one per ScrapeCraft feature. just sync-scrapers upserts them into a local ScrapeCraft instance, along with the input sets that hold each scraper's seed URLs; see scrapecraft/README.md.

All fake data is seeded (SCRAPER_TESTER_SEED, default 1337) — identical on every run, so scraper tests can assert exact values.

Admin — http://localhost:8000/admin/

  • Per-app request rates: live charts (req/s by status class, last 5 min), totals, and average response times — measured server-side, so you can verify your scraper's configured rate without trusting the scraper.
  • Live request log with full stored headers per request.
  • Clear data per app, or all of it, for fresh stats.

Commands

just run            # migrate + start dev server (reload on)
just test           # pytest
just lint           # ruff check + format check
just makemigration "msg"
just clean-db       # delete the sqlite db

Adding a test app

Copy src/scraper_tester/apps/_example/ and edit — no wiring needed. Full guide: docs/adding-an-app.md.