Shopify Store Scraper avatar

Shopify Store Scraper

Pricing

$19.99/month + usage

Go to Apify Store
Shopify Store Scraper

Shopify Store Scraper

Shopify Store Scraper collects publicly available data from Shopify stores, including products, collections, descriptions, and store metadata. Use it for research, analytics, or data aggregation. Built for speed, accuracy, and scalable scraping workflows.

Pricing

$19.99/month + usage

Rating

0.0

(0)

Developer

Scraper Engine

Scraper Engine

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

0

Monthly active users

2 days ago

Last modified

Share

Shopify Store Scraper — Catalogue, Theme, Apps and Pricing Data

Shopify Store Scraper turns any public Shopify storefront address into a structured store profile plus one row per product: real myshopify domain, theme identity, installed apps and web pixels, full catalogue size, collection count, price range and stock coverage — returned as typed JSON, no HTML parsing required. Give it a list of store URLs and get a clean dataset ready for a spreadsheet, CRM import or competitor-tracking pipeline. Run it on Apify to see a live profile in under a minute.

What is Shopify Store Scraper?

Shopify Store Scraper is an Apify Actor that reads a public Shopify storefront the way a visitor's browser would — its homepage, meta.json, products.json and collections.json — and turns that into one structured store row plus one row per product read. It needs no Shopify account, no app install and no API key: every field comes from data the storefront itself publishes to any visitor. It's built for e-commerce researchers, growth and competitive-intelligence teams, lead-gen agencies and developers wiring Shopify data into a pipeline or AI agent.

What Shopify store data is publicly available to scrape?

Everything a storefront serves to an anonymous visitor — theme, catalogue, collections, checkout configuration — is publicly readable. Data behind the merchant's own login (Shopify Admin) or a store's own password gate is not.

Data categoryPublicly availableRestricted
Store identity (name, city, currency, ships-to list)✅ via meta.json
Theme identity, version, role✅ embedded in storefront markupTheme source files — Shopify Admin login
Installed apps & web pixels✅ inferred from public markup signalsFull app roster — Shopify Partner/Admin dashboard
Product catalogue (title, price, variants, images)✅ via products.json, when the store exposes itDraft/unpublished products
Collections index✅ via collections.json, when the store exposes it
Storefront contentPassword-protected stores need the store's own password
Order volume, revenue, customer recordsShopify Admin login only
Discount codes, private sale termsMerchant account

Shopify Store Scraper only returns publicly visible data — what any visitor sees. Nothing behind a login wall.

What data can I extract with Shopify Store Scraper?

Each run returns one store row carrying identity, theme, app and catalogue-economics data, and one product row per product actually read from the catalogue.

🏬 Store identity and theme fields

Field nameDescription
store_domain, store_urlThe address that was profiled
shop_name, myshopify_domainThe store's real *.myshopify.com identity
shop_idThe merchant's numeric shop id
store_name, store_descriptionMerchant-declared store name and description
store_city, store_province, countryMerchant-declared location
currency, money_format, active_currency, currency_rateBase currency, price formatting string, rendered currency and rate
localeStorefront locale (e.g. en-US)
ships_to_countries, ships_to_countries_countCountry list and count the store ships to
accepted_card_brands, offers_shop_pay_installmentsCheckout capabilities
theme_schema_name, theme_name, theme_id, theme_version, theme_role, theme_store_idThe theme actually running, plus the merchant's own working label for it
apps_installed, apps_by_source, apps_countDeduplicated app handles, split by evidence source, and the count
pixel_app_client_ids, pixel_countWeb pixel registry client ids and entry count

📊 Catalogue and commerce metric fields

Field nameDescription
total_products, published_products_countProducts actually read vs. what the store reports as published
catalog_complete, catalog_pages_readWhether the catalogue read finished, and how many reads it took
total_variants, total_variants_available, inventory_availability_pctVariant totals and in-stock share
collections, collections_count, published_collections_count, collections_complete, collections_pages_readThe full collection index and its cross-check against the store's own count
product_types, vendorsDistinct product types and vendors in the catalogue
price_min, price_avg, price_maxComputed across every variant read
products_on_sale, discount_pct_avg, max_discount_pctDiscount depth, null when nothing is discounted
oldest_product_date, newest_product_dateCatalogue age and freshness
products_with_images, avg_images_per_product, products_with_descriptionListing quality signals
newest_productsThe 10 most recently created products (title, handle, URL, price, date)

🛒 Product row fields (per product)

Field nameDescription
position1-based rank, newest product first
product_id, title, handle, product_urlProduct identity and link
vendor, product_type, tagsMerchant-set classification
price, price_max, currencyMin and max variant price, in the store's base currency
variant_count, variants_available, in_stockVariant count and stock coverage
image_count, image_urlImage count and the first image URL
created_at, updated_at, published_atProduct lifecycle timestamps

🤖 Add-on: Need additional Shopify data?

If you need the complete per-product variant breakdown (every SKU, option and per-variant price) rather than the summary carried on each product row, pair this Actor with Shopify Products Scraper. For merchant contact and lead-generation fields — emails, phone numbers, social profiles — pair it with Shopify Merchant Scraper. Both are Scraper Engine Actors and slot into the same store-URL input.

Why not build this yourself?

Shopify's own APIs are scoped to the store that issues the credentials — the Storefront API needs a token the store itself generates, and the Admin API needs the merchant's own app installation. Neither lets a third party pull another store's theme identity, app stack or catalogue economics. Building this yourself means writing and maintaining an HTML/JSON scraper: handling products.json pagination past the default page ceiling, detecting password gates and non-Shopify domains, parsing theme globals out of inline <script> blocks, and re-routing requests when a storefront starts blocking your IP. Shopify Store Scraper already does that: it walks the full catalogue and collection index page by page, classifies every storefront into one of five real states instead of returning a blank row, and re-routes through Apify Proxy tiers when a request is throttled.

🧭 How to use Shopify Store Scraper

Running it takes one required input — everything else is optional.

  1. Open Shopify Store Scraper on the Apify Store and click Try for free (or Run, if you already have it saved).
  2. Provide startUrls — one or more Shopify storefront addresses. A bare domain like allbirds.com works; it gets normalised automatically.
  3. Optionally set maxProducts to cap how many products are read per store, or leave it at 0 to read the entire catalogue.
  4. Optionally set proxyConfiguration if your account needs routed traffic.
  5. Start the run, then download or stream the resulting dataset as JSON, CSV, Excel, or via API.

How to scale to bulk store extraction

startUrls is an array — list as many storefront addresses as you want profiled in a single run. Each store is read independently: one store failing does not affect the others, and every row is pushed to the dataset as soon as it is ready, so a stopped run still keeps everything already collected. There is no separate "bulk" input mode — a longer startUrls list is the bulk path.

What can you do with Shopify store data?

  • 🏢 Competitive intelligence teams use price_min, price_avg and discount_pct_avg to benchmark a rival's pricing and promotion depth without opening every product page by hand.
  • 📈 Growth and martech teams use apps_installed and apps_by_source to see which review, SMS, upsell or analytics apps a competitor actually runs.
  • 🎯 Sales and lead-gen teams use total_products, collections_count and theme_schema_name to qualify a Shopify prospect list before spending a call on it.
  • 🔬 Market researchers use product_types, vendors and inventory_availability_pct to map category coverage and stock depth across a niche.
  • 🤖 AI engineers feed store_description, product_types, vendors and the catalogue price fields into a RAG index or agent tool to answer questions like "which competitor sells running shoes under $80."

How does Shopify Store Scraper handle rate limits and blocking?

Requests go out as plain HTTP GETs through a per-run fetcher. When no proxy is configured, requests go direct. When proxyConfiguration is set and a request comes back 403, 429, 502, 503 or 504, the fetcher escalates through a routing ladder — first to a shared Apify Proxy route, then to a residential proxy group — retrying up to 3 times with a short pause between attempts. Catalogue and collection pagination gets one deliberate extra retry before a page is treated as the end of the list, so a single hiccup can't be mistaken for "the catalogue ended here." If a store never answers at all, its row is reported as unreachable rather than the run failing, and every other store in the same run is unaffected.

⚠️ The scraper reads only what a storefront serves over plain HTTP — it does not run a browser or execute JavaScript. A store whose catalogue is not exposed at products.json reports storefront_status: "catalog_unavailable" rather than an error.

⬇️ Input

ParameterRequiredTypeConstraintsDescription
startUrlsYesarrayeditor: stringListOne or more Shopify storefront addresses. A bare domain works too (allbirds.com). Example: https://www.allbirds.com
maxProductsNointegerdefault: 0, minimum: 0How many product rows to return for each store address. Enter 10 and you get 10 products per store; enter 500 and you get 500 (or all of them, if the store publishes fewer). Set 0 to return the entire catalogue. Bigger catalogues take longer: a 6,478-product store needs 26 reads. Each store also gets one summary row, and its statistics are computed from the products actually returned.
proxyConfigurationNoobjecteditor: proxy, default { "useApifyProxy": false }Optional. Leave disabled unless your account requires routed traffic.

Example input

{
"startUrls": [
"https://www.allbirds.com",
"https://rothys.com"
],
"maxProducts": 25,
"proxyConfiguration": {
"useApifyProxy": false
}
}

⬆️ Output

Every run produces typed, normalized JSON with a stable field set across runs — no field appears with different types between runs, and a field that cannot be measured is null, never a zero or placeholder. Download results as JSON, CSV, Excel, HTML table or RSS from the dataset, or pull them with the API. Two row shapes appear in the same dataset, distinguished by type and isChild: one store row per address in startUrls, and one product row per product actually read from that store's catalogue.

Example output — store row

{
"type": "store",
"isChild": false,
"store_domain": "www.allbirds.com",
"store_url": "https://www.allbirds.com",
"storefront_status": "open",
"shop_name": "weareallbirds.myshopify.com",
"myshopify_domain": "weareallbirds.myshopify.com",
"shop_id": 11044168,
"store_name": "Allbirds",
"store_description": "Sustainable, comfortable shoes and apparel.",
"store_city": "San Francisco",
"store_province": "California",
"country": "US",
"currency": "USD",
"money_format": "${{amount}}",
"active_currency": "USD",
"currency_rate": 1.0,
"locale": "en-US",
"ships_to_countries": ["US"],
"ships_to_countries_count": 1,
"accepted_card_brands": ["visa", "master", "american_express", "discover"],
"offers_shop_pay_installments": true,
"theme_schema_name": "allbirds-theme",
"theme_name": "[DNAM Theme July 2026]",
"theme_id": 123456789,
"theme_version": "1.231.12",
"theme_role": "main",
"theme_store_id": null,
"apps_installed": ["Google Analytics 4", "Klaviyo", "Shop Pay", "PayPal"],
"apps_by_source": {
"theme_app_extension": ["redo"],
"app_proxy": ["attentive"],
"storefront_signal": ["Google Analytics 4", "Klaviyo", "PayPal", "Shop Pay"]
},
"apps_count": 5,
"pixel_app_client_ids": [2509311, 3426665],
"pixel_count": 8,
"total_products": 291,
"published_products_count": 291,
"catalog_complete": true,
"catalog_pages_read": 2,
"total_variants": 3084,
"collections": ["Best Sellers", "Men", "Women"],
"collections_count": 1345,
"published_collections_count": 1345,
"collections_complete": true,
"collections_pages_read": 6,
"product_types": ["Shoes", "Apparel"],
"vendors": ["Allbirds"],
"price_min": 18.0,
"price_avg": 89.53,
"price_max": 265.0,
"products_on_sale": 155,
"discount_pct_avg": 44.26,
"max_discount_pct": 60.0,
"total_variants_available": 1908,
"inventory_availability_pct": 61.9,
"oldest_product_date": "2018-02-08",
"newest_product_date": "2026-08-05",
"products_with_images": 291,
"avg_images_per_product": 4.2,
"products_with_description": 288,
"newest_products": [
{
"title": "Tree Runner Go",
"handle": "tree-runner-go",
"url": "https://www.allbirds.com/products/tree-runner-go",
"price": 98.0,
"created_at": "2026-08-05T00:00:00-07:00"
}
],
"scraped_at": "2026-08-15T00:00:00+00:00",
"scrape_duration_sec": 4.31
}

Example output — product row

{
"type": "product",
"isChild": true,
"store_domain": "www.allbirds.com",
"store_url": "https://www.allbirds.com",
"position": 1,
"product_id": 7834521098,
"title": "Tree Runner Go",
"handle": "tree-runner-go",
"product_url": "https://www.allbirds.com/products/tree-runner-go",
"vendor": "Allbirds",
"product_type": "Shoes",
"tags": ["running", "new-arrival"],
"price": 98.0,
"price_max": 98.0,
"currency": "USD",
"variant_count": 6,
"variants_available": 4,
"in_stock": true,
"image_count": 5,
"image_url": "https://cdn.shopify.com/s/files/1/example/tree-runner-go-1.jpg",
"created_at": "2026-08-05T00:00:00-07:00",
"updated_at": "2026-08-10T00:00:00-07:00",
"published_at": "2026-08-05T00:00:00-07:00",
"scraped_at": "2026-08-15T00:00:00+00:00"
}

Storefront status — what each value means

storefront_statusWhat happenedWhat the row still carries
openThe storefront publishes its catalogue dataEverything
password_protectedThe merchant has the storefront closed behind a password pageIdentity fields resolvable from meta.json; catalogue fields are null
catalog_unavailableA real Shopify storefront that does not expose products.jsonIdentity and theme/app signals where present; catalogue fields are null, never 0
not_shopifyNo Shopify storefront detected at that addressThe address and the status
unreachableThe storefront did not answerThe address and the status

⚠️ Every row pushed to the dataset — including unreachable, not_shopify and password_protected rows — is billed as one row_result charged event, same as an open store. Filter your startUrls list to addresses you've confirmed are live Shopify stores to avoid paying for addresses that resolve to nothing.

How does it work?

Shopify Store Scraper requests each storefront's homepage and meta.json in parallel over plain HTTP, using a browser-like set of headers — no headless browser, no JavaScript execution. It reads the response to decide which of five storefront states applies (open, password-protected, catalogue unavailable, not Shopify, or unreachable), then walks products.json and collections.json in pages of 250 items until a genuinely empty page is returned, deduplicating by product id along the way. Theme identity, currency and locale are parsed out of the Shopify.* globals embedded in the page markup, and installed apps are inferred from three independent evidence sources in that same markup — a theme-app-extension asset path, an app-proxy link, or a known vendor script signature — rather than from a single guess. Because every field is read from the storefront's own published data rather than derived from page layout, the output schema stays the same shape even when a store's theme or design changes.

Integrations

Shopify Store Scraper runs like any other Apify Actor, so it fits into workflows you already use.

Calling Shopify Store Scraper programmatically

from apify_client import ApifyClient
client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("shopify-store-scraper").call(run_input={
"startUrls": ["https://www.allbirds.com"],
"maxProducts": 25,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request.

No-code tools (n8n, Make, LangChain)

In n8n, use the Apify node (or an HTTP Request node against the Apify API) to start a run and read back the dataset. In Make, the Apify app's "Run an Actor" module does the same, with the dataset items feeding directly into the next module. In LangChain or a custom agent framework, wrap the apify_client call above as a tool so an agent can request a fresh store profile on demand.

Scraping publicly available business and product data — the kind Shopify Store Scraper collects — is generally lawful in most jurisdictions; this is not personal data about identifiable individuals, so GDPR and CCPA do not attach to it. Shopify Store Scraper returns only data that a storefront publishes to any visitor, no login and no bypass of a password gate involved. What does apply is the storefront's own terms of service and, in some jurisdictions, database-rights protections over compiled catalogue data — review a store's terms before large-scale or commercial use of its data. Consult legal counsel if your use case involves bulk storage of personal data.

❓ Frequently asked questions

What Shopify store fields does Shopify Store Scraper return?

The top fields are store_name, theme_schema_name, apps_installed, total_products and price_avg on the store row, plus title, price and in_stock on each product row. See What data can I extract for the full field tables.

Does Shopify Store Scraper require a Shopify account or login?

No. It reads only data a storefront serves to an anonymous visitor over plain HTTP — no Shopify account, API key or app installation is needed.

How many products can I extract in one run?

Set maxProducts to a specific number to cap it per store, or leave it at the default 0 to read a store's entire published catalogue. catalog_complete on the store row tells you whether the read reached the true end of the catalogue or stopped at your cap.

What happens if a store is password-protected or doesn't publish its catalogue?

The row is still returned, labelled honestly. storefront_status reports password_protected when the merchant has the store gated, or catalog_unavailable when a real Shopify storefront doesn't expose products.json. Catalogue fields are null in both cases — never 0, which would misrepresent "we don't know" as "there are none."

Can I scrape multiple Shopify stores at once?

Yes. startUrls accepts an array of storefront addresses; each is profiled independently in the same run, and one store failing does not affect the others.

Does Shopify Store Scraper work with Claude, ChatGPT and other AI agent tools?

It's callable as an HTTP endpoint by any agent framework that can make an API call — wrap the apify_client call shown under Integrations as a tool function for Claude, ChatGPT function calling, LangChain or a custom agent loop.

How does Shopify Store Scraper differ from a plain product-catalogue scraper?

Most Shopify scrapers return only product rows. This one adds a store-level profile in the same run — theme identity, installed apps and web pixels, collection index size, and honest classification of closed or unreachable storefronts — alongside a product row for every item read from the catalogue.

Does Shopify Store Scraper return data in a format LLMs can use directly?

Yes. Typed, normalized JSON with consistent field names across runs — no HTML parsing, no CSS selectors. Pass it directly to an LLM prompt, index it into a vector store, or feed it to an agent tool.

What happens when Shopify changes its storefront layout or blocking rules?

The scraper is maintained, and the output schema stays stable across storefront redesigns because fields are read from the store's own published data (meta.json, products.json, theme globals) rather than from page layout. No specific update turnaround time is published.

Can I use Shopify Store Scraper without managing proxies or browser infrastructure?

Yes. The Actor makes its own requests and, when proxyConfiguration is enabled, routes through Apify Proxy on your behalf — you don't provision or manage proxy or browser infrastructure yourself.

Which fields work best for RAG indexing and AI training data?

For RAG, index the free-text fields — store_description, product_types, vendors and title — since they carry the most retrievable context. For structured training data, the consistently typed numeric and boolean fields — price_min, price_avg, price_max, total_products, in_stock and catalog_complete — return as typed primitives across every run.

Scraper nameWhat it extracts
Shopify Products ScraperA store's full product catalogue — every product with its complete variant list, SKUs, per-variant availability, price range and image URLs
Shopify Merchant ScraperB2B lead data per store — verified merchant identity, emails, phones, social profiles, plus product/collection counts and tech stack
Shopify ScraperProduct data from individual Shopify homepages, collections or single product pages

💬 Your feedback

Found a bug or missing a field? Let us know through the Actor's Issues tab on the Apify Console, or contact Scraper Engine support directly — reports like this are how the field set stays accurate as Shopify's own storefront markup evolves.