Shopify Store Scraper - All Products & Live Prices avatar

Shopify Store Scraper - All Products & Live Prices

Pricing

from $0.50 / 1,000 product delivereds

Go to Apify Store
Shopify Store Scraper - All Products & Live Prices

Shopify Store Scraper - All Products & Live Prices

Scrape the full product catalogue of any Shopify store: titles, variants, SKUs, live prices, compare-at discounts, stock status, images, tags, product types and collections. Bulk multi-store, no API key, no login. Duplicate products from paginated boards are removed so you are never billed twice.

Pricing

from $0.50 / 1,000 product delivereds

Rating

0.0

(0)

Developer

DONGMIN KIM

DONGMIN KIM

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

8 hours ago

Last modified

Share

Shopify Store Scraper — All Products, Variants, Prices & Stock from Any Store

Point it at any Shopify store and get the entire product catalogue: every product, every variant, SKUs, live prices, compare-at discounts, stock status, images, tags, product types and optionally the store's collections.

Multiple stores per run. No API key, no store permission, no login.

A live run pulled 600 products in under a second from one store.

Why this is reliable

Every Shopify storefront publishes /products.json — it is part of the platform, not an oversight, and it has been stable for years. There is no HTML to parse here and no markup churn to chase, which is why this actor does not break the way theme-scraping tools do.

Two things it handles that a naive reader does not:

  • Duplicate products. Shopify paginates by offset over a catalogue that shifts between requests, so the same product genuinely comes back on two pages — measured at 100 repeats in 600 rows on a live store. Those are dropped, so you are never billed twice for one product.
  • Bot walls. A minority of stores sit behind a WAF that throttles datacenter IPs. The actor starts on cheap datacenter proxies and escalates to residential only for the stores that actually need it.

Input

{
"storeUrls": ["gymshark.com", "https://allbirds.com/collections/mens"],
"maxProductsPerStore": 1000,
"onSaleOnly": true,
"inStockOnly": false,
"minPrice": 0,
"productTypeContains": ["shoes"],
"includeVariants": true,
"includeCollections": false
}

Bare domains or any URL on the store both work — it normalises to the origin.

Every option

The same wording you see in the Apify console, with the JSON key for API and MCP callers.

OptionWhat it doesDefault
Shopify storesstoreUrls (required)Bare domains or any URL on the store — gymshark.com, https://allbirds.com/collections/mens, shop.example.co.uk. Multiple stores per run.
Max products per storemaxProductsPerStoreProducts arrive 250 per request, so this is the main cost control. Leave high for a full catalogue.1000
On sale onlyonSaleOnlyKeep only products whose compare-at price is above the live price. Filtered products are not billed.false
In stock onlyinStockOnlyKeep only products with at least one available variant.false
Minimum priceminPriceIn the store's own currency. 0 disables.0
Maximum pricemaxPriceIn the store's own currency. 0 disables.0
Product type or tag containsproductTypeContainsKeep only products whose product type or tags contain one of these. Case-insensitive.
Include variant detailincludeVariantsAttach the full variant array (SKU, price, availability, options) to each product. Turn off for a slimmer dataset.true
Also scrape collectionsincludeCollectionsAdd one row per collection with its title, handle and product count — a map of how the store organises its catalogue.false
Skip non-Shopify domainsskipNonShopifyCheck each domain is Shopify before scraping. Costs one cheap request per store and avoids wasted work.true
ConcurrencyconcurrencyStores processed in parallel.3
ProxyproxyConfigurationLeave the default. A minority of stores sit behind a WAF that throttles datacenter IPs; the actor starts cheap and escalates to residential only for the stores that need it.{"useApifyProxy":true}

Output

One row per product. With Include collections on, each store also writes one row per collection, marked type: "collection".

{
"storeDomain": "allbirds.com",
"productId": 6806723428554,
"title": "Men's Strider - Medium Grey",
"handle": "mens-strider",
"url": "https://allbirds.com/products/mens-strider",
"vendor": "Allbirds",
"productType": "Shoes",
"tags": "sale,mens,wool",
"createdAt": "2025-07-24T09:12:00-04:00",
"publishedAt": "2025-08-01T10:00:00-04:00",
"updatedAt": "2026-08-09T22:41:13-04:00",
"minPrice": 91,
"maxPrice": 95,
"compareAtPrice": 130,
"onSale": true,
"discountPercent": 30,
"inStock": true,
"variantCount": 13,
"availableVariantCount": 2,
"imageUrl": "https://cdn.shopify.com/…",
"imageCount": 7,
"options": [{ "name": "Size", "values": ["9", "10", "11"] }],
"description": "Soft & light. Wool upper.",
"variants": [
{ "variantId": 1, "title": "9", "sku": "AB-9", "price": 91, "compareAtPrice": 130, "available": false, "option1": "9" }
]
}

Every field

You are billed per row delivered, so here is everything a row can contain. A field is absent when the store did not publish it.

Product rows

FieldWhat it is
storeDomainWhich store the row came from, so a multi-store run reads without a join.
productIdShopify's numeric product id.
titleProduct title.
handleThe URL slug. It is the stable key across renames, and what you join on against a store's own exports.
urlCanonical product URL.
vendorBrand as the store records it.
productTypeThe store's own product type.
tagsThe store's tag string.
createdAtWhen the product was created in the store's admin — earlier than publishedAt, and the better signal for how long something has existed.
publishedAtWhen it went live on the storefront.
updatedAtLast edit of any kind, so a diff between runs tells you something changed.
descriptionBody copy with HTML stripped.
optionsThe option axes, each with name and values — e.g. Size and Colour.
imageUrlFirst image.
imageCountHow many images the product has, without pulling them all.
variantCountNumber of variants.
availableVariantCountHow many of those are in stock — the difference is the size curve breaking.
inStocktrue when any variant is available.
minPrice / maxPriceLive price range across variants.
compareAtPriceHighest compare-at price found, which is how Shopify represents the pre-markdown price.
onSaletrue when a compare-at price sits above the live price.
discountPercentThat markdown as a whole-number percent.
variantsPer-variant rows: variantId, title, sku, price, compareAtPrice, available, requiresShipping, grams, option1option3. Dropped when Include variants is off.

onSale and discountPercent are derived from the compare-at price, so you get the markdown without doing the arithmetic.

Collection rows (type: "collection")

FieldWhat it is
typeAlways "collection" on these rows; product rows have no type.
storeDomainWhich store the collection belongs to.
collectionIdShopify's numeric collection id.
titleCollection title.
handleIts URL slug.
urlCanonical collection URL.
productsCountHow many products the store reports in it.
updatedAtLast time the collection changed.
descriptionCollection body copy with HTML stripped.

Who this is for

  • Price analysts — schedule it and diff the price ladder over time, variant by variant.
  • Buyers and merchandisers — what a competitor sells, in what types, at what price, and what is selling out.
  • Sourcing and dropshipping teams — whole catalogues, filtered by price band, without asking anyone for access.
  • Promotion trackersonSaleOnly shows exactly what a store has marked down and by how much.

Common uses

  • Competitor price monitoring — schedule it and diff prices over time.
  • Assortment analysis — what a competitor sells, in what types, at what price ladder.
  • Discount trackingonSaleOnly: true shows exactly what a store has marked down and by how much.
  • Stock intelligenceavailableVariantCount reveals what is selling out.
  • Dropshipping and sourcing — pull catalogues and filter by price band.
  • Feeding a comparison site or a price-tracking product.

Pricing

Pay per product delivered. Products removed by your filters, duplicate products, non-Shopify domains, and failed stores cost nothing.

Starting a run costs $0.00002 — the platform's $0.00001 minimum, charged once per GB of memory, and these Actors run on 2 GB. That is two cents per thousand runs, and it is the only charge not tied to a row you received.

Other Actors in this family

Same engines, same billing, no account or API key on any of them.

YouTube & video

Search demand

E-commerce

Hiring

FAQ

Will I get blocked or rate-limited? This reads /products.json, the endpoint Shopify itself serves on every shop for exactly this purpose. It is not defended, which is why the Actor runs on datacenter IPs and why the price can be what it is. Nothing here signs in to a store.

Does this need Shopify API access? No. It reads the public storefront endpoint that every Shopify store serves.

Does it work on every Shopify store? Almost all. A small number disable the endpoint (reported as a clear error) or sit behind a WAF (handled by proxy escalation).

Is the domain Shopify? The actor checks before scraping and skips non-Shopify domains rather than wasting your budget on them.

Can I get inventory quantities? No — Shopify exposes availability as a boolean publicly, not exact counts. availableVariantCount is the closest public signal.

Can I run it on a schedule? Yes, via Apify Schedules, webhooks, or the API. Also available over MCP for AI agents.

Is it legal to scrape Shopify stores? This reads the public /products.json endpoint that Shopify itself serves on every storefront for exactly this purpose — no login, nothing bypassed, no rate limit worked around. Prices, stock and titles are facts about products on public sale. Each store's own terms are a separate contract question. Not legal advice.

How much does 1,000 products cost? $0.50, plus $0.00002 for the run. Products your filters remove, duplicate rows from paginated boards, and stores that fail are never billed.

Can I export the results to Excel or Google Sheets? Yes. Every run's dataset downloads as CSV, Excel, JSON, XML or RSS from the Storage tab, or straight from the API if you want a live link a spreadsheet can pull.

Can I connect it to Zapier, Make or n8n? Yes — Apify publishes integrations for all three, plus webhooks that fire when a run finishes. A common setup is a schedule here and a webhook into your own database or Slack.

Do I need to write code? No. Fill the form in the console and press Start. If you do want code, the Apify client libraries for Python and JavaScript call this the same way, and it is available over MCP so an AI agent can call it directly.