Shopify Store Products Scraper (Prices, Variants)
Pricing
from $0.90 / 1,000 product scrapeds
Shopify Store Products Scraper (Prices, Variants)
Scrape every public product from any Shopify store, custom domains included: title, vendor, type, tags, prices, compare-at/sale flags, availability, variants with SKUs, options, images and description. Store, collection or product URLs. Pay only for products returned.
Pricing
from $0.90 / 1,000 product scrapeds
Rating
0.0
(0)
Developer
Mogul Tools
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Share
Shopify Store Products Scraper (Prices, Variants, SKUs, Stock)
Enter Shopify store domains (custom domains like allbirds.com work), collection URLs or product URLs. You get one clean row per product with title, vendor, type, tags, min/max price, compare-at price, sale flag and discount %, availability, every variant (SKU, barcode, price, options, weight, stock flag), images and description. The scraper reads each store's public JSON endpoints (/products.json, /collections/<handle>/products.json, /products/<handle>.js|.json, /meta.json), so it needs no browser and no proxies, and runs are fast. In our test it scraped 2,214 products from 12 stores in under 8 seconds.
You pay only for real products. Non-Shopify sites, password-protected stores, 404s, blocked stores, invalid inputs, robots.txt-disallowed URLs and duplicates are written free, each with a reason code.
Use cases
- Competitor price monitoring: track prices, compare-at prices,
onSaleandmaxDiscountPercentacross rival stores. - Catalog research and dropshipping: pull full catalogs (vendors, product types, tags, variants) to find gaps and trends.
- Stock tracking:
availableandavailableVariantCountper product, andavailableper variant. - Lead lists: use the optional store summary row (store name, currency, country, product count, vendors, price range) to qualify Shopify merchants.
Input
| Field | Default | Notes |
|---|---|---|
stores | – | Store domains or URLs, e.g. gymshark.com, https://colourpop.com, myshop.myshopify.com. If www. is blocked or headless, the bare domain is tried (and the other way round). |
collectionUrls | – | e.g. https://colourpop.com/collections/lips. Only that collection is scraped. |
productUrls | – | e.g. https://www.allbirds.com/products/mens-tree-runners. These rows also include updatedAt, barcodes and inventoryQuantity when the store exposes them. |
maxProductsPerStore | 1000 | Cap per store or collection. 0 = no cap (Shopify itself allows at most 25,000 per listing). |
keyword | – | Comma-separated. Keeps products whose title, vendor, type, handle or tags contain any term (case-insensitive substring). It doesn't apply to product URLs. Filtered-out products are not charged. |
includeVariants | true | Turn off for smaller rows. Prices and availability are still summarized. |
includeStoreSummary | false | One free summary row per store. |
includeFailedRows | true | Free rows for inputs that returned no products. |
maxChargedProducts | 0 (no limit) | Stop after this many charged products. |
maxConcurrency / requestDelayMs | 5 / 500 | Stores run in parallel. Requests to the same store are paced, and the delay doubles automatically if the store answers 429. |
{ "stores": ["allbirds.com", "gymshark.com"], "collectionUrls": ["https://colourpop.com/collections/lips"], "maxProductsPerStore": 500, "keyword": "runner" }
Output (one row per product, abridged)
{"rowType": "product", "status": "OK", "store": "kyliecosmetics.com", "storeName": "Kylie Cosmetics", "currency": "USD","productId": 9168000876786, "handle": "kylies-sunset-glam-look-bundle", "title": "Kylie's Sunset Glam Look Bundle","url": "https://kyliecosmetics.com/products/kylies-sunset-glam-look-bundle","vendor": "kylie-cosmetics", "productType": "Bundle", "tags": ["..."],"priceMin": 208.8, "priceMax": 208.8, "compareAtPrice": 232, "onSale": true, "maxDiscountPercent": 10,"available": true, "variantCount": 1, "availableVariantCount": 1, "skus": ["..."],"options": [{ "name": "Title", "values": ["Default Title"] }],"variants": [{ "id": 49799067631858, "title": "Default Title", "sku": "...", "price": 208.8, "compareAtPrice": 232, "onSale": true, "available": true, "grams": 0, "options": ["Default Title"], "imageUrl": null }],"imageUrl": "https://cdn.shopify.com/...", "images": ["..."], "imageCount": 10,"bodyText": "...", "bodyHtml": "...", "createdAt": "...", "publishedAt": "...", "updatedAt": "...","collection": null, "source": "store", "charged": true, "errorCode": null, "error": null}
Every row has the same fields. Free rows have charged: false, a status/errorCode and an error message: NOT_SHOPIFY, PASSWORD_PROTECTED, NOT_FOUND, SHOP_UNAVAILABLE, PRODUCTS_JSON_DISABLED, BLOCKED, RATE_LIMITED, ROBOTS_DISALLOWED, NO_PRODUCTS, NO_MATCHES, DUPLICATE, INVALID_INPUT, PAGINATION_LIMIT, or network codes such as TIMEOUT and DNS_ERROR. A run summary is saved to the key-value store as RUN_SUMMARY.
Pricing (pay per event)
One event, product-scraped. It is charged once per unique product written with real data.
| Tier | Per product | Per 1,000 products |
|---|---|---|
| FREE | $0.0015 | $1.50 |
| BRONZE | $0.0013 | $1.30 |
| SILVER | $0.0011 | $1.10 |
| GOLD | $0.0009 | $0.90 |
Free: everything in the free-row list above, plus products removed by your keyword filter. Apify's standard actor-start event ($0.00005) applies. Set a max total charge or maxChargedProducts to cap spend. The run stops cleanly at your limit and never charges past it.
Limitations
- Public catalog only. Unpublished, hidden or B2B-only products aren't visible. Store listings don't include exact stock counts.
inventoryQuantityappears only on product-URL rows, and only if the store exposes it (most don't). - Shopify caps listings at 25,000 products per endpoint. For bigger stores, add collection URLs (each has its own 25,000 cap). Products seen in several collections are charged once.
- Some Shopify stores disable
/products.json(PRODUCTS_JSON_DISABLED). Others sit behind bot walls such as Cloudflare, Vercel or Akamai (BLOCKED). Headless stores built on Hydrogen or custom front ends often fail on the custom domain. Try their*.myshopify.comaddress. These rows are free. currencyis the store's default currency (from/meta.json). Prices are those served to an anonymous visitor from the run's region, without market- or customer-specific pricing.- robots.txt is respected. Stores that disallow the endpoints are written free as
ROBOTS_DISALLOWED. - Recommended memory: 512 MB (default). 256 MB works for small runs.