Shopify Store Scraper - Products, Prices, Theme & Apps
Pricing
from $1.00 / 1,000 results
Shopify Store Scraper - Products, Prices, Theme & Apps
Shopify store scraper: export every product, price, variant, SKU and stock flag from any public store, plus its theme, currency and apps. No login. Download JSON, CSV or Excel. From $1 per 1,000 results.
Pricing
from $1.00 / 1,000 results
Rating
0.0
(0)
Developer
Alexandre Manguis
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 days ago
Last modified
Categories
Share
Shopify Store Scraper – Products, Prices, Variants, Theme & Apps
What does it do?
This Shopify store scraper exports the full public product catalog of any Shopify store: titles, prices, compare-at prices, variants, SKUs, stock flags, images, tags and dates. It also detects the store's theme, currency and installed apps. Paste one or many store URLs and download the result as JSON, CSV, Excel or via API. It reads only what the store shows publicly (its /products.json catalog and homepage). No login is used and no emails or contact details are collected.
Who is it for / use cases
- Price monitoring & competitor research: track prices, discounts (
onSale,compareAtPrice) and stock (available) across competitor stores. - Dropshipping & product sourcing: browse a supplier's or niche leader's catalog with variants and SKUs.
- Agencies & app developers: see which theme and apps (e.g. reviews, pixels, upsell tools) a store uses.
- Marketplaces, aggregators, data teams: feed catalogs into spreadsheets, BI tools or your own database.
- Change tracking: use
updatedSinceDateto fetch only recently updated products.
Features
- Any number of stores per run; duplicate stores are removed. Product and collection URLs are reduced to the store.
- One row per product, with all variants (id, SKU, price, compare-at price, availability, options, weight in grams).
- Optional single-collection scrape via
collectionHandle. - Theme name/ID, currency and known apps attached to each product (can be turned off).
- Plain-text description always; raw HTML optional.
- Limits: overall (
maxResults) and per store (maxProductsPerStore). - Clear error rows for URLs that are not Shopify stores or whose catalog is hidden, instead of a failed run.
- Runs on Apify datacenter proxy; no browser needed, so runs are fast and light.
Input
| Field | Type | Description |
|---|---|---|
startUrls (required) | array | Store homepages, custom domains or *.myshopify.com. |
maxResults | integer | Max product rows across all stores (default 100). Also caps your spending. |
maxProductsPerStore | integer | Per-store cap; 0 = no per-store limit (default). |
collectionHandle | string | Only scrape this collection (e.g. all, or a handle from the store's /collections/<handle> URLs). Applied to every store. |
includeTechStack | boolean | Detect theme, currency and apps (default true). |
includeDescriptionHtml | boolean | Also output the raw HTML description (default false). |
updatedSinceDate | string | Only products updated on/after this ISO date, e.g. 2026-09-01. |
maxConcurrency | integer | Stores processed in parallel, 1–10 (default 3). |
proxyConfiguration | object | Apify datacenter proxy is the default and was enough in our tests. |
Example input:
{"startUrls": ["https://www.allbirds.com"],"maxResults": 20,"includeTechStack": true,"proxyConfiguration": { "useApifyProxy": true }}
Output
One dataset item per product. Real sample (shortened; run on allbirds.com):
{"storeUrl": "https://www.allbirds.com","storeDomain": "www.allbirds.com","storeName": "Allbirds","productId": 7340901859408,"title": "Women's Allbirds Flip Flop - Dusty Pink","handle": "womens-allbirds-flip-flop-dusty-pink","productUrl": "https://www.allbirds.com/products/womens-allbirds-flip-flop-dusty-pink","vendor": "Allbirds","productType": "Shoes","tags": ["allbirds::gender => womens", "shoprunner"],"descriptionText": "Sun on your feet. Comfort underneath. ...","price": 25,"priceMax": 25,"compareAtPrice": 50,"currency": "USD","onSale": true,"available": true,"variantCount": 7,"options": [{ "name": "Size", "values": ["5", "6", "7", "8", "9", "10", "11"] }],"variants": [{ "id": 42146889039952, "title": "5", "sku": "A12513W050", "price": 25, "compareAtPrice": 50,"available": false, "option1": "5", "option2": null, "option3": null, "grams": 455 }],"featuredImageUrl": "https://cdn.shopify.com/s/files/1/1104/4168/files/A12513_26Q2_Allbirds-Flip-Flop-Dusty-Pink_PDP_LEFT.png?v=1774646345","createdAt": "2026-03-27T21:03:50.000Z","publishedAt": "2026-09-25T23:58:13.000Z","updatedAt": "2026-10-03T14:12:42.000Z","themeName": "allbirds-theme","themeId": 130450260048,"detectedApps": ["Attentive", "Bold Commerce", "TikTok Pixel"],"scrapedAt": "2026-10-03T14:12:40.672Z"}
Output fields & fill rates
Measured on a 300-product production run (qgJ9XvpjP0YbHPpUn). Fill rate = share of rows where the field is present; it depends on what each store publishes.
| Field | Fill rate | Field | Fill rate |
|---|---|---|---|
title, productId, handle, productUrl | 100% | price, priceMax, currency | 100% |
vendor, tags, options, variants, variantCount | 100% | available, onSale | 100% |
createdAt, publishedAt, updatedAt | 100% | themeName, themeId, detectedApps | 100% |
storeUrl, storeDomain, scrapedAt | 100% | productType | 98.3% |
featuredImageUrl, imageUrls | 94.7% | descriptionHtml | 93.7% |
descriptionText | 92.0% | storeName | 73.3% |
compareAtPrice | 22.3% (only discounted items) |
detectedApps is 100% present as a field but can be an empty list when no known app is recognised.
Error rows
If a URL cannot be scraped, the dataset gets a row with storeUrl, error and scrapedAt, and the run still succeeds. Seen in our test runs:
Not a valid store URLproducts.json unavailable (HTTP 404) - not a Shopify store or catalog hiddenCollection "<handle>" is empty or does not exist(the handle must exist on that store)
How to use via API
Replace <TOKEN> with your Apify API token.
curl
curl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/run-sync-get-dataset-items?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"startUrls": ["https://www.allbirds.com"], "maxResults": 20}'
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<TOKEN>' });const run = await client.actor('<ACTOR_ID>').call({startUrls: ['https://www.allbirds.com'],maxResults: 20,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items.length, items[0].title, items[0].price);
Python
from apify_client import ApifyClientclient = ApifyClient("<TOKEN>")run = client.actor("<ACTOR_ID>").call(run_input={"startUrls": ["https://www.allbirds.com"],"maxResults": 20,"includeTechStack": True,"includeDescriptionHtml": False,})items = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(len(items), items[0]["title"], items[0]["price"])
Pricing
Pay per result: you are charged one event per product row delivered. Error rows are not charged. Price per 1,000 results depends on your Apify plan:
| Plan | Per 1,000 results |
|---|---|
| Free | $1.50 |
| Bronze | $1.30 |
| Silver | $1.15 |
| Gold and above | $1.00 |
Set maxResults to cap what a run can cost. Apify platform usage (compute, datacenter proxy) is billed separately by Apify; in our test runs it was well under $0.001 per run for 20–300 products. As of the pricing check, comparable Shopify scrapers listed $1.20–$7.00 per 1,000 at the Gold tier.
Troubleshooting
- "products.json unavailable": the site is not on Shopify or the store has hidden its catalog. Nothing is bypassed; try another store.
- "Collection … is empty or does not exist": check the handle in the store's
/collections/<handle>URL, or leavecollectionHandleempty. - Fewer rows than expected:
maxResults,maxProductsPerStoreorupdatedSinceDatemay be filtering. A spending limit set on the run also stops it cleanly. - Empty
detectedAppsor missingstoreName: the store's homepage did not expose it; the catalog data is unaffected. - Prices look wrong: prices are in the store's own
currencyfield, as published.
FAQ
Does it need a login or API key from the store? No. It uses only public pages.
Does it collect emails or contact information? No, by design. Only product catalog and theme/app data.
Does it work on any Shopify store? On stores that publish /products.json, which most do. Stores that hide it return an error row.
Is scraping legal? The data is public, but you are responsible for complying with the store's terms and applicable law, especially when reusing images and descriptions.
Can I get just one collection? Yes, via collectionHandle.
How do I monitor changes? Schedule the Actor and use updatedSinceDate, or compare price and available between runs.
Keywords
shopify store scraper, shopify product scraper, shopify products.json, shopify price monitoring, shopify catalog export, shopify theme detector, shopify apps detector, shopify competitor analysis, shopify variants SKU, ecommerce scraper, dropshipping product research
Hashtags
#shopify #shopifyscraper #ecommerce #webscraping #pricemonitoring #dropshipping #productdata #competitoranalysis #apify