feat: pre-flight layout probe before crawling - #7
Merged
Conversation
- probe_layout: five structural checks (h1, specialty sections, metric headings, waiting-time table header, last-updated footer) plus an extractor end-to-end signal for structurally valid pages that yield no records — the subtlest drift - run_pipeline(preflight=True): scrapes one canary page per run and raises LayoutDriftError listing every failed assertion before any deep crawl; preflight=False preserves previous behaviour - CLI: --no-preflight flag; exit 2 with named failures on drift - Drifted-layout fixture proves the probe catches restructured pages; probe, pipeline and CLI paths all verified in the sandbox
With preflight on by default, run_pipeline scrapes a canary first; this test's empty FakeBackend has no canary page (strict scrape -> KeyError). The test isolates crawl behaviour, so opt out of preflight explicitly — preflight itself is covered by tests/test_preflight.py.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses the gap identified in the drift discussion: a site layout change previously surfaced only as a silently empty CSV after a full crawl. Now a canary probe runs before any crawl and aborts with named failures. Follows on from #6.
What's included
pipeline/preflight.pyprobe_layout(page) -> LayoutProbeResult— pure function running five structural checks against the load-bearing signals the extractor depends on:<h1>provider headingsection.specialtyblocksh4metric headingsPage last updated: DD/MM/YYYYfooterLayoutDriftError— carriesurl+failuresfor diagnosable aborts.pipeline/run.py—run_pipeline(..., preflight=True)(default): scrapes one canary page (first seed), probes it, and raisesLayoutDriftErrorbefore any crawl call is made.preflight=Falsepreserves the previous lenient behaviour.cli.py—--no-preflightflag; on drift the CLI prints each named failure and exits 2 — a distinct code so scheduled workflows can alert on drift specifically.tests/fixtures/trust_page_drifted.html— the same trust restructured (tables → divs, renamed headings, changed footer) proving the probe catches real drift.tests/test_preflight.py(12 tests) — probe pass/full-drift/partial-drift/end-to-end-signal/canary-must-be-data-bearing; pipeline abort-before-crawl (asserts zero crawl calls), golden pass-through, disabled-preflight behaviour; CLI flag, exit-2-on-drift with monkeypatched backend, and the full success path writing a CSV.Verification
Probe executed in the sandbox: good layout passes clean, fully drifted page yields all 5 named failures, partial drift (footer format) yields exactly 1. Extractor end-to-end signal confirmed both directions.
Design decisions to review
--no-preflightexists for debugging, not production.nhs-scraper-diff); scheduling alerts can key on it precisely.