Not marketing. Engineering.

Why Plainscrape?

Five honest answers about why this exists and how it actually works.

Why selectors fail

A CSS selector like div.grid__x9 > h4.ttl is a bet that a website's internal structure will never change. It's a bad bet. Class names are minified per deploy, A/B tests swap layouts per visitor, and frameworks re-render the same content into different DOM shapes. The selector isn't describing the data you want — it's describing an accident of how the page was built this week.

Every scraping team eventually maintains a graveyard of selectors, each one a small pager waiting to go off.

Why HTML changes don't have to matter

Here's the thing selectors miss: when a site redesigns, the meaning of the page almost never changes. A product still has a name, a price, a rating. Only the markup moved. Plainscrape anchors extraction to meaning — "the product's price" — so a Tuesday redesign changes nothing about your Tuesday dataset.

We extract what the page says, not where the page says it.

Why LLMs help — and where they don't

Language models are genuinely good at one thing scrapers were always bad at: reading a page the way a person does. That's what makes "every product under $50 with rating above 4.5" a valid program.

But running an LLM on every page of every crawl would be slow, expensive, and occasionally creative in ways data pipelines can't tolerate. So Plainscrape uses the model to understand the structure once, derives a deterministic extraction template from that understanding, and reuses it across thousands of similar pages at near-zero marginal cost. The model escalates back in only when a page breaks the pattern. You get language-level flexibility with pipeline-level determinism — and when a field genuinely isn't on the page, you get NOT_FOUND, never a plausible hallucination.

Why refinement works

Nobody specifies an extraction perfectly on the first try — not humans, not agents. Everywhere else, "oh, I also need the SKU" means re-crawling the whole site and paying for it twice.

Plainscrape keeps what it already extracted: the cleaned page content, the derived structure, the dataset. A follow-up instruction — "also include the SKU; split price into amount and currency" — runs against that memory, not against the web. The dataset updates in place, pages_used: 0. That's not a UX flourish; it's a different architecture, and it's why iteration costs a fraction of a cent instead of a second crawl.

Why pricing is transparent

Credit systems exist because per-page costs vary — JavaScript rendering costs more than static HTML, residential proxies cost more than datacenter. The industry's answer was multipliers: a "1 credit" page becomes 5, 9, or 25 credits once you enable the features you actually need. You find out at the end of the month.

Our answer is to do the engineering instead: smart rendering skips the browser on static pages, templates skip the model on repeat structures, and the savings fund a flat promise — 1 page = 1 page, everything included, failed pages free. And because we're confident in the math, every API response tells you exactly what it cost: "cost_usd": 0.079. If a pricing model can't survive being printed on every response, it's the wrong pricing model.

The honest summary

No single piece here is magic. Language-based extraction exists. Cheap crawling exists. What we think is worth building is the combination: natural language in, structured data out, conversational refinement in between, transparent cost throughout, and an API shaped for the agents that are about to do most of the world's extracting.

If that combination sounds like the tool you were about to build internally — that's exactly the point.

Convinced? Skeptical? Either way, try it.

Open the playground

No signup · the benchmarks page shows our receipts