Verified against Replit Agent · 2026-08-05
Build a scheduled scraper pipeline that's safe to run unattended for months
A Replit Agent brief for a scheduled scraping pipeline built to run unattended for months — idempotent upserts, per-item error isolation, and the raw response kept alongside the normalized result.
The prompt
Ready to copy — highlighted parts are example details you can swap.
Build a scheduled data pipeline that runs once every night at 2am UTC, pulls a public list of competitor product prices from 40 known product URLs, and stores clean, de-duplicated results in a database — built to run unattended for months, not just to work once when I watch it run manually.
PIPELINE STAGES
1. Fetch: pull from a public list of competitor product prices from 40 known product URLs. Respect a fixed 2-second delay between requests, and treat a 429 or 503 response as a signal to back off and retry the whole run later rather than hammering the source immediately — this is someone else's server, and a scraper with no delay between requests is the kind of thing that gets an IP blocked, which would break every future run, not just this one.
2. Parse: extract product name, current price, currency, and in-stock status from the raw response.
3. Normalize: clean and standardize the extracted fields — strip currency symbols and commas from price into a plain decimal, normalize in-stock text ("In Stock", "Available", "2 left") into a single boolean is_in_stock.
4. Store: write to a database, keyed so that re-running the pipeline against the same source data never creates duplicate rows — use a natural unique key from the source data itself (not an auto-incrementing ID that would happily insert the same logical record twice) with an upsert, not a plain insert.
RELIABILITY RULES
If one item in a batch fails to parse or fetch, log that specific failure with enough detail to debug later and continue processing the rest of the batch — one bad item must never abort the whole run and silently skip every item after it. Store the raw fetched response alongside the normalized result, not just the normalized version, so that if a normalization rule turns out to be wrong later, the pipeline can be corrected and re-run against the original raw data rather than needing to re-scrape from scratch. Add a run log table recording every pipeline run — start time, end time, items processed, items failed, and a short status — so I can see the actual history of runs without digging through console output.
SCHEDULING AND ALERTING
Set this up using Replit's Scheduled Deployments (or the closest equivalent — cron-style scheduling, not a script that only runs while I happen to have the workspace open) to run once every night at 2am UTC. If a run fails outright — the source is unreachable, an unexpected exception escapes the per-item error handling above — send a notification to an email to me via a simple SMTP send, since this doesn't warrant a full Slack integration for one person so I find out the same day, not the next time I happen to check manually and notice weeks of missing data.
CONSTRAINTS
Replit's managed Postgres database, with a raw_snapshots table and a separate normalized products_daily table Handle the source being temporarily unreachable (a timeout, a 503) as a retryable condition with backoff, distinct from a genuinely malformed response that indicates the source's structure changed and needs a human to look at the parser, not just retry.Customize
Optional — swap in your own details for the highlighted parts above.
Why this works
Replit's Scheduled Deployments — cron-style execution running independent of whether the workspace is open — is the actual capability this prompt is written around, and naming it explicitly, rather than "run this every night" with no mechanism specified, matters because the default, easiest-to-generate alternative is a script with a sleep loop running inside the interactive workspace. That approach stops the instant the workspace session ends or the Repl goes idle, which defeats the entire point of a job meant to run unattended for months; an unscoped prompt has no particular reason to prefer the platform's real scheduled-execution feature over the simpler-looking loop.
The upsert-on-natural-key requirement targets the single most common bug in scheduled scraping pipelines specifically. Because the whole point is to re-run repeatedly against a source that may or may not have changed since last time, a plain INSERT keyed only on an auto-incrementing ID will happily create a fresh duplicate row for the same real-world item every single run. This bug is invisible for a while — the pipeline "works" by every visible measure, running without errors — right up until someone queries the accumulated data three months later and finds each product appearing ninety times.
Storing the raw response alongside the normalized result addresses a specific and recoverable-versus-not distinction that matters a lot for a scraper meant to run unattended. Source websites change their markup or price-formatting conventions over time, and a normalization rule that was correct on day one can silently start producing wrong values — a price of "1,299" parsed as 1.299 after a formatting change upstream. Without the raw response retained, fixing that bug means the historical data is permanently wrong with no way to recover it; keeping the raw snapshot means a corrected normalization rule can simply be re-run against everything already collected.
Verified against
Replit Agent Replit Agent (chat-based build mode, with Scheduled Deployments) · 2026-08-05
Changelog
- 2026-08-05 — Initial publish, verified against Replit Agent with cron-style Scheduled Deployments and a raw-plus-normalized storage split.
Need this built into your business?
If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.
EXPLORE CUSTOM SOFTWARE
