Start free
All posts
· Roger Massana · guide, comparison

JSON schema vs CSS selectors: two ways to scrape, compared

Both get data off a page. One couples you to the layout, the other to the meaning. Here's an honest comparison of when each one wins.


There are two fundamentally different ways to get structured data off a web page. You can point at where the data lives with a CSS selector, or you can describe what the data is with a schema and let extraction find it. Neither is universally better. They fail in different ways and shine in different situations, so it is worth understanding the trade.

The selector approach

You inspect the page, find the element, and write a path to it:

const price = document.querySelector(".product__price-now").textContent;

This is fast, free, and completely deterministic. It runs in milliseconds and there is no model in the loop to second-guess. As long as the page keeps that exact class on that exact element, it works forever.

The catch is in that “as long as.” Selectors are coupled to the page’s structure, and structure is the thing site owners change constantly. A redesign, an A/B test, a framework upgrade, or a single renamed class quietly breaks your scraper, and you find out from the gap in your data rather than from an error.

The schema approach

You describe the data and let extraction map the page onto it:

const { price } = await client.extract({
  url,
  schema: { price: z.number() },
});

This couples you to the meaning of the data, not its position. When the site moves the price into a new container, “the price” is still the price, so the extraction survives the redesign. You also get type guarantees for free: price comes back as a number, validated, or you get a clean null if it genuinely is not there.

The cost is that there is more machinery involved. A request renders the page and runs an extraction step, so it is slower and not free per call, and it is the right tool for data that matters, not for scraping a million trivial pages where pennies add up.

Side by side

CSS selectorsJSON schema
Couples toPage layoutData meaning
Survives redesignsNoYes
SpeedMillisecondsSeconds
Cost per pageFreePer request
Type safetyYou parse it yourselfValidated at the boundary
Best forOne stable page, fastMany pages, changing sites

How to choose

Reach for selectors when the page is stable, you control it or trust it not to change, and you need raw speed on high volume. Reach for a schema when you are extracting the same shape across many pages, the sites redesign on their own schedule, or you need typed, validated output you can drop straight into a database.

Most scraping jobs that cause ongoing pain are the second kind. That is the maintenance cost selectors hide until Wednesday.

Try it

See what describing the data instead of the DOM feels like. Run the live demo, or start free.


← All posts Start free with Extracto →