To scrape a Shopify store, point a Shopify scraper at the store's home page, a collection or a product URL, and it reads the store's public product data and saves one row per product: title, brand, every variant with its price and stock status, the sale price, SKUs, weights, images and tags. On Scrape.ly that's the Shopify Scraper. It works on any public Shopify storefront without a login or API key, and it costs $0.50 per 1,000 products.
This guide covers the fields, the no-code steps, the API (curl, Python, Node.js and MCP), the cost and the pitfalls. Everything comes from a real run on 23 October 2026: men's shoes between $50 and $150 from Allbirds, 10 products and 130 variants in 6 seconds.
What data you can get from a Shopify store
The Shopify Scraper writes one row per product. A /collections URL returns one row per collection instead.
| Field | What it holds |
|---|---|
source | Store product ID, canonical URL, retailer name, language, currency, and created, updated and published timestamps |
title, brand, categories, tags | Product identity, including the store's own tags |
description | The product description as HTML |
price.current, price.previous | Current price and compare-at (pre-sale) price, in minor units |
price.stockStatus | InStock, OutOfStock or LowInStock |
priceRange | Lowest and highest variant price, and whether they differ |
options | Option names and values, such as every size |
variants[] | Per variant: ID, title, SKU, options, price, stock status, weight in grams, taxable and requires-shipping flags |
medias[] | Product images with URL and alt text |
fullyOutOfStock | true when every variant is sold out |
Prices are integers in minor units: 14000 means 140.00 in source.currency. Product pages add barcodes, tax codes and per-size availability. Opt-in extras add real stock counts (grabRealInventory), related products (maxRecommendationsPerProduct), selling plans and videos (grabStorefrontDetail) and information panels such as materials or care (grabContentSections).
How to run the Shopify scraper without code
- Open the Actor's page in the Scrape.ly Store and sign in.
- Pick a ready-made input. We ran the preset Allbirds men's shoes, 50 to 150 USD, 10 products. "Try this input" opens it in the console.
- Swap in the store or collection you want to track. This is the exact input of our run:
{
"startUrls": [{ "url": "https://www.allbirds.com/collections/mens" }],
"minPrice": 50,
"maxPrice": 150,
"maxResults": 10
}- Click Start. Our run took 6 seconds.
- Export the products as JSON, CSV or Excel.
The fields that matter most:
startUrls(required): a store home page crawls the whole catalog, a collection URL crawls that collection, a product URL saves that product, and a URL ending in/collectionslists the store's collections. Several stores can go in one run.maxResults: records to save for the whole run (default 10).0means no limit, so set a maximum charge first.minPrice,maxPrice: a price window in the store's currency (140means 140.00), applied to the lowest variant.query: search each store for a keyword instead of crawling the URL path. It uses the store's public suggestions and returns at most 10 products per store.- Extras: the preset Palettes with stock counts turns on real inventory; Kith tops with recommendations adds related products and storefront details.
To read prices in another currency, add ?currency=EUR to the start URL or use a locale path such as /en-gb/.
How to scrape Shopify products with the API
Create an API token under Settings → API & Integrations and export it as SCRAPELY_TOKEN. The Actors API docs list every endpoint.
curl. A 10-product run takes seconds, well inside the 45-second limit of the synchronous endpoint, which returns the products as a JSON array (add ?format=csv for CSV):
curl -X POST "https://api.scrape.ly/v2/actors/shelfbright~shopify-scraper/run-sync-get-dataset-items" \
-H "Authorization: Bearer $SCRAPELY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"startUrls": [{"url": "https://www.allbirds.com/collections/mens"}], "minPrice": 50, "maxPrice": 150, "maxResults": 10}'For a full catalog, use the asynchronous flow (/runs, then /v2/actor-runs/RUN_ID?waitForFinish=60) or one of the clients: a 10,000-product store took about 22 minutes in the publisher's test.
Python (pip install scrapely-client-python). call() waits however long the run takes. This example prints price, sale price and how many sizes are in stock, the three numbers a competitor tracker needs:
import os
from scrapely_client import ScrapelyClient
client = ScrapelyClient(os.environ["SCRAPELY_TOKEN"], api_url="https://api.scrape.ly")
run = client.actor("shelfbright/shopify-scraper").call(
run_input={"startUrls": [{"url": "https://www.allbirds.com/collections/mens"}],
"minPrice": 50, "maxPrice": 150, "maxResults": 10}
)
print(run.status) # SUCCEEDED, FAILED, ABORTED or TIMED-OUT
for p in client.dataset(run.default_dataset_id).iterate_items():
price = p["price"]["current"] / 100
was = p["price"]["previous"] / 100 or None
in_stock = sum(v["price"]["stockStatus"] != "OutOfStock" for v in p["variants"])
print(f'{price:7.2f} was {was or "-":>6} {in_stock:2}/{len(p["variants"])} sizes {p["title"]}')Node.js (npm install scrapely-client):
import { ScrapelyClient } from 'scrapely-client';
const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN, baseUrl: 'https://api.scrape.ly' });
const run = await client.actor('shelfbright/shopify-scraper').call({
startUrls: [{ url: 'https://www.allbirds.com/collections/mens' }],
minPrice: 50,
maxPrice: 150,
maxResults: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((p) => [p.title, p.price.current / 100, p.price.stockStatus, p.source.canonicalUrl]));AI agents (MCP). Add the hosted Scrape.ly MCP server. In Cursor, put this in ~/.cursor/mcp.json:
{
"mcpServers": {
"scrapely": {
"url": "https://api.scrape.ly/mcp",
"headers": { "Authorization": "Bearer YOUR_TOKEN" }
}
}
}In Claude Code, run claude mcp add --transport http scrapely https://api.scrape.ly/mcp and sign in with /mcp. Then ask: "Use scrapely to run shelfbright/shopify-scraper on https://www.allbirds.com/collections/mens, 20 products, and give me a table of product, price, sale price and sizes in stock." The agent reads the input with fetch-actor-details, runs it with call-actor and reads the rows with get-actor-output. The Shopify API page shows the same Actor as an API product.
A real run: Allbirds men's shoes from $50 to $150
We ran the preset on 23 October 2026. It saved 10 products in 6 seconds of run time and was charged $0.0059. The first five:
| Product | Price | Was | Sizes in stock | Status |
|---|---|---|---|---|
| Men's Dasher NZ - Anthracite (Dark Anthracite Sole) | $140.00 | – | 6 of 13 | InStock |
| Men's Dasher NZ - Light Burnt Olive (Natural White Sole) | $140.00 | – | 4 of 13 | InStock |
| Men's Dasher NZ - Blizzard (Blizzard Sole) | $140.00 | – | 13 of 13 | InStock |
| Men's Dasher NZ - Blizzard/Deep Navy (Blizzard Sole) | $140.00 | – | 0 of 13 | OutOfStock |
| Men's Dasher NZ - Dark Eucalyptus (Dark Eucalyptus Sole) | $99.00 | $140.00 | 9 of 13 | InStock |
What the full run shows:
- One product line, many rows. Eight of the ten products were colorways of the Dasher NZ at $140; the other two were Cruiser canvas shoes at $75. Allbirds lists each colorway as its own Shopify product, so a "product" in Shopify terms is often a single color.
- Stock is the real signal. The ten products had 130 size variants (sizes 8 to 15), and 73 of them, 56%, were in stock. One colorway was sold out in every size, two were in stock in all 13.
- Sales show up as fields. One colorway was marked down to $99 from $140, which you see in
price.previouswithout parsing a strikethrough price. - Variants carry SKUs and weights. Every size has its own SKU and shipping weight (914 g for a US 8 of the first shoe), which is what you need to match products across retailers.
- Tags reveal the store's taxonomy. Allbirds' tags include its internal material, silhouette and price-tier labels, useful for grouping a competitor's catalog the way they do.
The log, without the platform's start-up lines:
2026-10-23T03:02:29.106Z [Scrapely] Container started (setup 2.0 s)
2026-10-23T03:02:30.418Z [scrapely.proxy_configuration] INFO Platform proxy access check succeeded.
2026-10-23T03:02:32.596Z [scrapely.actor] INFO Saved 10 products and 0 collections. datacenter_bytes=76252 residential_bytes=0
2026-10-23T03:02:33.362Z [Scrapely] Container state: status=exited exitCode=0 oomKilled=falseReading the collection and saving ten products took about 2 seconds over the default datacenter proxy, using 76 KB of traffic and no residential bandwidth.
What it costs
The Actor charges $0.0005 per product saved ($0.50 per 1,000). Extras are separate opt-in events: $0.0003 per product with a real stock count, $0.0003 per nested related product, $0.0003 per collection row and $0.0001 per product with information panels. Platform usage (compute and storage) is billed on top.
For our run: 10 products × $0.0005 = $0.005 in product fees. The run was charged $0.0059 in total: $0.0008 of compute, $0.00005 of dataset writes and $0.00001 of proxy traffic. A 1,000-product catalog costs $0.50 in product fees; a product reached twice in the same run is saved and charged once. A store that doesn't publish stock counts isn't charged for inventory.
What to watch out for when scraping Shopify stores
- Not every store is Shopify. On a site that isn't, the run succeeds, saves nothing and says so in the status line, so a wrong URL costs you nothing in product fees.
- Password-protected storefronts are skipped. Only public stores can be read.
- Prices are in minor units. Divide by 100 for dollars and euros, and check
source.currencybefore you compare stores. - Stock counts are not stock status. Every variant comes with in stock or out of stock. A number of units only appears with real inventory on and when the store publishes one;
LowInStockmeans a real count of 1 to 5. maxResultsis per run. It counts across all stores in the input, not per store.- Keyword search is for spot checks.
queryuses the store's own search suggestions, which return up to 10 products per store. Crawl a collection or the home page when you need everything. - Datacenter first. Datacenter proxies are the default and were enough here. Switch to residential only if a store refuses datacenter addresses.
Is it legal to scrape a Shopify store?
The Actor reads only public product data, the same catalog any shopper sees, and it skips password-protected stores. Product titles, prices, variants and stock status are commercial facts about products, not personal data, which makes catalog scraping one of the lower-risk kinds of scraping.
Each store has its own terms of service, and they may set rules for automated access or reuse of descriptions and images. Read the terms of the stores you track before you build a product on their data. Product photos and descriptions are usually copyrighted, so use them for analysis rather than republishing them. Keep your request volume modest; the Actor's defaults are light, as the 76 KB in our log shows. This is general information, not legal advice: for commercial use, ask a lawyer about your case.
Why Scrape.ly for Shopify data
- One input for every store. Bright Data's Python tutorial appends
/products.jsonto a store URL and pages through it by hand. That works store by store, but you write the pagination, price conversion, stock logic and retries yourself. The Actor takes any store, collection or product URL and returns the same fields every time. - The official API isn't built for this. Shopify's Storefront API answers product queries without a token, but product tags and metafields need an access token (shopify.dev), and you write GraphQL queries per store. The Actor returns tags, variants and stock with no token and no queries.
- Cheap enough to run daily. $0.50 per 1,000 products, and our run cost $0.0059. Schedule a competitor's collection every morning and send the rows to Google Sheets or a webhook.
- Part of a full pricing stack. Combine Shopify stores with the Google Shopping Scraper, Amazon and eBay, as in our price scraping guide. For marketplace sellers, the eBay guide adds condition and sold counts.
FAQ
Can you scrape any Shopify store?
Any public Shopify storefront, yes. Password-protected stores are skipped, and sites that aren't Shopify return nothing (and cost nothing in product fees). Paste a home page for the full catalog, a collection or a single product.
How do I scrape Shopify products with Python?
Install scrapely-client-python, call shelfbright/shopify-scraper with startUrls and maxResults, and iterate over the dataset, as in the example above. Divide prices by 100 to get dollars.
Can I scrape Shopify stock levels?
Every variant comes with a stock status. Turn on Real inventory counts (grabRealInventory) to add the number of units per variant when the store publishes it, at $0.0003 per product that has one.
Does a Shopify store's products.json still work?
On many stores, yes: Allbirds' /products.json returned products when we checked on 23 October 2026. It gives you raw JSON one page at a time. The Shopify Scraper reads the store's public product data for you and returns clean, filtered rows with stock status per variant.
How much does it cost to scrape a Shopify store?
$0.50 per 1,000 products, plus small usage and any extras you turn on. Our 10-product run was charged $0.0059. The Free plan's $5 of monthly credit covers about 10,000 products in product fees.




