Shopify Store Scraper — Markets, Currencies & Catalogs avatar

Shopify Store Scraper — Markets, Currencies & Catalogs

Pricing

from $0.01 / 1,000 results

Go to Apify Store
Shopify Store Scraper — Markets, Currencies & Catalogs

Shopify Store Scraper — Markets, Currencies & Catalogs

Shopify Store Scraper extracts store data across markets, currencies, and product catalogs, including product titles, prices, variants, inventory, collections, and store details. Ideal for competitor research, pricing analysis, catalog monitoring, and e-commerce insights.

Pricing

from $0.01 / 1,000 results

Rating

0.0

(0)

Developer

SimpleAPI

SimpleAPI

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

1

Monthly active users

3 days ago

Last modified

Share

Shopify Store Scraper — Markets, Currencies & Catalogs

Give this Shopify store scraper a storefront URL and it returns every market that store actually sells in, the real currency each market is served in, and how the catalogue and prices shift from one market to the next. Each run produces a store row (baseCurrency, marketCount, currencyCount, distinctCurrencies, isInternationalised) plus one market row per country (marketCode, currency, priceMedian, anchorPrice, catalogueCoveragePct). Ecommerce analysts, cross-border service vendors, and DTC competitive researchers use it to see how a brand really prices and stocks itself abroad — not what its country selector claims.


🧭 What is Shopify Store Scraper — Markets, Currencies & Catalogs?

It is an Apify Actor that profiles one or more public Shopify storefronts and answers three questions a standard store profile does not: which markets the store actually sells in, what currency each of those markets is really served in, and how the catalogue and price level differ market to market. Output is a flat, typed JSON dataset — no Shopify account, API key, or store login is required, since every field comes from the same public storefront endpoints (meta.json, products.json, collections.json, cart.js) that any visitor's browser already loads.

  • 🗺️ Market discovery from three independent public signals — published regional (hreflang) alternates, localized storefront sections, and the store's shipping destination list — unioned and de-duplicated, or narrowed to one source with discoverMarkets.
  • 💱 Real, pinned currency per market — each market is asked directly what it charges, not inferred from a flag icon or the store's declared currency.
  • 📦 Localized catalogue size and price level per market, with coverage against the home market (catalogueCoveragePct, priceMedian, priceMin, priceMax).
  • 🧷 One identical product priced across every market (anchorPrice), for a like-for-like comparison instead of comparing medians of catalogues that are not the same.
  • 🎯 Country targeting that bypasses discovery — name exact ISO country codes in probeCountries and get exactly those markets, whether or not the store publishes them.
  • ⬇️ Standard Apify dataset export — JSON, CSV, Excel, XML or HTML table, plus a separate mirrored dataset of market-only rows when emitMarketRows is on.

📦 What data can I extract with Shopify Store Scraper — Markets, Currencies & Catalogs?

Every run returns three kinds of rows — a store row, one market row per probed market, and (only when a storefront can't be profiled) a status row — each carrying every field below.

Store row (type: "store", isChild: false) — one per storefront

FieldExample valueUse case
type"store"Filter store-level rows out of the mixed dataset
isChildfalseSame filter, boolean form
store_domain"rothys.com"Primary key joining a store row to its market rows
store_url"https://rothys.com"The normalized storefront address that was profiled
shop_name"rothys.myshopify.com"Store's real myshopify.com handle
myshopifyDomain"rothys.myshopify.com"Same handle under its canonical field name
shopId12345678Shopify's internal numeric shop ID
storeName"Rothy's"Store's published display name
country"US"Store's home country
currency"USD"Store's home currency
baseCurrency"USD"Store's declared home currency (same value as currency)
moneyFormat"${{amount}}"How the store formats prices on its own pages
locale"en"Storefront's declared content language
storefrontStatus"open"open / limited_data / closed_to_public / not_shopify / unreachable / temporarily_unavailable
excludedFromCoveragefalsetrue when this row should be dropped from coverage math
theme_name"Impulse"Storefront theme label
themeSchemaName"impulse"Theme's internal schema name
theme_id123456789Numeric theme ID
theme_version"9.2.1"Theme version string
apps_installed["Klaviyo", "Shop Pay", "Yotpo"]Apps the storefront itself evidences
apps_by_source{"theme_app_extension": [...], "app_proxy": [...], "storefront_signal": [...]}Same list, broken out by how it was detected
apps_count14Count of apps_installed
total_products664Home-catalogue product count
publishedProductsCount664Store's own published-count figure, for cross-check
catalogueTruncatedfalsetrue if a catalogue page failed mid-walk
productPagesWalked3Pages read to build total_products
total_variants2114Variant count across all products
collections["Flats", "Sneakers", "New Arrivals"]Collection titles
collections_count198Collections found (paginated to completion)
publishedCollectionsCount198Store's own published-count figure
collectionPagesWalked1Pages read for collections
categories["Shoes", "Bags"]Distinct product_type values
vendors["Rothy's"]Distinct vendor values
price_min45.0Cheapest home-catalogue price
price_avg128.4Mean home-catalogue price
price_max268.0Most expensive home-catalogue price
products_on_sale42Products with a compare_at_price discount
discount_pct_avg18.5Mean discount % across on-sale products
maxDiscountPct40.0Largest single discount % found
total_variants_available1890Variants currently in stock
inventory_availability_pct89.4% of variants in stock
oldest_product_date"2015-03-02"Earliest product created_at (date only)
newest_product_date"2026-07-30"Latest product created_at (date only)
products_with_images664Products carrying at least one image
avg_images_per_product4.2Mean image count per product
products_with_description660Products with non-empty body_html
top_products[{"title": "...", "url": "...", "price": 160.0}]Ten newest products, most recent first
marketCount35Distinct markets discovered from all sources
localizedStorefrontCount35Discovered markets with their own path or domain
marketsProbed8Markets actually probed this run
discoveredMarketCountries["AT", "AU", "BR", "..."]Every country code discovered, probed or not
marketCountries["AT", "BR", "CA", "..."]Country codes actually probed this run
marketLocales["en-CA", "pt-BR"]hreflang tags of the probed markets
marketPaths["/en-ca", "/pt-br"]URL path prefixes of the probed markets
distinctCurrencies["ARS", "AUD", "BRL", "CAD", "CHF", "EUR"]Currencies found among probed markets
currencyCount6Count of distinctCurrencies
isInternationalisedtruetrue when >1 currency or an alternate domain exists
publishedAlternateCount40hreflang alternate links found on the homepage
alternateDomains[]Separate-domain sibling storefronts detected (e.g. a .co.uk)
marketDiscoverySources{"published_alternates": 40, "localized_sections": 12, "shipping_list": 35}Raw hit count per discovery source
inputMarketPathnullMarket path supplied directly in the input URL, if any
shipsToCountries["US", "CA", "GB", "..."]Store's own declared shipping list
shipsToCountryCount224Count of shipsToCountries
declaredCurrency"USD"Duplicate of baseCurrency, kept for compatibility
homeCountry"US"Duplicate of country
unpinnedCurrency"USD"Currency returned by an un-pinned cart.js read of the home store
storefrontQuotesByRequestOriginfalsetrue when unpinnedCurrency disagrees with baseCurrency
marketsWhereOriginChangedTheAnswer0Count of probed markets where the pinned and unpinned currency disagree
pricesPinnedToCountry"US"Country code used to pin the home-catalogue price sample
rootCatalogueCount492Home market's sitemap-counted product total
catalogueCoverageByMarket{"AT": 64.23, "BR": 64.23}catalogueCoveragePct keyed by market code
priceIndexByMarket{"AT": {"index": 1.14, "median": 170.0, "currency": "EUR", "sameCurrencyAsBase": false}}Each market's median price relative to the home market
priceIndexBaseMarket"ROOT"Always "ROOT" — the home catalogue is the index base
priceIndexFxAdjustedfalseAlways false — the index is never currency-converted
rootPriceMedian150.0Home market's median sample price
priceLeaderByCurrency{"USD": {"cheapestMarket": "US", ...}}Cheapest/dearest computed separately within each currency group
cheapestMarket"FR"Cheapest market in the headline currency group
dearestMarket"AT"Dearest market in the headline currency group
marketPriceSpreadPct3.03% spread between cheapest and dearest in that group
priceComparisonCurrency"EUR"Which currency group the headline comparison was made in
anchorProductHandle"womens-casual-clog-revelvet-syrah"Product handle used for the like-for-like check
anchorPriceRoot160.0Anchor product's home-market price
anchorPriceByMarket{"CA": {"price": 235.0, "currency": "CAD"}}Anchor product's price, per market
anchorMarketsCovered7Markets where the anchor product was actually found and priced
scraped_at"2026-08-08T00:00:00+00:00"ISO timestamp the row was collected
scrape_duration_sec41.2Wall-clock seconds spent profiling this store

💱 Market row (type: "market", isChild: true) — one per probed market

The decision-driving data attached to every market: its own currency, its own catalogue size, and its own price level, so a market can be judged on what it is actually offered rather than the store's home numbers.

FieldExample value
type / isChild"market" / true
store_domain, store_url"rothys.com", "https://rothys.com"
marketCode"BR"
marketPath"/pt-br"
marketUrl"https://rothys.com/pt-br"
marketLocaleTag"pt-BR"
alternateUrlnull
isAlternateDomainfalse
discoveredVia["localized_sections", "published_alternates", "shipping_list"]
inShipsToListtrue
currency"BRL"
currencySource"localized_storefront" (or "alternate_storefront" / "country_selection")
storeDeclaredCurrency"USD"
currencyMatchesStore / currencyIsBaseCurrencyfalse / false
currencyUnpinned"USD"
currencyDependsOnRequestOriginfalse
pricePinnedToCountry"BR"
marketProductCount316
marketProductCountSource"market_index"
catalogueCoveragePct64.23
priceMedian / priceMin / priceMax1050.0 / 720.0 / 1890.0
priceCurrency"BRL"
priceSampleSize100
priceSampleVariants1604
anchorProductHandle"womens-casual-clog-revelvet-syrah"
anchorPrice1050.0
anchorPriceMoneyShape"minor_units_integer"
scraped_at"2026-08-08T00:12:41+00:00"

🎯 Targeting and discovery fields

The fields that drive which markets get probed and how they're segmented: marketCode (ISO country), discoveredVia (which of the three discovery sources found it), inShipsToList, isAlternateDomain/alternateUrl (separate-domain markets), and — on the store row — marketDiscoverySources (per-source hit counts) and discoveredMarketCountries (everything found, whether or not it was probed). These are the fields the input parameters below act on: discoverMarkets picks which sources feed them, probeCountries bypasses them entirely for named codes, and maxMarkets caps how many get probed.

Status row (type: "status") — emitted instead of a store row

FieldExample value
type"status"
isChildfalse
store_url, store_domain"https://example-store.com", "example-store.com"
storefrontStatus"unreachable" / "temporarily_unavailable" / "not_shopify" / "incomplete" / "no_input"
statusDetail"This address does not present as a Shopify storefront."
excludedFromCoveragetrue
scraped_at"2026-08-08T00:00:00+00:00"

🆚 How does this Shopify store scraper differ from the official Shopify API?

Shopify's own Storefront API can return a store's markets, localization and international prices — but every Storefront API access token is scoped to a single store, generated and approved by that store's own owner. You cannot use it to survey which markets and currencies a competitor's or a prospect's store serves, because you don't hold — and cannot get — a token for a store you don't administer. That scoping is documented in Shopify's own developer docs as of 2026-08-15 (shopify.dev — Getting started with the Storefront API; shopify.dev — Building localized experiences with the Storefront API and Shopify Markets).

FeatureShopify Storefront APIThis Actor
Credential neededAccess token generated and approved by the store ownerNone — works from a public storefront URL
Coverage across stores you don't runOne store per token; cannot query a store you don't administerAny number of public storefronts in one run, via startUrls
Market discoveryYou must already know a store's markets to query itDiscovers markets from three independent public signals automatically
Currency per marketReturns the store's configured market listDirectly probes each market's live currency, pinned per country
Cross-market price comparisonYou write your own cart/context calls, per market, per storeanchorProductCheck prices one identical product across every probed market in a single run
SetupRegister an app, get a token approved by the storeAdd a URL and run
OutputRaw GraphQL response shape you defineFlat, typed dataset rows, same schema for every store

Why can't I just query another store's markets with the Storefront API?

Because the token is scoped to one store. Building a competitive or market-research view — "which of these 40 brands sell into Brazil, and in what currency" — would mean getting each of those 40 merchants to hand you their own access token, which they have no reason to do. This Actor sidesteps that entirely: it reads the same public JSON endpoints (meta.json, products.json, cart.js) any visitor's browser already receives when it loads the store, so no token or store relationship is required, for any number of storefronts.

Use the Storefront API when you're building or operating your own store's storefront or headless frontend. Use this Actor when you need market, currency and price data about storefronts you do not run.


🎯 How to use data extracted from Shopify?

Ecommerce and DTC competitive analysts

Feed a list of competitor startUrls, keep fetchLocalizedCatalogue and anchorProductCheck on, and get back each brand's real footprint: currencyCount, distinctCurrencies, marketPriceSpreadPct, and the anchor product's price in every market. This turns "does Brand X sell internationally" from a guess based on a footer flag icon into a table of currencies, coverage percentages and prices you can sort and chart.

Cross-border service providers

3PL, tax, FX and localization vendors run a fixed prospect list through the actor on a schedule, filtering on isInternationalised and currencyCount to separate stores that are already multi-market from ones that are still domestic — the latter being the better outreach target for "help me expand," the former for "help me optimize what I already have."

Market research and intelligence

Run a set of stores in one category and aggregate distinctCurrencies, catalogueCoverageByMarket and priceIndexByMarket across them to map which regions a category is under-served in, or how consistently brands price the same product type abroad versus at home.

AI agents and automated pipelines

Because output is one flat JSON schema per row regardless of the store, an agent can call this Actor as a tool over any storefront URL and read baseCurrency, marketCount and anchorPriceByMarket straight into a pricing or expansion-planning pipeline without per-store parsing logic.


🔼 Input sample

ParameterRequiredTypeDescriptionExample value
startUrlsYesarrayOne or more Shopify storefronts to profile. A bare domain works too. Each storefront produces one store row plus one row per market.["https://rothys.com", "https://www.allbirds.com"]
storefrontUrlsNoarrayOptional extra storefronts, merged with startUrls and de-duplicated.["https://gymshark.com"]
discoverMarketsNostring (enum)Which signals build the candidate market list: all (default, union of all sources), published_alternates, localized_sections, shipping_list."all"
probeCountriesNoarrayTwo-letter country codes to probe whether or not the store published them. Listing codes here gets you exactly those markets — maxMarkets never trims a list you typed yourself.["US", "CA", "GB", "DE", "BR"]
maxMarketsNointeger (min 1, max 60, default 8)How many discovered markets are probed per store. Localized storefronts are always probed before shipping-only countries. Ignored when probeCountries is set.8
fetchLocalizedCatalogueNoboolean (default true)Reads each market's own catalogue for product count, coverage and price range. Off runs currency-only.true
priceSampleSizeNointeger (min 10, max 250, default 100)Products read per market to compute median/min/max price. Higher is more stable and slower.100
anchorProductCheckNoboolean (default true)Picks one product and prices it in every market for a like-for-like comparison.true
emitMarketRowsNoboolean (default true)Adds a labelled row per market and mirrors those rows into a separate per-run market dataset. Off returns store rows only.true
proxyConfigurationNoobject (proxy editor, default {"useApifyProxy": false})Optional connection settings — leave as-is unless a specific storefront is slow to respond.{"useApifyProxy": false}
{
"startUrls": ["https://rothys.com", "https://www.allbirds.com"],
"discoverMarkets": "all",
"maxMarkets": 8,
"fetchLocalizedCatalogue": true,
"priceSampleSize": 100,
"anchorProductCheck": true,
"emitMarketRows": true
}

Common pitfall: probeCountries codes must be exactly two letters — a three-letter code like "USA" is silently ignored (only 2-character entries are used). And once you list any codes there, maxMarkets stops applying entirely: the cap only ever trims a discovered list, never one you typed by hand, so you always get every country you named, plus nothing else.


🔽 Output sample

Output is typed, normalized JSON with the same schema for every store — no per-brand parsing needed. Every run writes to the Actor's default dataset, which exports to JSON, CSV, Excel, XML or HTML table like any Apify dataset; market rows are also mirrored into a separate per-run market-only dataset when emitMarketRows is on.

{
"type": "store",
"isChild": false,
"store_domain": "rothys.com",
"store_url": "https://rothys.com",
"shop_name": "rothys.myshopify.com",
"storefrontStatus": "open",
"country": "US",
"baseCurrency": "USD",
"moneyFormat": "${{amount}}",
"locale": "en",
"apps_count": 14,
"apps_installed": ["Attentive", "Google Analytics 4", "Klaviyo", "Shop Pay"],
"total_products": 664,
"publishedProductsCount": 664,
"collections_count": 198,
"marketCount": 35,
"marketsProbed": 8,
"distinctCurrencies": ["ARS", "AUD", "BRL", "CAD", "CHF", "EUR"],
"currencyCount": 6,
"isInternationalised": true,
"alternateDomains": [],
"rootCatalogueCount": 492,
"priceIndexByMarket": {
"AT": { "index": 1.1409, "median": 170.0, "currency": "EUR", "sameCurrencyAsBase": false }
},
"priceIndexFxAdjusted": false,
"anchorProductHandle": "womens-casual-clog-revelvet-syrah",
"anchorPriceRoot": 160.0,
"anchorPriceByMarket": { "CA": { "price": 235.0, "currency": "CAD" } },
"cheapestMarket": "FR",
"dearestMarket": "AT",
"marketPriceSpreadPct": 3.03,
"priceComparisonCurrency": "EUR",
"scraped_at": "2026-08-08T00:00:00+00:00",
"scrape_duration_sec": 41.2
}
{
"type": "market",
"isChild": true,
"store_domain": "rothys.com",
"marketCode": "BR",
"marketPath": "/pt-br",
"marketUrl": "https://rothys.com/pt-br",
"marketLocaleTag": "pt-BR",
"isAlternateDomain": false,
"discoveredVia": ["localized_sections", "published_alternates", "shipping_list"],
"inShipsToList": true,
"currency": "BRL",
"currencySource": "localized_storefront",
"currencyIsBaseCurrency": false,
"marketProductCount": 316,
"catalogueCoveragePct": 64.23,
"priceMedian": 1050.0,
"priceCurrency": "BRL",
"priceSampleSize": 100,
"priceSampleVariants": 1604,
"anchorProductHandle": "womens-casual-clog-revelvet-syrah",
"anchorPrice": 1050.0,
"anchorPriceMoneyShape": "minor_units_integer",
"scraped_at": "2026-08-08T00:12:41+00:00"
}

⚠️ Only store and market rows are billed. Both are pushed with the row_result charged event. Status rows — unreachable, temporarily_unavailable, not_shopify, incomplete, no_input — are pushed with no charged event at all, so an unreachable storefront costs nothing. Filter them out of any analysis with type != "status" (equivalently, excludedFromCoverage == false).


🎚️ How do you filter and target specific markets?

This is the actual control surface, not a generic filter list — every knob below maps directly to an input parameter.

Discovery source vs named countries. discoverMarkets: "all" unions three public signals and is the most complete option for most stores, since real coverage varies by brand and most publish only one or two of the three. Switch to a single source (published_alternates, localized_sections, or shipping_list) when you already know which signal a given storefront uses and want a faster, narrower run. probeCountries bypasses discovery entirely — name exact ISO codes and get exactly those markets, whether the store published them or not.

Volume control. maxMarkets (1–60, default 8) caps how many discovered markets get probed, with localized storefronts always probed ahead of shipping-only countries. It never trims a probeCountries list — that list is honoured in full, so five codes always means five market rows.

Depth vs speed. fetchLocalizedCatalogue (default on) turns per-market catalogue and price reads on or off; priceSampleSize (10–250, default 100) trades sample stability for run time; anchorProductCheck (default on) adds the one-product, every-market comparison.

{ "startUrls": ["https://rothys.com"], "probeCountries": ["US", "CA", "GB", "DE", "BR"] }
{ "startUrls": ["https://rothys.com"], "maxMarkets": 20, "fetchLocalizedCatalogue": false, "anchorProductCheck": false }
{ "startUrls": ["https://rothys.com"], "discoverMarkets": "localized_sections", "priceSampleSize": 250, "anchorProductCheck": true }

The first pins five specific countries regardless of what the store discloses. The second is a fast, currency-only sweep across up to 20 discovered markets. The third is a slower, deeper price audit restricted to markets with their own localized storefront section.


▶️ Want to try other Shopify scrapers?

ScraperWhat it extracts
Shopify Merchant Scraper: Niche & Keyword Store SearchDiscovers Shopify stores by niche or keyword
Shopify Products Scraper With Variant & SKU RowsPer-product, per-variant catalogue rows for a given store
Shopify Scraper: Sales Channel & Product Templates DataSales-channel and theme/template metadata per store
Amazon Search Scraper By Country & CurrencyCross-country pricing for Amazon search results
Google Play Scraper: Country Pricing & In-App PurchasesCross-country app pricing and in-app purchase data

🔌 How to extract Shopify data programmatically

Every run is a standard Apify Actor call: one API call starts it, one call reads back structured JSON — no separate signup or credential beyond your Apify API token.

Python example

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_API_TOKEN>")
run = client.actor("your-username/shopify-store-scraper-markets-currencies-catalogs").call(
run_input={
"startUrls": ["https://rothys.com"],
"probeCountries": ["US", "CA", "GB", "DE"],
"anchorProductCheck": True,
}
)
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row.get("type") == "market":
print(row["marketCode"], row["currency"], row["priceMedian"])

Export to spreadsheets or CRM

Apify's dataset export handles CSV/Excel directly — map store_domain to a "Store" column, baseCurrency/currency to "Currency", marketCount/marketCode to "Markets", and anchorPrice/priceMedian to your pricing columns. Import the CSV into Sheets, Excel, or a CRM's bulk-import flow with no reshaping needed.


Yes. This Actor reads only public storefront data — store profile, market list, currencies, catalogue and price figures — that Shopify serves to any visitor's browser without a login. These are business and product records, not personal data about identifiable individuals, so GDPR and CCPA do not govern them; the relevant frameworks are Shopify's own terms of service, which govern what a third party may do with data read from a merchant's storefront, and database-rights law in jurisdictions where a compiled catalogue is separately protected. Consult legal counsel for commercial applications involving bulk storage of personal data.


❓ Frequently asked questions

What happens if a store has closed or isn't on Shopify anymore?

The run reports a status row instead of guessing. storefrontStatus is closed_to_public for a password-locked store, not_shopify for a non-Shopify address, unreachable/temporarily_unavailable for a store that didn't respond, and incomplete if profiling failed partway through. All of these carry excludedFromCoverage: true so they never quietly drag down a coverage figure.

Can I get catalogue and pricing data along with the market list?

Yes — fetchLocalizedCatalogue (default on) adds marketProductCount, catalogueCoveragePct, priceMedian, priceMin and priceMax per market, and anchorProductCheck (default on) adds anchorPrice for one identical product priced everywhere it's found. Turn both off for a currency-only run.

How accurate is the price and currency data?

The Actor returns each market's price and currency exactly as its storefront answers at request time, pinned to that specific country — never inferred from an unpinned request, which can answer with the wrong currency entirely. Prices move with the merchant's own pricing changes, so re-run periodically if you're tracking price changes over time.

How many markets can I get per run?

Up to maxMarkets (maximum 60, default 8) discovered markets per store, or exactly as many markets as you name in probeCountries — that list is never trimmed. There is no cap on how many storefronts you list in startUrls.

What's the real difference between maxMarkets and probeCountries?

maxMarkets caps a discovered list built from the store's own published signals; probeCountries replaces discovery altogether with countries you name explicitly, and is honoured in full regardless of maxMarkets. Use probeCountries when you need the same fixed set of countries for every store in a comparison run.

Does this scraper work with Claude, ChatGPT, and AI agent frameworks?

It's callable as a standard Apify Actor run by any agent framework or HTTP client via apify_client or a direct REST call — there's no separate MCP server documented for this Actor.

How is this different from a plain Shopify product scraper?

A product scraper returns one row per SKU in a single market. This Actor never emits per-product rows at all — it emits one store summary plus one row per market, with currency, catalogue coverage and one anchor product's price compared across every market in the run. If you need line-item product and variant data for a single store, pair this with SimpleAPI's own Shopify Products Scraper instead.

Can I use this without a Shopify API key or developer account?

Yes. Supply a public storefront URL — a bare domain works — and run it. No Shopify account, API key, access token, or store login of any kind is required.


✅ Conclusion

Shopify Store Scraper — Markets, Currencies & Catalogs turns "does this brand sell internationally" from a guess into a dataset: which markets a store actually serves, what currency each one is really quoted in, and how catalogue size and price level shift market to market, down to one identical product priced everywhere it's carried. It's built for ecommerce analysts, cross-border service vendors, and market researchers who need that comparison across any number of public Shopify storefronts without a token or login for any of them. Add a storefront URL and run it on the Apify platform to get your first store and market rows in one pass.