Shopify Product Scraper avatar

Shopify Product Scraper

Pricing

from $7.00 / 1,000 product scrapeds

Go to Apify Store
Shopify Product Scraper

Shopify Product Scraper

Extract full product catalogues from any Shopify store with a public products.json feed: titles, prices, compare-at prices, discounts, price ranges, currency, every variant with SKU, options and in-stock status, images, tags and vendor. Non-Shopify or protected URLs get a clear reason.

Pricing

from $7.00 / 1,000 product scrapeds

Rating

5.0

(1)

Developer

WebDataLabs

WebDataLabs

Maintained by Community

Actor stats

3

Bookmarked

327

Total users

41

Monthly active users

2 days ago

Last modified

Share

Shopify Scraper - Extract Products, Prices & Variants

What you get

One flat row per product: title, brand, product type, tags, price, compare-at price, discount %, price range, store currency, every variant (option values, SKU, barcode, availability), all image URLs, publish dates and the product URL. Paste either www. or the apex domain - the actor resolves whichever host serves the data.

And it tells you the truth when there is nothing to get. Every run writes an OUTPUT record to the key-value store with a per-store status (OK, CAPPED, PARTIAL, EMPTY_CATALOGUE, NOT_SHOPIFY, HEADLESS_STOREFRONT, PASSWORD_PROTECTED, BLOCKED, RATE_LIMITED, UNREACHABLE) and the reason. A run that was blocked or throttled fails loudly instead of finishing green with an empty dataset, and a truncated catalogue is reported as PARTIAL rather than "complete".

Two Modes:

  • URL Mode (default): Scrape product data from specific Shopify store URLs
  • Discovery Mode: Find Shopify stores by category from a 321K+ store directory

Quick Start

Scrape Products from a Store (Default)

{
"storeUrls": [{ "url": "https://gymshark.com" }],
"maxProducts": 100
}

Scrape Multiple Stores

{
"storeUrls": [
{ "url": "https://gymshark.com" },
{ "url": "https://allbirds.com" }
],
"maxProducts": 0
}

Discover Stores by Category

{
"mode": "discovery",
"category": "food/coffee",
"maxStores": 500
}

Product Data Extracted

  • Pricing: Current price, original price, discount %, price ranges, store currency
  • Variants: All sizes, colors, options (up to 250 per product)
  • Inventory: Stock availability per variant
  • Metadata: Brand, category, tags, SKU, barcode, images, description text, timestamps

Any value that could not be determined is null. The actor never fills a gap with a placeholder such as 0, "N/A" or "Unknown".

Not included: review counts, ratings and sales estimates. See Why there is no review or sales data.

Product Output

{
"store": "gymshark.com",
"product_id": 4592837465123,
"product_url": "https://gymshark.com/products/training-shorts-black",
"handle": "training-shorts-black",
"title": "Training Shorts - Black",
"vendor": "Gymshark",
"type": "Shorts",
"tags": ["training", "sale"],
"price": 45,
"currency": "GBP",
"compare_at_price": 60,
"discount_pct": 25,
"price_min": 45,
"price_max": 45,
"variant_count": 12,
"available_variants": 8,
"featured_image": "https://cdn.shopify.com/s/files/1/0001/products/shorts.jpg",
"variants": [
{
"title": "M / Black",
"option1": "M",
"option2": "Black",
"price": 45,
"sku": "GS-TS-M-BLK",
"available": true
}
],
"scraped_at": "2026-07-27T10:15:00.000Z"
}

Why there is no review or sales data

reviews_count, rating, review_app and the estimated_sales_* fields were removed in build 1.0.25. They are not "coming back later" — they were removed because they could not be delivered honestly:

  • Coverage was a coin flip. Reading review counts needs one extra page request per product (a 100x increase in requests against a store), and even then it only works when the theme prints the numbers into the HTML. Measured over 60 products on four live stores: 0% coverage on one store, 13% on another, 60% and 80% on the other two. 62% of rows were empty overall.
  • The extra per-product requests broke runs. That request amplification is what tripped Shopify's per-shop rate limit and caused zero-result runs, which is why the option had to be switched off by default — after which the fields were null on 100% of real customer rows.
  • Where it was populated, it was often wrong. Sibling colourways shared one family-level number (three different products each reporting the same 281 reviews), and on one store a shop-wide total of 1,365 was attached to two unrelated bundle products as if it were theirs.
  • The sales numbers were an estimate of an estimate. They were just reviews_count / 2%, so they inherited every error above and multiplied it by 50 — turning that bogus 1,365 into "68,250 units sold" on two products at once.

A null that might mean "no reviews" or "we could not read it", next to a number that might be this product's or its whole catalogue's, is worse than no column at all. If you need Shopify review data, scrape it from the review provider directly.


Discovery Mode

Find Shopify stores from the cro.media directory (321,567+ stores, updated daily), filterable by 112 categories.

Available Categories (112 total)

CategorySubcategories
Fashionshoes, jewellery, bags, lingerie, outerwear, swimwear, activewear, kids
Beauty & Skincareserum, mask, cleanser, sunscreen, acne, toner, exfoliant
Haircareshampoo, conditioner, styling, tools
Food & Grocerysnack, candy, bakery, meat, seafood, vegan, organic, glutenfree, coffee, tea, alcohol
Electronicsphone, computer, camera, audio, wearable
Home & Livingfurniture, lighting, decor, storage
Kitchenappliance, cookware, utensil, storage, tableware, drinkware
Sportsequipment, clothing
Petsfood, accessory, health
Baby & Infantclothing, gear, feeding, toys
Beddingblanket, sleepwear, mattress, pillow, duvet
Morebathroom, bath-body, dental, eyewear, watches, bags, accessories, books, music, art, crafts, gifts, flowers, outdoors, automotive, tools, office, safety, cleaning, energy

Use the category slug in input (e.g., "fashion/shoes", "food/coffee", "skincare").

Discovery Output

{
"domain": "cortezcoffee.com",
"store_name": "Cortez Coffee Roasters",
"shopify_theme": "Shapes",
"store_url": "https://cortezcoffee.com",
"category": "food/coffee",
"discovered_at": "2026-02-17T20:08:38.291Z"
}

Input Parameters

ParameterDefaultDescription
modeurlurl = scrape specific stores, discovery = find stores from directory
storeUrls-Shopify store URLs to scrape (URL mode, required)
maxProducts100Max products for the whole run, shared across all store URLs; 0 = unlimited
category(empty)Store category filter for discovery mode (e.g., fashion, food/coffee)
maxStores1000Max stores to discover (discovery mode)
maxPages10Max directory pages to scrape, ~300 stores/page (discovery mode)
proxyConfigurationApify proxyProxy settings; datacenter by default, auto-escalates to residential when a store throttles

Use Cases

1. Competitor Product Monitoring

Track competitor prices and inventory:

{ "storeUrls": [{ "url": "https://gymshark.com" }, { "url": "https://allbirds.com" }], "maxProducts": 0 }

2. Dropshipping Product Research

Scrape full catalogues from trending stores and rank products by price, discount depth and how many variants are still in stock.

3. Shopify Store Discovery

Find all stores in a niche category:

{ "mode": "discovery", "category": "food/vegan", "maxStores": 5000, "maxPages": 20 }

4. Lead Generation

Discover stores by category, export domains, and use for outreach campaigns.


API Integration

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
// Scrape products
const run = await client.actor('webdatalabs/shopify-scraper-pro').call({
storeUrls: [{ url: 'https://gymshark.com' }],
maxProducts: 50
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items); // Array of products

Technical Details

  • Products: Shopify public JSON API (/products.json), no auth required
  • Host resolution: both www. and the apex domain are tried before a store is judged
  • Discovery: HTTP + Cheerio parsing of cro.media directory (no browser needed)
  • Proxy: every request goes through Apify Proxy; a throttled or blocked request is retried on a fresh IP and escalated to residential
  • Rate limiting: 0.5 s between catalogue pages, exponential backoff on HTTP 429

What happens when a store cannot be scraped

SituationWhat the run does
Store throttled/blocked and 0 products deliveredRun fails with the HTTP status and the hosts tried
Catalogue cut short mid-wayRun reports PARTIAL in the log and in OUTPUT; the reported total is what actually landed in the dataset
URL is not a Shopify storeRun succeeds with 0 items, logs NOT_SHOPIFY and the evidence (server headers, HTTP status)
Headless (Hydrogen/Oxygen) storefrontRun succeeds with 0 items and says the store does not expose /products.json
Password-protected storefrontRun succeeds with 0 items and says the storefront is locked

Pricing

Pay-Per-Event: Transparent pricing per product scraped or store discovered.

See current pricing in the Apify Console.


FAQ

Does URL mode require authentication? No, it uses Shopify's public /products.json API.

Does it return reviews, ratings or sales estimates? No. Those fields were removed in build 1.0.25 because they could not be produced accurately - see Why there is no review or sales data. This actor returns catalogue, pricing, variant and inventory-availability data only.

Why did my run return 0 products? Check the OUTPUT record in the key-value store and the run log: every store URL gets a status and a reason (not a Shopify store, headless storefront, password protected, empty catalogue, blocked or rate-limited). A blocked or rate-limited run fails rather than reporting success.

How many stores are in the discovery directory? 321,567+ stores, updated daily by cro.media. Filterable by 112 categories.

Can I schedule recurring runs? Yes, use Apify's scheduler or integrate with n8n/Zapier/Make.


ActorDescription
Shopify Store IntelligenceDeep store analysis with tech stack, apps, pricing strategy
Etsy Scraper ProEtsy products with ratings, reviews, shop data
Amazon Reviews ScraperAmazon customer reviews for sentiment analysis
Reddit Scraper ProMonitor subreddits and track keywords

Need this data as a managed feed?

If you would rather receive this data on a schedule than run the Actor yourself, we can build and operate the feed: the fields you specify, the cadence you set, delivered to a dataset, S3, a webhook, or your database. Every scheduled run is checked against an agreed shape rather than assumed to be fine, missing values are reported as null instead of filled with placeholders, and repairing the collector when the source changes is covered by the monthly rate. Priced as a one-time setup fee plus a monthly rate, scoped in writing before anything is built.

Contact: support@webdatalabs.net

Support

Leave a review

Is this actor saving you time? A quick review on the Store helps other people find it — and tells us which fields to add next. Rate this actor →

This actor is a general-purpose tool for analyzing publicly accessible web data. The user bears sole responsibility for ensuring their specific use complies with applicable laws, the target website's Terms of Service, and Apify's Terms of Service. The provider (webdatalabs) expressly disclaims liability for any unauthorized or unlawful use.


This tool is not affiliated with Shopify or cro.media. All trademarks belong to their respective owners.

Built by WebDataLabs | Website | More Actors


SEO Keywords

Shopify scraper, Shopify product scraper, Shopify data extractor, Shopify price scraper, Shopify inventory scraper, Shopify variant scraper, Shopify competitor analysis, Shopify dropshipping tool, Shopify catalog export, Shopify store finder, Shopify store directory, find Shopify stores, Shopify market research, Shopify store discovery, Shopify category search, scrape Shopify products