A one‑off scrape is a weekend project. Running the same collection job every hour for three years is an infrastructure problem, and most teams underestimate how different those two things are. Continuous collection breaks in ways that batch jobs don't. Sites redesign their markup, rate limits tighten overnight, and the IP pool that worked in March gets flagged by June. The stack has to absorb all of it without a human watching the logs. Here's what the working parts look like when a pipeline actually holds up.
Every pipeline sits on a fleet of outbound connections, and that fleet is the first thing target sites push back against. Cloudflare, Akamai, and DataDome fingerprint traffic well past the IP address now: TLS handshake order, HTTP/2 frame settings, header casing, even mouse‑movement telemetry on the heavier defenses.
So the exit node matters less than it did five years ago. But it still matters. A single datacenter IP hammering a product catalog at 40 requests per second collects a 429 inside of two minutes, and repeat offenders get range‑banned rather than throttled.
Spread that same volume across a rotating residential pool and the pattern reads as ordinary browsing. For jobs that never stop, residential rotating proxies unlimited bandwidth tend to beat metered plans on cost, since per‑gigabyte pricing punishes exactly the workloads that run around the clock. A crawler pulling image‑heavy catalog pages can burn through 200 GB in a single week.
Teams reach for cron, then discover that overlapping runs corrupt state. Apache Airflow and Prefect exist because a scheduler needs to know what already ran, what failed, and what should never fire twice.
Idempotency is the rule that saves everyone. Every fetched page should carry a content hash and a fetch timestamp so a re‑run overwrites cleanly instead of duplicating rows. A Postgres upsert keyed on (url, fetched_date) handles this in roughly one line.
Backfills need their own lane. Mixing a 90‑day historical pull into the same queue as hourly collection starves the live jobs, and the freshest data (the entire reason the pipeline exists) arrives last.
And retries deserve a budget. Three attempts with exponential backoff catches genuine network flakiness; anything past that is usually a parser problem wearing a network problem's clothing.
Silent failure is the expensive kind. A parser that returns empty strings instead of prices won't throw an exception. It just fills the warehouse with nulls for six weeks until someone in finance notices the dashboard flatlined.
Four signals cover most of it: response‑size distribution, non‑200 rate per domain, parse‑success ratio per selector, and median time‑to‑first‑byte per exit region. Prometheus and Grafana handle this without much setup. Alert on ratios rather than raw counts, because raw counts move every time the crawl schedule changes.
Status codes deserve separate treatment in the retry logic. A429 response means back off and try later, while a 403 usually means the fingerprint got burned and retrying just wastes request budget.
Continuous collection carries obligations that one‑time research doesn't. TheRobots Exclusion Protocol became a formal IETF standard in 2022, which makes ignoring it considerably harder to explain later.
Case law around web scraping has drifted toward permitting collection of publicly accessible data, though hiQ v. LinkedIn ended in a settlement rather than a clean rule anyone can cite. Personal data brings GDPR into scope regardless of whether the page sat behind a login.
Sensible guardrails are boring: rate‑limit per domain instead of per proxy, honor crawl‑delay directives, cache hard enough that the same URL isn't fetched twice in an hour, and put a real contact address in the User‑Agent string.
Detection is moving from IP reputation toward session realism. Headless browser fingerprints, timing gaps between clicks, and scroll depth all get scored now, which means the request layer will keep needing replacement parts.
Teams building for the next few years should assume they'll swap that layer at least twice, and design parsing and storage so neither tier cares where the HTML came from. That separation is what keeps a pipeline alive through a site redesign instead of rebuilt from scratch every spring.