Shopify Store Scraper — Products, Prices & Inventory
Pricing
from $2.50 / 1,000 results
Shopify Store Scraper — Products, Prices & Inventory
Extract full product catalogs from any Shopify store: titles, prices, variants, SKUs, inventory, images. Fast JSON-endpoint extraction with automatic fallback.
Pricing
from $2.50 / 1,000 results
Rating
0.0
(0)
Developer
Rushi Patel
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
16 hours ago
Last modified
Categories
Share
Extract the full product catalog from any Shopify store — titles, prices, variants, SKUs, availability, images, tags, and more — with one clean dataset record per product, plus a per-store summary saved to the run's key-value store (so you're only charged for actual product records).
This is a fast, reliable Shopify scraper built for product data extraction at scale: point it at a store URL and get structured product data back. By default it uses Shopify's public JSON endpoints (no browser, no fuss), with an automatic multi-layer fallback so you keep getting data even when the easy path is closed.
Sample output (real data)
Below is genuine data captured from live runs against deathwishcoffee.com and mejuri.com:
| Store | Title | Type | Price (min–max) | Currency | Variants | Images |
|---|---|---|---|---|---|---|
| Death Wish Coffee | Allfather's Aloha Button Up | Apparel | $40.00 | USD | 6 | 5 |
| Mejuri | (jewelry product) | Jewelry | $98–$398 | CAD | 1 | 5 |
One product record (trimmed):
{"storeName": "Death Wish Coffee","productId": 7492694540343,"title": "Allfather's Aloha Button Up","vendor": "BAMKO","productType": "Apparel","priceMin": 40, "priceMax": 40, "currency": "USD","tags": ["Apparel", "Men", "Merch"],"variants": [{"id": 42323014910007, "title": "S", "sku": "USHVJA02", "price": 40, "compareAtPrice": null, "available": false, "options": {"Size": "S"}}],"images": [{"src": "https://cdn.shopify.com/s/files/.../Front_Web2.jpg", "alt": null}],"url": "https://www.deathwishcoffee.com/products/allfathers-aloha-button-up-sold-out"}
And the per-store summary (saved to the run's key-value store under STORE_SUMMARIES, so it isn't billed as a result):
{"recordType":"store_summary","storeName":"Death Wish Coffee","productCount":291,"collectionCount":124,"priceRange":{"min":11.99,"max":40,"currency":"USD"},"currency":"USD","vendorList":["BAMKO"],"extractionPath":"products_json","status":"success"}
Why this scraper — 3-layer reliability fallback
Most tools break the moment a store changes its configuration. When you scrape a Shopify store with this actor, it works down a chain of extraction strategies so you keep getting complete data:
- Primary — public
products.jsonendpoint. Fast, structured, page-based pagination, no browser required. This is the default path for most stores. - Fallback — sitemap parsing. If
products.jsonis disabled, the actor parsessitemap.xmlto discover product URLs, then extracts per-product JSON / JSON-LD. - Last resort — opt-in headless browser (
useBrowser). For stores behind aggressive bot protection. This uses roughly 10x the compute and is off by default — you turn it on only when you need it.
Built to fail loudly, never silently:
- Shopify detection first. The actor confirms a URL is actually a Shopify store before doing anything else, and fails fast with a clear, actionable message if it isn't — it never silently returns garbage.
- Password-protected / pre-launch stores are detected and reported, so you always know why a store returned no products.
- Transparent extraction path. Every store's summary records exactly which path was used (
extractionPath), so you can audit how each result was obtained.
Completeness
One record per product with the fields you actually need for shopify price monitoring and ecommerce scraper workflows: full variant breakdowns, SKUs, availability, compare-at pricing, images with alt text, tags, vendor, product type, and timestamps — plus a store-level summary for the whole catalog.
Transparent, per-result pricing
Flat pay-per-result pricing you can predict before you press Start. No monthly rental, no surprise platform-usage bills. See Pricing.
Input
Fill in only storeUrls and you'll get the full catalog with sensible defaults.
| Field | Type | Default | Description |
|---|---|---|---|
storeUrls | array of strings | — (required) | Shopify store root URLs, e.g. https://www.allbirds.com |
scope | enum: all_products | collections | single_products | all_products | What to extract |
collectionHandles | array | optional | Used with scope=collections; empty = all collections |
productUrls | array | optional | Used with scope=single_products |
includeVariants | boolean | true | Include per-variant data |
includeImages | boolean | true | Include product images |
maxProductsPerStore | integer | 0 (unlimited) | Cap products per store |
useBrowser | boolean | false | Opt-in headless browser for stores behind aggressive bot protection (~10x compute) |
useResidentialProxy | boolean | false | Route requests through residential proxy |
Output
One dataset record per product. A per-store store_summary is saved to the run's key-value store (STORE_SUMMARIES) — you're only charged for product records, not summaries.
Per-product record:
storeUrl, storeName, productId, handle, title, description (plain text, HTML stripped), vendor, productType, tags[], createdAt, updatedAt, publishedAt, priceMin, priceMax, currency, totalInventory (usually null — public endpoints rarely expose inventory), variants[] {id, title, sku, price, compareAtPrice, available, inventoryQuantity, options}, images[] {src, alt}, url, scrapedAt.
Currency is reported as-is and never converted.
Per-store summary (key-value store, key STORE_SUMMARIES):
{"recordType": "store_summary","storeUrl": "...","storeName": "...","productCount": 291,"collectionCount": 124,"priceRange": { "min": 11.99, "max": 40, "currency": "USD" },"currency": "USD","vendorList": ["BAMKO"],"extractionPath": "products_json","status": "success","scrapedAt": "..."}
Quickstart
- Paste one or more store URLs into
storeUrls. - Click Start.
- Get one row per product; the per-store summary is in the run's key-value store.
Minimal input:
{ "storeUrls": ["https://www.allbirds.com"] }
That's it — filling only storeUrls produces the full product catalog with defaults applied.
Scheduling recipe — monitor competitor prices weekly
Turn this into a hands-off shopify price monitoring pipeline:
- Add your competitors' store URLs to
storeUrls. - Create an Apify Schedule that runs this actor every Monday.
- Between runs, diff
priceMin/priceMaxperproductIdto catch price changes.
Wire it into your stack with Apify Schedules + integrations — for example, a webhook that pushes changes to Slack or appends new rows to Google Sheets — so price movements land where your team already works.
Pricing
Pay-per-result: $2.50 per 1,000 products.
Transparent, flat, and predictable — no monthly rental and no surprise platform-usage bills. You know your cost before you run.
The value here is reliability + predictable pricing: the 3-layer fallback keeps results flowing, and the per-result model means you pay for products, not for platform time. (Browser mode is more compute-intensive and is opt-in — it's off unless you enable useBrowser.)
FAQ
"It says my store isn't Shopify."
The actor detects whether a URL is actually a Shopify store before extracting, and fails fast with a clear message if it can't confirm one. If you're certain the site is Shopify but it's behind bot protection, enable useResidentialProxy and/or useBrowser and try again.
What happens with password-protected or pre-launch stores? They're detected and reported in the store summary. You'll get a clear status explaining why no products were returned, rather than an empty result with no explanation.
Why is totalInventory (and often inventoryQuantity) null?
Public Shopify endpoints rarely expose inventory figures, so these fields are usually null. This reflects what the store makes publicly available.
How is non-USD currency handled?
Currency is reported exactly as the store lists it (e.g. CAD for Mejuri) and is never converted. Handle any conversion downstream if you need a single currency.
Can it handle very large stores?
Yes. Results are streamed per page as they're extracted. Use maxProductsPerStore to cap how many products you pull from each store when you don't need the whole catalog.
Can I scrape a specific collection?
Yes. Set scope=collections and list the collection handles in collectionHandles. Leave collectionHandles empty to scrape all collections.
How do pagination and de-duplication work?
The primary path uses page-based pagination against products.json. Products are de-duplicated by productId per store, so you get one clean record per product even across paginated pages.
Do I need to enable the browser?
No — the browser is opt-in. Most stores are handled by the fast public-JSON and sitemap paths. Only enable useBrowser for stores behind aggressive bot protection, and expect roughly 10x the compute cost when you do.
Keywords
Shopify scraper · Shopify product scraper · scrape Shopify store · Shopify price monitoring · ecommerce scraper · product data extraction.