Shopify Products Scraper & Price Tracker: Variants, Stock, SKUs
Pricing
from $1.60 / 1,000 product scrapeds
Shopify Products Scraper & Price Tracker: Variants, Stock, SKUs
Scrape every product and variant from Shopify stores: prices, compare-at prices, stock, SKUs, images, tags and descriptions. Schedule it as a Shopify price tracker for price drops, price increases, restocks, sell-outs, new and removed products. Pay only per product.
Pricing
from $1.60 / 1,000 product scrapeds
Rating
0.0
(0)
Developer
JT Palms
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
15 hours ago
Last modified
Categories
Share
Shopify Products Scraper & Price Tracker: scrape Shopify stores, then track their price changes
A Shopify products scraper with built-in price tracking. Give it a list of Shopify stores and get every product back: title, vendor, type, tags, prices, compare-at prices, sale flag, stock status, every variant with SKU and options, images and description. Turn on change tracking, schedule it daily, and each run tells you which products dropped in price, went up, came back in stock, sold out, are new, or were removed.
USD 2 per 1,000 products. Stores that are not Shopify, unreachable or blocked are reported free. Removed-product alerts are free.
What people use it for
- Competitor price monitoring. Schedule a daily run over your competitors' stores with Only output changes on. You get a short list of price drops, price increases, restocks, sell-outs and new launches, and pay only for those rows.
- Catalog research for dropshipping and DTC brands. See a store's full range, price points, discount depth (compare-at vs price), best vendors and product types before you pick a niche or a supplier.
- Product feeds. Pull a clean product and variant feed (SKU, price, stock, images) from your own store or a partner's for Google Sheets, a comparison site, or an affiliate catalog.
- Market research. Compare pricing, assortment size, sale frequency and launch pace across a whole category of Shopify brands.
Change tracking (the main reason to schedule it)
With Track changes between runs on, every row gets a change field that compares it with the previous run:
change | Meaning |
|---|---|
new | Not seen in the previous run (a new launch, or the first run for this store) |
price_drop | Lowest price went down (or, if equal, the highest price went down) |
price_increase | Lowest price went up (or, if equal, the highest price went up) |
back_in_stock | Was sold out, now at least one variant is available |
sold_out | Was available, now every variant is sold out |
unchanged | Same price range and same stock status |
removed | Was in the previous run, no longer listed (deleted, unpublished or moved out of the collection). Free. |
previousPriceMin and previousPriceMax hold the earlier prices, and changes lists every label that applies when more than one does (for example ["price_drop", "back_in_stock"]). A product that got cheaper looks like this (other fields left out):
{ "title": "Classic Crew Tee", "priceMin": 25, "previousPriceMin": 35, "change": "price_drop", "changes": ["price_drop"] }
Only output changes skips the unchanged rows, so you pay only for products that actually changed.
Schedule tip. Save your store list as a task with Track changes and Only output changes on, then add a schedule (for example daily at 06:00). The first run sets the baseline and marks every product new; from the second run on you get only real changes. Add an integration (email, Slack, Google Sheets, Make, Zapier or a webhook) on "run succeeded" to receive each day's changes automatically.
How it works: after each run the actor keeps a small snapshot per store (product ID, title, price range, in stock) in a key-value store named shopify-price-tracker in your account, one record per store (and per collection, if you use one). Named stores do not expire, so the history survives between runs. Good to know:
- Snapshots are shared by every run in your account that tracks the same store and collection. An extra manual run with tracking on moves the baseline forward.
removedis only reported when the whole catalog was read. Runs limited by Max products per store, stopped by your cost limit, or cut short by an error do not report removals, and they keep the older snapshot entries for products they did not reach.- To start over for a store, delete its record from the
shopify-price-trackerstore under Storage.
Sample output
One row per product (from a real run on allbirds.com with tracking on; arrays and text shortened):
{"store": "allbirds.com","productId": 7340901859408,"handle": "womens-allbirds-flip-flop-dusty-pink","title": "Women's Allbirds Flip Flop - Dusty Pink","vendor": "Allbirds","productType": "Shoes","tags": ["allbirds::edition => limited", "allbirds::gender => womens", "shoprunner"],"url": "https://allbirds.com/products/womens-allbirds-flip-flop-dusty-pink","createdAt": "2026-03-27T14:03:50-07:00","publishedAt": "2026-09-25T16:58:13-07:00","updatedAt": "2026-09-28T11:14:26-07:00","priceMin": 25,"priceMax": 25,"compareAtPriceMax": 50,"currency": "USD","onSale": true,"available": true,"variantCount": 7,"optionNames": ["Size"],"variants": [{ "id": 42146889039952, "title": "5", "sku": "A12513W050", "price": 25, "compareAtPrice": 50, "available": false, "option1": "5", "option2": null, "option3": null, "grams": 455 },{ "id": 42146889072720, "title": "6", "sku": "A12513W060", "price": 25, "compareAtPrice": 50, "available": false, "option1": "6", "option2": null, "option3": null, "grams": 492 }],"images": ["https://cdn.shopify.com/s/files/1/1104/4168/files/A12513_26Q2_Allbirds-Flip-Flop-Dusty-Pink_PDP_LEFT.png?v=1774646345"],"bodyText": "Sun on your feet. Comfort underneath. Light, easy, and made for warm weather, these flip flops bring everyday comfort to sunny days, beach walks, and everything...","scrapedAt": "2026-09-28T18:14:27.498Z","change": "unchanged","changes": [],"previousPriceMin": 25,"previousPriceMax": 25}
In Variant mode you get one row per size or color instead, with the product fields repeated and these added: variantId, variantTitle, sku, price, compareAtPrice, variantAvailable, variantOnSale, option1 to option3, grams. The row url links straight to that variant.
A store that could not be read comes back as one free row with an error, for example "Not a Shopify store or products.json disabled (HTTP 404).", "Domain not found (DNS lookup failed). Check the spelling." or "Store is password protected. Its products are not public."
Export as JSON, CSV or Excel, or read the results through the Apify API. The dataset has three table views: Products, Changes and Variants.
How to use it
- Put your stores in Shopify stores, one per line. Bare domains (
allbirds.com), full URLs and*.myshopify.comaddresses all work. A collection URL such ashttps://store.com/collections/salereads only that collection. - Optional: set Collection to read one collection from every store, One row per to Variant, or Max products per store for a quick sample.
- Optional: turn on Track changes between runs and Only output changes, then schedule the actor (see the tip above).
- Click Start, then download the results or connect them to your tools.
Pricing
| What | Price |
|---|---|
| Product row (or variant row in Variant mode) | USD 0.002 (USD 2 per 1,000) |
| Unchanged product skipped by Only output changes | Free |
removed row | Free |
| Store that is not Shopify, unreachable, blocked or password protected | Free |
Examples: a full read of a 2,000-product store costs USD 4. Tracking 5 stores of 2,000 products each with Only output changes costs USD 20 for the first (baseline) run; after that you pay per changed product, so a day on which 200 products change costs USD 0.40.
In Variant mode every variant row counts, so a product with 8 sizes is 8 rows. Set a maximum cost per run in the run options and the actor stops cleanly when it reaches it; everything saved before that is kept.
Limits
- The actor identifies itself. Every request carries the user agent
Mozilla/5.0 (compatible; shopify-store-products/1.0; +https://apify.com/JTPalms/shopify-store-products), with plain request headers. It never pretends to be a browser. Some sites block bots; a blocked request is reported as an error, not hidden. - It reads the public
/products.jsonfeed that Shopify storefronts serve. Only products published to the online store appear; hidden, draft and B2B-only products do not. - Some stores disable or block that feed (headless storefronts, custom proxies, password pages). Those are reported free with an error. The actor also tries the
www.host and the store's*.myshopify.comaddress before giving up. - Stock is a yes or no per variant. Shopify does not publish inventory quantities in this feed.
- Prices are what the feed returns, normally in the store's default currency, which is read from the store's
/meta.json. Localized prices for other countries are not included. - Descriptions are plain text capped at 2,000 characters, and up to 10 images are listed per product.
- Pages are read one at a time per store with a short pause between them, and rate limits (HTTP 429) and server errors are retried up to 3 times. Large stores (10,000+ products) take a minute or two each.
Related actors
- WooCommerce Products Scraper & Price Tracker: Scrape every product from any WooCommerce store through its public Store API: prices, sale prices, stock, SKUs, categories, tags,...
- Website Tech Stack Detector (Wappalyzer Alternative): Find the technology behind any website in bulk: CMS, ecommerce platform, analytics, frameworks, CDN, hosting, payment, email and...
FAQ
Is it legal? It reads /products.json, a public endpoint every Shopify storefront serves to anyone, the same product data shown on the store's own pages. It does not log in, bypass protections, or collect personal data. As with any data, check how you use it against the store's terms and your local rules.
Do I need a Shopify API key or store access? No. It works on any public Shopify store without keys, apps or login.
How do I know which sites run on Shopify? Just add them. Non-Shopify sites come back free with an error. To filter a big list first, run it through a tech stack detector.
Why do I see a different price in my browser? Stores that sell in several countries can show a converted or localized price to visitors. This actor reports the feed price in the store's default currency.
Can I get an alert when a competitor drops a price? Yes. Schedule a task with Only output changes on and add an email, Slack or webhook integration. Each run then sends only the changed products.
Something looks wrong for a store? Open an issue with the store domain.