Shopify Product Scraper & Competitor Price Monitor
Pricing
from $0.80 / 1,000 results
Shopify Product Scraper & Competitor Price Monitor
Scrape any Shopify or WooCommerce store's products, variants, prices, discounts and stock. Monitor competitor price drops, restocks and new products on a schedule. No login or proxy.
Pricing
from $0.80 / 1,000 results
Rating
0.0
(0)
Developer
Ad Astra Connect
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
an hour ago
Last modified
Categories
Share
Shopify Product Scraper and Competitor Price Monitor (WooCommerce too)
Track competitor prices, discounts and stock on any public Shopify or WooCommerce store, and export the full product catalog with every variant. Enter store URLs, get one row per product (or per variant) with price, compare-at price, discount, availability, vendor, product type and images. Switch to Changes mode and schedule it: each run returns only what changed (price drops, price increases, back in stock, out of stock, new and removed products). It reads the stores' public product feeds (Shopify /products.json, WooCommerce Store API), so there is no login, no proxy and no browser.
Typical buyers: ecommerce brands watching competitors, pricing analysts, dropshippers and product researchers, and agencies running catalog audits.
Sample output: Shopify product prices and discounts
Real rows from a run on October 21, 2026 (store allbirds.com), shortened:
| platform | title | vendor | price | compareAtPrice | discountPct | onSale | available | variantCount |
|---|---|---|---|---|---|---|---|---|
| shopify | Women's Allbirds Flip Flop - Dusty Pink | Allbirds | 25 | 50 | 50 | true | true | 7 |
| shopify | Men's Canvas Runner NZ - Deep Navy Stripes (Blizzard Sole) | Allbirds | 100 | false | true | 13 | ||
| shopify | Men's Cruiser Terry - Warm White (Warm White Sole) | Allbirds | 115 | false | true | 13 |
Each row also has storeUrl, productId, handle, url, imageUrl, currency, priceMax, tags, variants, createdAt, updatedAt and publishedAt.
Why use this Shopify and WooCommerce scraper?
- Two platforms, one schema. Shopify and WooCommerce rows have the same fields, so you can compare stores side by side.
- Auto-detects the platform. Just paste the store URL.
- Price and stock monitoring built in. A compact baseline is kept in Apify storage; later runs return only what changed. The first baseline run is free.
- Products or variants. One row per product with a nested variants array, or one row per variant (size, colour, SKU).
- Filters before billing. Keyword, price range and availability filters run before output, so you pay only for rows you keep.
- Fast and light. Reads public JSON feeds directly. A typical store of a few hundred products finishes in seconds.
Use cases
- Competitor price monitoring for ecommerce brands and retailers.
- Back-in-stock and sale alerts via Apify webhooks, Make, Zapier or n8n.
- Product research and catalog analysis: assortment size, price bands, discount depth, vendors.
- Catalog exports to CSV or Excel for merchandising, marketplaces or affiliate sites.
- Market and trend tracking across a list of DTC brands.
What data can you get
| Fields | What they contain |
|---|---|
platform, storeUrl | Detected platform and input store origin |
productId, handle, title | Product identity and name |
vendor, productType, categories, tags | Shopify vendor/type or WooCommerce brand/categories, and catalog tags |
url, imageUrl, imageCount | Product page, first image, number of images |
currency, price, priceMax | Currency code and lowest/highest variant prices |
compareAtPrice, onSale, discountPct | Lowest sale reference price, any-variant sale flag, lowest-priced variant's percentage discount |
available, variantCount | Any-variant availability and variant count |
variants | Product-mode array of variant IDs, titles, SKUs, prices, reference prices, stock and up to three options |
variantId, variantTitle, sku | Single variant identity in variants mode |
variantPrice, variantCompareAtPrice, variantAvailable | Single variant price, reference price and availability |
createdAt, updatedAt, publishedAt, scrapedAt | Feed timestamps when exposed, plus collection time |
descriptionText | Optional plain text description, with contact details removed |
changeType, detectedAt | Monitoring event and observation timestamp |
previousPrice, currentPrice, priceChangePct | Variant prices before/after and signed percentage change |
previousAvailable, currentAvailable | Variant stock status before/after |
The dataset has Overview and Changes table views. Export it as JSON, CSV, Excel, or another supported Apify format. IDs are strings. Missing values are null; descriptions are omitted unless requested. Feed fields such as customer details, reviews, ratings, and extension payloads are never included in the output.
How to scrape Shopify and WooCommerce products
- Open the Actor input and enter public store URLs. Bare domains work too. The prefilled examples are two stores whose public feeds were verified during development.
- Choose Products, Variants, or Changes. Leave platform on Auto detect unless you know it.
- Set product and output limits, plus any availability, price, or keyword filters.
- Run the Actor. Open the dataset for results and the
RUN_SUMMARYkey-value record for store statuses, detected platforms, counts and errors. - For monitoring, schedule repeated Changes runs with the same
monitorKey, collection, and product limit.
{"startUrls": ["https://www.allbirds.com","https://offermanwoodshop.com"],"platform": "auto","mode": "products","maxProductsPerStore": 30,"maxResults": 60,"includeDescription": false,"onlyAvailable": false,"requestDelayMs": 1000}
A Shopify collection URL such as https://shop.example.com/collections/shoes reads that collection's product feed. Other store paths select the origin's full product feed. WooCommerce installations in a WordPress subdirectory are currently unsupported.
Input reference
| Input | Default | Behavior |
|---|---|---|
startUrls | Allbirds and Offerman Woodshop | Required in the editor; empty raw input uses these defaults |
platform | auto | auto, shopify, woocommerce |
mode | products | products, variants, changes |
monitorKey | default | Namespace for independent monitoring baselines |
emitBaselineOnFirstRun | false | Emit new_product per matching variant on a first Changes run |
minPriceChangePct | 0 | Absolute percentage threshold, inclusive; stock events unaffected |
maxProductsPerStore | 500 | Parent products read before filtering; 0 means unlimited |
maxResults | 2000 | Hard cap on dataset rows across all stores; minimum 1 |
includeDescription | false | Add plain text product descriptions |
onlyAvailable | false | Require any variant in stock at product level |
minPrice, maxPrice | Unset | Inclusive bounds on the lowest variant price, in store currency |
keywords | [] | Any keyword may match title, vendor, type or tags, ignoring case |
requestDelayMs | 1000 | Minimum per-host interval; larger Crawl-delay wins |
Output example
Illustrative product row, with the variant array shortened:
{"platform": "shopify","storeUrl": "https://shop.example.com","productId": "101","handle": "wool-runner","title": "Wool Runner","vendor": "Sample Footwear","productType": "Shoes","categories": [],"tags": ["wool", "running"],"url": "https://shop.example.com/products/wool-runner","imageUrl": "https://cdn.example.com/shoe.jpg","imageCount": 1,"currency": "USD","price": 80,"priceMax": 90,"compareAtPrice": 100,"onSale": true,"discountPct": 20,"available": true,"variantCount": 2,"variants": [{"variantId": "201","title": "Blue / 8","sku": "WR-B-8","price": 80,"compareAtPrice": 100,"available": true,"option1": "Blue","option2": "8","option3": null}],"createdAt": "2026-01-01T00:00:00Z","updatedAt": "2026-02-01T00:00:00Z","publishedAt": "2026-01-01T00:00:00Z","scrapedAt": "2026-10-20T12:00:00Z"}
How much does it cost to scrape Shopify and WooCommerce products?
This Actor uses pay per event pricing: $1.00 per 1,000 results (Apify Store discount tiers pay less). The price on the Store page is authoritative. Platform compute is included, so you pay for the rows you receive plus Apify's small per-run start fee, nothing else.
| Example run | Rows returned | Approximate cost |
|---|---|---|
| Products mode, 3 stores, 100 products each | 300 | about $0.30 |
| Variants mode, one store with 1,000 variants | 1,000 | about $1.00 |
| Daily Changes mode on 5 stores, about 20 changes per day | about 600 per month | about $0.60 per month |
What you are charged for: each dataset row is one product event (a product row, a variant row or a change record). A variant with both a price and a stock change produces two rows. The silent first baseline in Changes mode emits no rows and costs nothing beyond the start fee. Use maxResults to cap a run, and set a maximum cost per run in Apify; the Actor stops cleanly when that limit is reached.
Incremental runs / monitoring
Set mode to changes. On the first successful run per store, the Actor saves a baseline and logs that it saved it. The default is zero output rows. Set emitBaselineOnFirstRun to true to emit new_product records for that baseline.
Snapshots live in the named key-value store store-product-feed-monitor-state. A hash of the input store host and monitorKey selects the record. Keep the same host spelling, including www, across runs. The store retains only compact per-variant identity, prices, reference price, stock, title, URL, currency and filter eligibility. Large snapshots are split into chunks below 8 MB, with the manifest written last. Descriptions and images are not saved in monitoring state.
Later runs can emit new_product, removed_product, price_drop, price_increase, back_in_stock, and out_of_stock. These names apply per variant, so a newly added size is a new_product event. priceChangePct is signed, rounded to two decimals, and null when there is no meaningful previous price or the previous price is zero. The minimum percentage threshold uses the unrounded absolute change. Compare-at price is retained in the baseline, but a compare-at-only edit has no dedicated event type.
A capped feed scan cannot prove that an unseen variant was removed. It preserves unseen baseline entries and suppresses removal events. To monitor removals across the entire store, use maxProductsPerStore: 0. Changing the collection, product limit, origin, or detected platform starts a fresh baseline. Use separate monitorKey runs for multiple collections on the same host. Filters apply to product-level matches; an event is included if the previous or current product matched, so an out-of-stock transition can still be reported with onlyAvailable: true.
Failed or malformed feed scans leave the previous snapshot intact and emit no monitoring events. If a row or spending limit interrupts change delivery, the snapshot is not advanced; already delivered events can repeat next run. Increase limits and deduplicate by variant, event and values if needed. Avoid overlapping schedules that write the same host/monitorKey pair; the KV store has no cross-run lock. Public feeds can change while paging, so no run represents a transactional catalog export.
Scheduling and integrations
Use Apify schedules to check feeds hourly, daily, or at another suitable interval. Trigger webhooks after runs, download datasets through the Apify API, or connect results to Make, Zapier, and n8n. AI agents can start runs and consume datasets through Apify's MCP integration. The Actor itself sends no alerts or messages; configure your chosen integration to route change records.
Is it legal to scrape Shopify and WooCommerce stores?
The Actor reads only the official public product endpoints exposed to visitors by Shopify and WooCommerce. It does not log in, send cookies, fetch customer data or reviews, or access cart, checkout, or account endpoints. It identifies its User-Agent, respects robots.txt, and honors Crawl-delay. Output selects catalog fields only and removes email addresses and recognizable phone numbers from text. A product catalog can contain names as part of product or brand names; the Actor does not retrieve personal profiles or identify individuals.
Users are responsible for checking applicable law, store terms, and their rights to use and redistribute catalog information, images, and descriptions. Public accessibility does not grant unrestricted reuse rights.
Limitations
- Some stores disable feeds, block automated access, or require authentication. These are recorded as unsupported, blocked, or failed; there is no bypass.
- Shopify uses
/products.json?limit=250&page=N, or the equivalent collection route, and optionally/meta.jsonfor currency. Currency stays null if that metadata is unavailable or disallowed. No cart-based currency lookup is used. - WooCommerce uses
/wp-json/wc/store/v1/productsand falls back to/?rest_route=/wc/store/v1/productsonly on HTTP 404. Real variant details are fetched in batches through the same public Store API. If advertised variants cannot be retrieved, that target fails rather than inventing variant values. - Feed timestamps, Shopify categories, WooCommerce brands, and stock detail depend on what the platform exposes. Missing timestamps are null. Shopify availability is the feed's boolean; stock quantities are not collected.
- Prices use the store's currency. There is no conversion, shipping calculation, tax adjustment, customer-specific pricing, or regional session selection. WooCommerce minor units are converted using
currency_minor_unit. compareAtPriceis the lowest reference price among sale variants.discountPctis calculated from the lowest-priced variant's own reference price and is null if that variant is not on sale. A different variant can still makeonSaletrue.- Products mode retains all variants of a matching product. Variants mode emits all those variants, including unavailable ones if another variant makes the product available.
- One request at a time keeps memory and load small. Retries cover 429, 5xx, and network failures with exponential backoff, jitter, Retry-After and a 20-second timeout per attempt, up to four retries. Robots HTTP 404 allows proceeding; inaccessible or invalid robots responses fail closed.
- A store status is
ok,not_found,blocked_by_robots,unsupported, orerror. Duplicate URLs are markedduplicate; targets after an output limit arenot_processed. Only runs with no successful targets fail overall. Partial catalog output from a later failing page may remain in the dataset.
FAQ
Why did my first Changes run return no rows? It saved a baseline. Run it again with the same host, monitorKey and scope to compare, or enable baseline output.
Why are no removal alerts reported? The product cap may have stopped the scan. Use unlimited product scans for reliable removal detection.
Can I monitor a Shopify collection? Yes. Supply its /collections/{handle} URL. Use an independent monitorKey for a different collection on the same host.
Are WooCommerce REST API keys required? No. This Actor uses the public Store API, not the authenticated administrative REST API.
How often should I run Changes mode? Daily suits most price monitoring. Hourly works for fast-moving sales; keep the same monitorKey and avoid overlapping runs.
Can I get alerts by email or Slack? The Actor writes change rows to the dataset. Use an Apify webhook or the Make, Zapier or n8n integration to route them to email, Slack or a spreadsheet.
Does it work with every store? No. Only reachable public feeds with allowed robots rules are supported. Custom headless stores, site protections, older Store APIs and subdirectory WordPress installations can prevent collection.
Why can a row show no currency or timestamp? The store's public endpoint did not supply it, or the optional metadata route was unavailable.
Support
Use the Issues tab on the Actor's Apify Store page. Include the run link, input settings, affected store URL and expected behavior. Do not include credentials or customer information.
Disclaimer
Shopify and WooCommerce are trademarks of their respective owners. This Actor is an independent tool and is not affiliated with, sponsored by or endorsed by Shopify Inc., Automattic or any store you monitor. Nothing in this README is legal advice.