Shopify Store Scraper — Products, Prices & Inventory avatar

Shopify Store Scraper — Products, Prices & Inventory

Pricing

from $2.50 / 1,000 results

Go to Apify Store
Shopify Store Scraper — Products, Prices & Inventory

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

Rushi Patel

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

16 hours ago

Last modified

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:

StoreTitleTypePrice (min–max)CurrencyVariantsImages
Death Wish CoffeeAllfather's Aloha Button UpApparel$40.00USD65
Mejuri(jewelry product)Jewelry$98–$398CAD15

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:

  1. Primary — public products.json endpoint. Fast, structured, page-based pagination, no browser required. This is the default path for most stores.
  2. Fallback — sitemap parsing. If products.json is disabled, the actor parses sitemap.xml to discover product URLs, then extracts per-product JSON / JSON-LD.
  3. 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.

FieldTypeDefaultDescription
storeUrlsarray of strings— (required)Shopify store root URLs, e.g. https://www.allbirds.com
scopeenum: all_products | collections | single_productsall_productsWhat to extract
collectionHandlesarrayoptionalUsed with scope=collections; empty = all collections
productUrlsarrayoptionalUsed with scope=single_products
includeVariantsbooleantrueInclude per-variant data
includeImagesbooleantrueInclude product images
maxProductsPerStoreinteger0 (unlimited)Cap products per store
useBrowserbooleanfalseOpt-in headless browser for stores behind aggressive bot protection (~10x compute)
useResidentialProxybooleanfalseRoute 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

  1. Paste one or more store URLs into storeUrls.
  2. Click Start.
  3. 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:

  1. Add your competitors' store URLs to storeUrls.
  2. Create an Apify Schedule that runs this actor every Monday.
  3. Between runs, diff priceMin / priceMax per productId to 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.