Shipmind Labs

A scraper that returns nothing is not an empty catalog. It is an outage that reports success.

We have kept retail catalog parsers running for a cross-border e-commerce platform for years, and the failure mode is almost never a crash. The site ships a layout change, the price selector stops matching, and the request still comes back 200. The job finishes. The dashboard is green. Downstream, products quietly lose their price, or drop out of the catalog entirely, and the first person to notice is a customer or a support agent.

What fixed this for us was refusing to let a run write straight into the live catalog.

A run goes into a staging batch. The batch carries its own statistics: rows parsed, share of rows with a missing price, share with no image, count against the previous successful run for the same source. Promotion into production data is a separate step with rules attached, so a source that suddenly yields a fraction of its usual rows does not promote, it raises an alert and keeps yesterday's data.

The mental shift is small but it changes the whole design: parsing is not a write path, it is a proposal that has to pass review. Stale data is a known, bounded problem. Silently corrupted data is not.

If you run scrapers or third-party imports in production, you probably know the version of this that bit you: what signal actually told you a source had broken, and how long it took.

Was this useful?

Building something similar?

or email hello@shipmindlabs.com