The parser ran clean on my laptop for a week. Deployed, it kept running clean, and quietly wrote prices into the catalog that were wrong by a factor I didn't catch for two days.
Nothing crashed. The selectors matched. The numbers were numbers.
What changed was who the request looked like. From my machine the retailer served one page variant. From the production egress it served another: different markup in places, and a price field formatted for a different locale, with the currency sitting in an element I never parsed because on my machine it wasn't there.
So the pipeline ingested plausible values. Plausible is the dangerous category: a malformed price throws, and a plausible one ships to customers and into every downstream margin calculation. The hour it took to fix was the cheap part. Reprocessing a catalog cost more, and so did not knowing, for a while, how far the bad values had travelled.
What I do differently now on anything that scrapes: the parser asserts on the contract, not just the selector. Currency explicit or reject. Expected ranges per category. Plus a small canary set of known items that the pipeline rechecks on every run, and if those drift the run stops instead of writing.
The local environment lies most when it sits on a friendlier network than production.
I've written up more of these failure modes from payments and catalog work on my blog, if that's useful: https://polycratia.com/c/8d5d683b
If you run scrapers at scale, you either validate parsed output against a known baseline or you hear about it from the people downstream.