E-commerce Product Scraper & JSON-LD Extractor
Pricing
Pay per usage
E-commerce Product Scraper & JSON-LD Extractor
Extract product prices, availability, images, identifiers and variants from public product pages. Discover URLs from store sitemaps, filter by data completeness, and export JSON or CSV. Free-plan sample: up to 25 pages per run.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Scopras Data Labs
Maintained by CommunityActor stats
0
Bookmarked
18
Total users
8
Monthly active users
16 days ago
Last modified
Categories
Share
Turns product pages into one clean row each — parsed prices, normalised stock status, variants, absolute image URLs — from any storefront, not just Shopify.
Give it product URLs, or give it a store's homepage and let it find them.
{"startUrls": [{ "url": "https://www.gymshark.com" }],"discoverProducts": true,"maxProducts": 10,"minCompleteness": 50}
Illustrative output shape (not a live product quote). Every field is flat — no nested objects or arrays — so the Console's CSV/Excel export button renders a clean table without opening a single item:
{"name": "Legacy Fitted T-Shirt","brand": "Gymshark","sku": "GSTS-4471","price": 32,"priceCurrency": "USD","availability": "InStock","inStock": true,"imageCount": 1,"primaryImage": "https://cdn.shopify.com/s/files/…/legacy-tee.jpg","imagesJson": "[\"https://cdn.shopify.com/s/files/…/legacy-tee.jpg\"]","variantCount": 2,"variantsJson": "[{\"name\":\"Legacy Tee — S\",\"sku\":\"GSTS-4471-S\",\"price\":32,\"availability\":\"InStock\"},{\"name\":\"Legacy Tee — M\",\"sku\":\"GSTS-4471-M\",\"price\":32,\"availability\":\"OutOfStock\"}]","source": "jsonld","completeness": 1,"missingFields": [],"ok": true}
price/priceCurrency— the price is always a clean number with the currency symbol and thousands/decimal formatting resolved, in a column separate from its ISO currency code (see "What the extractor handles" below for the locale-parsing rule).inStock— a plain boolean derived fromavailability(nullwhen the page gave no availability signal at all), for price monitors and feeds that just need yes/no rather than nine schema.org spellings.imageCount/primaryImage/imagesJsonandvariantCount/variantsJson— the genuinely nested parts of a product (multiple images, per-variant price/sku/stock) are summarised into flat columns (imageCount,variantCount,primaryImage) and the full detail is kept as a JSON string you canJSON.parse()back into an array on re-import, instead of a raw array that CSV/Excel would render unreadably.
Pricing and free-plan sample
The Pricing tab shows the current price. Unreachable pages and rows below your completeness filter are never charged.
Apify Free plans: up to 25 product pages per run. Paid plans can process larger batches within your configured limit and run budget. This is a per-run sample limit. The prefilled input now discovers 10 products from a store sitemap with a 50% completeness filter; replace the example store with your target.
To scrape individual product URLs, turn discovery off. To process a whole store, turn it on. Set a maximum total charge before starting a larger job.
What the extractor handles
Prices come out as numbers, in the right magnitude. "1.299,90" and
"1,299.90" are the same amount written by two halves of the world. Returning
the string hands you a problem you discover in row 40,000; guessing wrong makes
it a thousandfold error. Both are parsed, and anything genuinely unreadable —
"call for pricing" — comes back absent rather than as 0.
Variants are not lost. A ProductGroup keeps name and brand on the parent
and SKU, price and stock on each child. Read either node alone and you get half
a product. Both are read, and every variant is returned with its own row of
fields.
Non-English stores stay legible. Pages served as windows-1254 or ISO-8859-9
are decoded in the encoding the server declared, and HTML entities are resolved
with case respected — Ç is Ç, ç is ç. No mojibake, no
ü in your spreadsheet.
It works past the Shopify convention. Product URLs are found from the
store's own sitemap filing rather than guessed from the path, so flat-URL
stores work too — hisar.com.tr/hisar-16-parca-granit-ceyiz-seti has no /products/
segment anywhere and is found regardless.
Three sources, in the right order. JSON-LD first, then microdata, then
OpenGraph — and a fallback only ever fills a gap, never overwrites. Each row
tells you which sources it needed (source: "jsonld" | "mixed" | …).
Every row grades itself. completeness is the share of the seven fields
that matter — name, brand, identifier, price, currency, availability, image —
and missingFields names the ones that were absent. Set
Minimum completeness to drop thin rows, and you are never charged for them.
A name that is really a SKU gets fixed. Some stores publish
"name": "PCDP253G13IY". Where the page offers something better, you get the
real title.
Input
| Field | What it does |
|---|---|
startUrls | Product URLs, or store homepages when discovery is on |
discoverProducts | Find product pages from robots.txt and the sitemaps it declares |
maxProducts | Hard cap for the run |
minCompleteness | Drop rows below this percentage. Dropped rows are never charged |
includeVariants | Keep the per-variant array, or flatten to one row per product |
crawlerIdentity | Your own User-Agent. Whoever runs the scrape answers for the traffic |
Output
Two kinds of row, so a run is always auditable:
- Products —
ok: true, plus everything above. - Unreachable pages —
ok: falsewithurl,httpStatusanderror. Recorded so you can see them; never charged.
Politeness
Requests to one host are spaced out, bodies are capped, timeouts are hard, and
a 429 is honoured with a single backed-off retry. These are not configurable.
A scrape that gets your IP banned was not a bargain, and the stores being read
did not ask to be.
Limits, stated plainly
- Public pages only. URLs that point at localhost, private networks or non-http(s) schemes are refused.
- No JavaScript rendering. Products whose data is drawn client-side and
published in no markup at all will come back thin.
completenesswill say so rather than pretending otherwise. - Compressed sitemaps (
.xml.gz) are read like plain ones, with the same size cap after decompression. - Discovery depends on the store publishing a sitemap. Without one, only the homepage's own product links are found — the run says so explicitly when that happens, because 40 rows against a catalogue of 4,000 is a number you need to know the provenance of.
- At most 15 sitemap documents are read per store, and no more than 25 are requested. A store whose index lists hundreds of dead children will not spend your run collecting 404s.
- A run that reaches your maximum total charge stops there and says so in the log and the run's status. It does not keep fetching pages it cannot deliver — raise the budget and run it again for the rest.
Built on the engine behind Scopras, an audit tool that grades a store's product markup against what AI shopping agents need. Same extraction rules: this actor gives you the data, Scopras tells you what is wrong with it.
Build a recurring ecommerce workflow
Use XML Sitemap Scraper to inventory URLs, extract the product records here, then compare recurring datasets with Product Catalog Change Monitor. For public Shopify catalogs and variant snapshots, use Shopify Price Monitor.
You can save inputs as an Apify task and schedule recurring collection. Export the Output dataset as JSON, CSV or Excel, or connect it to your existing workflow through the API and integrations.
For support, open an issue with a run ID and public product URL. Do not post tokens or private customer information.
FAQ
Which stores does this product scraper work on? Any storefront that publishes product markup (JSON-LD, microdata or OpenGraph) in its HTML — Shopify, WooCommerce, Magento, BigCommerce and custom stores. Pages that draw products only with JavaScript come back thin, and the completeness score says so.
Can it find every product in a store? With discovery on, it reads the store's robots.txt and sitemaps to list product URLs, then extracts each one. Cap the run with Max products.
How much does it cost? See the Pricing tab. Unreachable pages and rows below your completeness filter are never charged.
How do I track price changes? Run it on a schedule and compare datasets with Product Catalog Change Monitor.
Is it legal? It reads publicly available pages only, with no login. You are responsible for respecting each site's terms and the privacy rules that apply to your use of the data.
Can I run it through the API or on a schedule? Yes. Save your input as a task, schedule it in Apify Console, or call it from the Apify API. Results export as JSON, CSV or Excel and connect to Google Sheets, Slack, Make, Zapier or a webhook.