Shopify Merchant Scraper: Market Currency & Shipping Data
Pricing
from $1.55 / 1,000 results
Shopify Merchant Scraper: Market Currency & Shipping Data
Scrape Shopify merchant data including market currencies, shipping zones, delivery options, store details, product pricing, and regional settings. Ideal for e-commerce research, competitor analysis, market expansion, and international Shopify store insights.
Pricing
from $1.55 / 1,000 results
Rating
0.0
(0)
Developer
Scrapio
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Shopify Merchant Scraper β Leads, Market Currency & Shipping Data
Turn a list of Shopify storefront URLs into structured merchant-lead rows β store name, contact email/phone, socials, product and collection counts, theme, detected apps, and a derived lead-quality label β and, for every destination country you list, a real per-market check: the live currency the store quotes there and a real shipping-cost/carrier simulation run through the store's own cart. Unlike scraping frameworks that hand back raw HTML, Shopify Merchant Scraper: Market Currency & Shipping Data returns typed JSON, one row per store plus one child row per store/country pair, ready for a CRM, a spreadsheet, or an LLM context window without any parsing. This guide covers every input, every output field, and how teams actually run it β for one-off prospecting lists, scheduled monitoring, or bulk dataset builds.
π§ What Does This Shopify Merchant Scraper Do?
It crawls each Shopify storefront you give it using only the store's own public pages and public JSON endpoints (/products.json, /meta.json, /cart.js, /cart/shipping_rates.json) β no Shopify account, API key, or login is required at any point in the source code. For each store it returns a merchant-lead row, and, when you supply destinationCountries, it adds a real cart-level probe per destination: the currency the storefront actually quotes for that market and whether the store's own shipping-rate menu returns rates and a carrier for that address.
- Merchant identity: store title, real merchant name/description/city/province,
myshopifyDomain - Contact extraction: email and phone, tiered from
tel:/mailto:markers first, validated free-text fallback second - Seven-platform social detection: Facebook, Instagram, Twitter/X, TikTok, YouTube, Pinterest, LinkedIn
- Product/collection counts, theme name and version, detected app handles (theme-app-extension and app-proxy signals)
- Storefront status classification:
open,password_protected,catalog_unavailable,unreachable - A derived
leadQualitylabel computed only from fields already on the row - Per-destination-country live currency check, price-scale sanity flag, and a real shipping-rate/carrier simulation
β‘ Features & Capabilities
Everything below is read directly from the Actor's own source β no field or behavior described here is aspirational.
Core features
- Two-tier contact extraction β
tel:/mailto:/phone:markers are trusted first; a strict free-text regex (rejects SVG coordinates, tracking-pixel digit runs, and all-zero groups) is the fallback, run across the homepage plus/pages/contact,/contact,/pages/contact-us, and/policies/contact-information - Real merchant identity, not a guessed title β
merchantName,merchantDescription,merchantCity,merchantProvince, andmyshopifyDomainare read from the store's own/meta.json, separate from the raw<title>tag captured instoreName - True product counts where available β
productCountuses the store's ownpublished_products_countwhen/meta.jsonexposes it (productCountSource: "meta"); otherwise it falls back to the length of the/products.json?limit=250feed and is taggedproductCountSource: "products_feed_capped_at_250"so you know the number is a floor, not a fact, for stores with more than 250 published products - Live per-market currency check β for each destination country, a fresh, uncontaminated session reads
/cart.js?country={cc}and reports themarketCurrencythe storefront actually quotes there, flagged againstcurrencyMatchesHome - Real shipping-rate simulation β adds a genuinely addable product variant to a fresh cart and requests
/cart/shipping_rates.jsonwith a fullshipping_address(country + zip, plus province for province-scoped countries), returningshippingCheckStatus,shippingAvailable,shippingRateCount, and the cheapest rate's price, currency, and carrier name - Price-scale sanity flag β
priceScaleWarningcompares the market cart total to a country-unpinned home total and flags an implausible >20x or <0.05x jump when currencies differ - Escalating connection strategy β starts direct, escalates to an Apify Proxy
AUTOgroup and then aRESIDENTIALgroup on blocked responses (403, 406, 407, 429, 451, 503) or connection errors, and stays escalated for the rest of the run - Live dataset writes β every store row is pushed the moment it is ready; a crash mid-run does not lose completed rows
When another tool might suit you better
If all you need is a single, store-wide home currency and a homepage contact scrape, the market-currency and shipping-simulation work in this Actor is extra network calls and run time you don't need β a plain storefront scraper without the per-country cart probing will be faster and cheaper for that narrower job. This variant exists specifically for teams that need to know what a store actually charges and ships to a specific destination country, not just its home-market listing price.
Shopify Merchant Scraper: Market Currency & Shipping Data within the Scrapio data stack
This Actor covers merchant leads plus per-destination currency and shipping checks. For product-level fields (descriptions, specs, tags), use Shopify Products Scraper β Descriptions, Specs & Tags. For related-product and price-comparison data, use Shopify Scraper: Related Products & Price Comparison. For a lighter store-level contact-only scrape without the market simulation, use Shopify Store Scraper: Emails, Phones & Social Links.
Why do developers and data teams scrape Shopify?
π’ B2B prospecting and sales lead generation
Teams selling to Shopify merchants β payment providers, fulfillment/3PL companies, app developers, agencies β feed in a list of target storefronts and get back email, phone, leadQuality, themeName, and appHandles in one pass. A 3PL or freight-forwarding team specifically can cross-reference shipsToCountries against marketsShippable to find merchants whose current shipping coverage has real gaps in a target destination, then prioritize outreach by leadQuality.
π AI training data and RAG indexing
merchantDescription, storeName, and themeName are consistent, high-information text fields for RAG enrichment of a merchant-directory or e-commerce knowledge base. For structured training data, productCount, currency, shipsToCountries, distinctMarketCurrencies, and the per-market shippingCheckStatus/cheapestShippingPrice fields give a numeric/categorical feature set with a stable schema across runs, with no HTML to strip before it reaches a model context window.
π± Competitive and market intelligence
Track a competitor's distinctMarketCurrencies and marketsShippable over repeated runs to see when they open or drop a destination market, or watch appHandles and themeName for stack changes. cheapestShippingPrice per countryCode is a direct read on a competitor's live landed-shipping cost in a given market.
π¬ Research and academic use
The Actor returns only publicly accessible storefront pages and public JSON/cart endpoints, the same requests a shopper's own browser would make β suitable for academic research into cross-border e-commerce pricing and shipping practices, scoped to public data only.
π₯ Product and SaaS development
storefrontStatus, leadQuality, and the per-market rows are structured enough to back a merchant-directory product, a lead-enrichment API, or a shipping-coverage monitoring tool without additional normalization work.
π Input Parameters
All fields are optional (required: [] in the input schema). Names, types, and defaults below are copied exactly from .actor/actor.json.
| Parameter | Type | Constraints | Description |
|---|---|---|---|
storeUrls | array (stringList) | β | One or more Shopify storefront URLs to analyze (e.g. https://kyliecosmetics.com/). Bulk paste, upload a list, or pipe from another actor. This is the primary field; if both storeUrls and startUrls are supplied, storeUrls wins. |
startUrls | array (stringList) | β | Accepted for compatibility with the base Shopify Merchant Scraper's input shape β same meaning as storeUrls. |
maxStores | integer | min 1, max 10000, prefill 100 | Hard cap on how many of the provided store URLs will be processed. |
maxItems | integer | min 1, max 10000, default 100 | Accepted for compatibility with the base actor's input shape β same meaning as maxStores. |
destinationCountries | array (stringList) | prefill ["US","CA","GB","AU","DE"] | Destination countries to check, as 2-letter ISO country codes. Each store is checked against every code you list, up to maxMarketsPerStore. |
checkMarketCurrency | boolean | default true | For each destination country, read the store's own live currency for that market and flag it against the store's ships-to list and home currency. |
simulateShipping | boolean | default true | For each destination country, add a real product to a cart and request the store's own shipping-rate menu for that destination, including province/state so the check actually clears the storefront's validation. |
maxMarketsPerStore | integer | min 1, max 20, default 5 | Caps how many of the listed destinationCountries are actually probed per store, to keep runs fast and cheap. |
concurrency | integer | min 1, max 50, default 10 | How many stores to process in parallel. |
requestDelay | number | min 0, max 10, default 0.5 | Polite delay (seconds) inserted between requests to the same store. |
proxyConfiguration | object (proxy) | default {"useApifyProxy": false} | Use Apify Proxy, custom proxy URLs, or no proxy. By default the scraper connects directly; if a store starts blocking requests it automatically escalates its own connection strategy regardless of this setting. |
Example input
{"storeUrls": ["https://kyliecosmetics.com/", "https://www.allbirds.com/"],"maxStores": 50,"destinationCountries": ["US", "CA", "GB", "AU", "DE"],"checkMarketCurrency": true,"simulateShipping": true,"maxMarketsPerStore": 5,"concurrency": 10,"requestDelay": 0.5,"proxyConfiguration": { "useApifyProxy": false }}
Supported URL types and input formats
- Bare storefront domain or full URL β
kyliecosmetics.comorhttps://kyliecosmetics.com/both work;storeUrlsitems missing a scheme are normalized tohttps://before the run starts. - A base-actor-shaped input also works unchanged β
{"startUrls": [...], "maxItems": 100, "proxyConfiguration": {...}}is accepted as-is, since every base field is a real, declared property here too. destinationCountriesas 2-letter ISO codes only β any list item that is not exactly 2 characters after trimming and uppercasing is silently dropped during input normalization; duplicates are removed.
π¦ Output Format
Typed, normalized JSON with a stable field set across runs. One dataset holds two row types, distinguished by type: a store row per storefront (default π Merchant Leads view) and a market row per store/destination-country pair (π Per-Market Currency & Shipping view). Every key below is read from the row-building code in src/main.py, not just the dataset view's default column list.
Output for a merchant-lead row (type: "store")
{"type": "store","isChild": false,"storeName": "Kylie Cosmetics by Kylie Jenner | Kylie Jenner Fragrances | Kylie Skin","merchantName": "Kylie Cosmetics","merchantDescription": "Shop Kylie Cosmetics by Kylie Jenner...","merchantCity": "Los Angeles","merchantProvince": "CA","domain": "kyliecosmetics.com","myshopifyDomain": "kylie-jenner-us.myshopify.com","email": "customerservice@kyliecosmetics.com","phone": "1-877-916-6128","facebook": "https://www.facebook.com/KylieCosmetics/","instagram": "https://www.instagram.com/kyliecosmetics/","twitter": "https://twitter.com/kyliecosmetics","tiktok": null,"youtube": null,"pinterest": null,"linkedin": null,"productCount": 238,"productCountSource": "meta","publishedCollectionsCount": 226,"currency": "USD","moneyFormat": "${{amount}}","shipsToCountries": ["US", "CA", "GB", "AU"],"acceptedCardBrands": ["visa", "mastercard", "american_express"],"offersShopPayInstallments": true,"storefrontStatus": "open","themeName": "KYLIE","themeVersion": "9.0.1","appHandles": ["klaviyo", "yotpo"],"appsCount": 2,"themeAppExtensions": ["klaviyo"],"appProxyHandles": ["yotpo"],"appCount": 2,"hasEmail": true,"hasPhone": true,"socialPlatformCount": 3,"leadQuality": "high","marketsChecked": 5,"marketsWithCurrency": 5,"marketsShippable": 4,"distinctMarketCurrencies": ["USD", "CAD", "GBP", "AUD", "EUR"],"url": "https://kyliecosmetics.com/","scrapedAt": "2026-08-13T10:03:57.462Z"}
Field notes: productCountSource is "meta" when the count came from the store's own published count, or "products_feed_capped_at_250" when it came from the length of the public products feed, which Shopify itself caps at 250 items per request β treat that value as a floor, not an exact count, on large catalogs. leadQuality is computed only as unqualified (when storefrontStatus isn't open), or from 2 points for a found email, 1 for a found phone, plus up to 3 for social platform count, bucketed into high (β₯5), medium (β₯2), or low β never fabricated from fields not on the row. appHandles is the union of themeAppExtensions and appProxyHandles; the two are also kept split for stores where the distinction matters.
Output for a market currency & shipping row (type: "market", isChild: true)
{"type": "market","isChild": true,"domain": "kyliecosmetics.com","parentUrl": "https://kyliecosmetics.com/","countryCode": "CA","inShipsToList": true,"marketCurrency": "CAD","currencyMatchesHome": false,"priceScaleWarning": false,"shippingCheckStatus": "rates_returned","shippingAvailable": true,"shippingRateCount": 3,"cheapestShippingPrice": 8.5,"cheapestShippingCurrency": "CAD","cheapestShippingCarrier": "Standard Shipping","scrapedAt": "2026-08-13T10:04:12.118Z"}
Field notes: shippingCheckStatus is one of "not_checked", "cart_add_failed", "rates_returned", "no_rates_available", "destination_not_serviceable" (Shopify's own shipping-rates endpoint returned HTTP 422 for that address), or "request_failed". inShipsToList is null when the store's own /meta.json published no ships_to_countries list to check against. priceScaleWarning is only ever set when the market and home currencies differ and a valid home cart total was captured; otherwise it stays null.
Schema stability and export options
Field names are stable across runs β they are not scraped from Shopify's front-end markup for the structured fields (currency, shipping rates, meta fields) but read from Shopify's own public JSON endpoints, which change far less often than storefront HTML. storeName and social links are markup-derived and can return null if a store's theme doesn't expose them. As an Apify dataset, results export to JSON, JSONL, CSV, Excel, XML, or RSS directly from the Console's Export button, or via the Apify API/apify_client in the same formats. Market rows are also mirrored, uncharged, to a secondary per-run dataset named <runId>-markets for teams that want the market-level data isolated from the store-level dataset.
π‘ Shopify Merchant Scraper: Market Currency & Shipping Data Strategy Guide
π― Strategy 1: Real-time enrichment pipeline
Trigger a run from your CRM or lead-intake workflow whenever a new Shopify prospect domain is added: pass it as a single-item storeUrls array, run the Actor, then read email, phone, leadQuality, and marketsShippable off the resulting store row and write them back to the CRM record. Because rows are pushed live as each store finishes, a single-URL run against a small concurrency returns fast enough to sit inline in an enrichment step rather than a batch job.
π― Strategy 2: Scheduled monitoring and alerting
Set up an Apify Schedule to re-run the same storeUrls list weekly or monthly. Diff each new run's distinctMarketCurrencies, marketsShippable, and shippingCheckStatus per countryCode against the previous run's dataset for the same domain, and alert when a tracked competitor opens a new destination market (marketsShippable increases) or drops shipping coverage to one you care about (shippingCheckStatus flips to destination_not_serviceable).
π― Strategy 3: Bulk dataset build
Feed a large storeUrls list (up to maxStores, capped at 10000) with concurrency raised toward its maximum of 50 for a research or lead-list build, then export the full dataset to CSV once the run completes. Keep maxMarketsPerStore and the destinationCountries list only as large as the destinations you actually need β each additional destination country adds a full cart-simulation round trip per store.
Strategy comparison at a glance
| Strategy | Best for | Run pattern | Output format |
|---|---|---|---|
| Real-time enrichment | New leads as they arrive | Single-URL run, triggered on event | JSON row β CRM field write |
| Scheduled monitoring | Tracking competitor market/shipping changes over time | Recurring Apify Schedule, same URL list | Dataset diff between runs |
| Bulk dataset build | Research or prospecting lists | One large parallel run | CSV/JSON export |
π΄ Related Shopify Scrapers & Tools
| Scraper | What it extracts |
|---|---|
| Shopify Store Scraper: Emails, Phones & Social Links | Store-level contact and social data only, without the market currency/shipping simulation |
| Shopify Products Scraper β Descriptions, Specs & Tags | Per-product descriptions, specifications, and tags |
| Shopify Scraper: Related Products & Price Comparison | Related-product and price-comparison data at the catalog level |
How to integrate Shopify Merchant Scraper: Market Currency & Shipping Data with your stack
Shopify Merchant Scraper: Market Currency & Shipping Data works with any language or tool that can make an HTTP request through the Apify API, or use the official apify_client SDKs below.
Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run_input = {"storeUrls": ["https://kyliecosmetics.com/", "https://www.allbirds.com/"],"destinationCountries": ["US", "CA", "GB", "AU", "DE"],"checkMarketCurrency": True,"simulateShipping": True,"maxMarketsPerStore": 5,"concurrency": 10,}run = client.actor("scrapio/shopify-merchant-scraper-market-currency-and-shipping-data").call(run_input=run_input)rows = []for item in client.dataset(run["defaultDatasetId"]).iterate_items():if item.get("type") == "store":rows.append(item)import csvwith open("shopify_leads.csv", "w", newline="", encoding="utf-8") as f:writer = csv.DictWriter(f, fieldnames=rows[0].keys())writer.writeheader()writer.writerows(rows)print(f"Wrote {len(rows)} store lead row(s) to shopify_leads.csv")
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });const input = {storeUrls: ['https://kyliecosmetics.com/', 'https://www.allbirds.com/'],destinationCountries: ['US', 'CA', 'GB', 'AU', 'DE'],checkMarketCurrency: true,simulateShipping: true,maxMarketsPerStore: 5,};const run = await client.actor('scrapio/shopify-merchant-scraper-market-currency-and-shipping-data').call(input);const { items } = await client.dataset(run.defaultDatasetId).listItems();const storeRows = items.filter((row) => row.type === 'store');console.log(`Fetched ${storeRows.length} store lead row(s)`);
Async and scheduled pipelines
For large storeUrls lists, call the Actor via client.actor(...).start() instead of .call() to kick off the run without blocking, then poll client.run(runId).get() or client.dataset(datasetId).iterate_items() once it finishes. For recurring jobs, an Apify Schedule re-runs the same input on a cron-style interval without any extra code β pair it with Strategy 2 above for change monitoring.
π― Who Needs Shopify Merchant Scraper: Market Currency & Shipping Data? (Use Cases & Industries)
π’ Fulfillment, 3PL, and cross-border logistics sales teams
Cross-reference shipsToCountries and per-market shippingAvailable against your own coverage map to find merchants whose current shipping setup has a real gap in a country you can serve, then prioritize outreach by leadQuality.
π Payment providers, app developers, and Shopify agencies
Use appHandles, themeName, and offersShopPayInstallments to identify merchants running a specific stack or missing an integration, then use email/phone to reach out directly.
π± Pricing and market-intelligence analysts
Track distinctMarketCurrencies and cheapestShippingPrice per countryCode across competitors to spot landed-cost differences and currency-scale anomalies flagged by priceScaleWarning.
π¬ Researchers
Public-data-only scope makes the dataset suitable for academic research into cross-border e-commerce pricing, currency, and shipping practices without any account-gated data.
π₯ Merchant-directory and monitoring-tool builders
storefrontStatus, leadQuality, and the per-market rows are structured enough to back a directory, enrichment API, or shipping-coverage monitor without extra normalization.
Is it legal to scrape Shopify?
Yes β scraping publicly accessible web pages is generally lawful in the United States; the Ninth Circuit's hiQ Labs v. LinkedIn Corp. (9th Cir. 2019) held that accessing publicly available data does not violate the Computer Fraud and Abuse Act. This Actor primarily returns business and storefront records β merchant identity, product/collection counts, currency, and shipping-market data β not personal social-media profiles, so most of what it returns sits outside data-protection frameworks built around personal data. Two separate questions still apply. First, scraping publicly accessible data has real legal precedent behind it, as above. Second, doing so may still violate a given store's Terms of Service, which is a matter of civil contract risk between you and that merchant, not a criminal matter. Third, this Actor's email and phone fields are limited to whatever a merchant has itself published on its own public storefront and contact pages for customer-facing purposes; where a captured contact detail happens to identify a specific individual rather than a general business inbox, ordinary data-protection obligations for storing and using personal data can still apply to that narrow slice of the output β consult counsel for that case. Shopify Merchant Scraper: Market Currency & Shipping Data returns only publicly accessible data. What you do with that data is your responsibility β consult legal counsel for commercial applications involving personal data.
β Frequently asked questions
Does Shopify Merchant Scraper: Market Currency & Shipping Data work without a Shopify account?
Yes. The source code never authenticates against Shopify β it reads each storefront's own public pages and public JSON/cart endpoints (/products.json, /meta.json, /cart.js, /cart/shipping_rates.json), the same requests a shopper's browser makes. No Shopify account, API key, or partner access is needed.
How does it handle Shopify's anti-scraping measures?
It starts with a direct connection and escalates only when it hits a blocked response (403, 406, 407, 429, 451, 503) or a connection error: first to an Apify Proxy AUTO group, then to a RESIDENTIAL group, staying at whichever rung it escalates to for the rest of the run. Requests retry with an exponential backoff (plus jitter) up to a capped ceiling before giving up on a given page.
Can I run it at scale without getting blocked?
concurrency (default 10, max 50) controls how many stores run in parallel, and requestDelay (default 0.5s) throttles requests within a single store's own request sequence. No uptime or block-rate figure is published for this Actor β the proxy escalation above is the real, documented mitigation.
How fresh is the data it returns?
Live per run β every field is fetched fresh from the storefront's own endpoints during that run; nothing is served from a cache. scrapedAt is stamped at collection time for both store and market rows.
Which fields work best for AI training and RAG indexing?
For RAG: merchantDescription, storeName, and themeName are the highest-information free-text fields. For training data: productCount, currency, shipsToCountries, distinctMarketCurrencies, and the per-market shippingCheckStatus/cheapestShippingPrice fields are the most consistently structured across records. All fields return as typed primitives (strings, numbers, booleans, arrays) requiring no normalization before use.
What happens to a store that's password-protected or unreachable?
It's detected and labeled, not silently dropped or returned as a misleading empty row. storefrontStatus is set to "password_protected", "catalog_unavailable", or "unreachable" as appropriate, and market probing is skipped entirely for any store that isn't "open".
Are failed-store rows charged the same as successful ones?
Yes β every store URL processed produces exactly one row_result-charged row, including the fallback row emitted when an unexpected error occurs mid-scrape (storefrontStatus: "unreachable"). If you only want successfully scraped leads, filter the dataset on storefrontStatus === "open" after the run.
Does it work with Claude, ChatGPT, and other AI agent tools?
There is no dedicated MCP server for this Actor. It's callable as an HTTP endpoint via the Apify API by any agent framework that can issue an HTTP request β every response is typed JSON, so no HTML parsing is needed before passing results into an LLM context window.
How does it compare to other Shopify scrapers?
No competitor listings were reviewed for this README, so no named-competitor comparison is made here. What can be stated with confidence from this Actor's own source code: it does not stop at a single store-wide currency field β for every destination country you list, it performs a live per-market currency read and a real cart-based shipping-rate simulation, both against the storefront's own endpoints.
βΉοΈ Disclaimer
Shopify Merchant Scraper: Market Currency & Shipping Data extracts only publicly available data from Shopify storefronts. This tool is intended for lawful use cases only. Users are responsible for complying with each scraped store's terms of service and applicable data protection laws in their jurisdiction.