Sephora Product Scraper (Global) avatar

Sephora Product Scraper (Global)

Pricing

from $4.50 / 1,000 results

Go to Apify Store
Sephora Product Scraper (Global)

Sephora Product Scraper (Global)

Scrape Sephora products across 20 storefronts (US, Canada, 9 EU markets, 10 APAC countries) through one unified Python actor. Extract prices, variants, ratings, and catalog details via official mobile APIs with TLS fingerprint impersonation, OAuth2/guest-token auth, and per-market session isolation.

Pricing

from $4.50 / 1,000 results

Rating

5.0

(1)

Developer

Richard Feng

Richard Feng

Maintained by Community

Actor stats

14

Bookmarked

418

Total users

16

Monthly active users

1.6 days

Issues response

9 days ago

Last modified

Share

What does Sephora Scraper do?

Sephora Scraper extracts complete product data — every variant, every price, every image, every review — from 28 Sephora storefronts across the US, Canada, 9 EU markets, 6 MENA markets, the UK, India, and 10 Asia-Pacific markets. Paste any sephora.* product or category URL and the actor auto-detects the market, fetches the data, and returns a normalized JSON record that's identical in shape across every region.

The same run can span multiple markets. Mix sephora.com, sephora.fr, and sephora.nz URLs in one startUrls list; the dispatcher groups them by market, runs each module concurrently with market-appropriate headers and auth, and streams everything to a single dataset tagged with a market field.

Why use Sephora Scraper?

  • 28 storefronts, one SKU. One actor covers US + Canada + 9 EU + 6 MENA + UK + IN + 10 APAC. No juggling multiple scrapers.
  • Fast, structured fetches. No browser automation, no HTML scraping. Expect seconds per product, not minutes.
  • Locale-correct pricing. NZD for New Zealand, EUR for France, USD for US — returned by Sephora's own localization layer, not guessed.
  • Shade undertone & finish. On US/Canada storefronts, every colour shade carries its undertone/finish descriptor (e.g. "light, neutral peach", "with neutral undertones") next to the shade name and swatch — the side detail Sephora shows under each shade — plus the product size.
  • Normalized schema. Every market emits the same top-level shape: source / brand / title / options / variants / medias / stats. Drop-in compatible with v1.x US dataset consumers.
  • Production-tested. Built on top of the autofacts/sephora US scraper that's been running continuously since 2025. EU and SEA ports were translated directly from the sephora-eu-scraper and sephora-nz-scraper standalone actors.

How to use Sephora Scraper

  1. In the Input tab, paste any Sephora product or category URL(s) into Sephora start URLs — from any country.
  2. (Optional) Set Max requests per crawl to cap the run (applies to all markets).
  3. (Optional) Override the auto-detected market with the Market override field if you're passing bare IDs instead of URLs.
  4. Click Start and download the results from the Dataset tab (JSON, CSV, XLSX, HTML).

No API keys, no tokens, no proxy account required for EU/SEA. US runs perform best with a residential-proxy Apify plan.

Input

FieldDescription
startUrlsProduct, category or editorial-page URLs from any sephora.* storefront. Required — see Supported URL shapes.
marketOptional market override. Values: us, eu-fr, eu-it, eu-de, eu-es, eu-pl, eu-ro, eu-pt, eu-cz, eu-gr, mena-ae, mena-sa, mena-bh, mena-om, mena-kw, mena-qa, uk, in, sea-nz, sea-au, sea-sg, sea-my, sea-th, sea-id, sea-ph, sea-hk, sea-tw, sea-bn. Leave blank to auto-detect from URLs.
localeOptional BCP 47 locale (e.g. fr-FR, en-NZ). Overrides the market's default.
categoryIdsCategory IDs to crawl instead of pasting category URLs. Read by EU, MENA, LATAM, UK and India; the ID format is the market's own (EU/MENA/LATAM SFCC ids like C479, UK numeric ids, India category slugs). Ignored by US and SEA — use category URLs there.
onlyNewProductsReturn only recently-added products instead of the whole category. Supported on US/Canada, the 7 EU markets, all 10 SEA markets and India; others are skipped with an error. See Incremental refresh below.
newProductsPageLimitPages per category on sort-only markets (SEA, India). Default 3. Ignored where a real filter exists.
advancedFilterUS/Canada only. Raw refinement expression sent as ref, e.g. filters[isNew]=true. Overrides onlyNewProducts.
proxyProxy configuration. Residential strongly recommended; set apifyProxyCountry to match the target market (e.g. FR for sephora.fr, NZ for sephora.nz) — see Tips.
maxConcurrencyConcurrent requests. Default 5.
maxRequestsPerCrawlGlobal hard cap on total Crawlee requests across every active market (includes listing, search, detail). 0 = unlimited.

Supported URL shapes

Paste the URL exactly as it appears in your browser — extra params are fine. Tracking params (?icid2=…) are ignored; ?skuId=… on a product URL preselects that variant.

ShapeExampleWhat you get
Product pagesephora.com/product/…-P467749That one product, all variants
Category pagesephora.com/shop/face-makeupEvery product in the category, paginated
Editorial page (US/CA)sephora.com/beauty/new-skin-care-productsThe page's editorial product list — see the note below

Editorial /beauty/… pages are the grids Sephora links from its homepage and category nav ("New", "Bestsellers", "Just Dropped"). These pages return the page's editorial product list — typically 7–28 items. Note that Sephora builds the grid you actually see on the site from a separate ranked feed, which overlaps this list only slightly and which this actor does not currently call. So treat a /beauty/… result as "the products Sephora tags on that page", not "the products displayed on it" — they are largely different. If you need a complete, stable assortment for a topic, use the matching /shop/… category URL, which paginates fully.

/beauty/… pages that carry articles or buying guides rather than a product grid are skipped with a log line. Canadian URLs (sephora.com/ca/en/beauty/…) work the same way. Other storefronts use their own listing grammar (e.g. sephora.fr/shop/…, sephora.nz/products/…).

Incremental refresh (keeping a catalogue up to date)

Re-scraping every product to catch a handful of changes is slow and expensive. Two things make incremental runs cheap.

1. Fetch only what's new. Set onlyNewProducts and pass your category URLs (see test-new-products.json for a ready-made US config). Measured on the US catalogue, 2026-08-19:

ProductsListing requests
Whole US catalogue10,784~180
New only1,201~21

EU sees a similar ratio — a French category of 886 products drops to 113.

2. Detect changes without fetching product pages. Category listings already carry productId, brand, price, rating and review count. A ~180-request sweep of all six US categories fingerprints the entire catalogue, so you only fetch full product records for the items that actually moved.

A practical schedule: onlyNewProducts hourly for discovery, a full listing sweep nightly for change detection, and full product fetches only for the diff.

What "new" means, per market

MarketsHowWhat you get
US, Canada, EU (FR, IT, DE, ES, PL, RO, PT)Server-side filterExactly the products Sephora flags as new
SEA (all 10), IndiaNewest-first sort, cappedThe most recently published, newProductsPageLimit pages per category (default 3 ≈ 70–110 products)
MENA, UK, LATAMNot supportedSkipped with an error — see below

MENA, UK and LATAM are skipped, not silently widened. Rather than return their full catalogue at your cost, those URLs are refused with a clear per-market error. If a run has no supported market left, it stops with nothing scraped. Why each is out:

  • UK — its catalog exposes no newness filter or sort at all.
  • MENA — a usable mechanism now exists (the search catalog has a new category, ~281 products) but is not wired up yet. Until it is, pass that category directly via categoryIds if you need it.
  • LATAM — unverified; the market is auth-blocked.

Caveats worth designing around

  • It is Sephora's flag, not your clock. On filter markets this is Sephora's own merchandising flag, which includes items flagged new for weeks — not "added since your last run". Diff product IDs against your own store for true novelty.
  • Sort markets give recency, not a flagged set. On SEA and India you get the newest N per category, bounded by newProductsPageLimit. Raising the cap costs proportionally more requests.
  • Dedupe by productId. The listing feed reorders slightly between page requests, so a single sweep can repeat ~5% of rows and miss a few. Run twice if you need near-complete coverage.
  • advancedFilter is US/Canada only and overrides onlyNewProducts; a ref= already on a start URL overrides both. Every override is logged.

Supported markets

RegionMarket IDCountryLocaleCurrencyHostname
AmericasusUnited Statesen-USUSDsephora.com
AmericasusCanadaen-CA / fr-CACADsephora.ca
EUeu-frFrancefr-FREURsephora.fr
EUeu-itItalyit-ITEURsephora.it
EUeu-deGermanyde-DEEURsephora.de
EUeu-esSpaines-ESEURsephora.es
EUeu-plPolandpl-PLPLNsephora.pl
EUeu-czCzech Republiccs-CZCZKsephora.cz
EUeu-grGreeceel-GREURsephora.gr
EUeu-roRomaniaro-RORONsephora.ro
EUeu-ptPortugalpt-PTEURsephora.pt
MENAmena-aeUnited Arab Emiratesen-AEAEDsephora.me/ae-en
MENAmena-saSaudi Arabiaen-SASARsephora.me/sa-en
MENAmena-bhBahrainen-BHBHDsephora.me/bh-en
MENAmena-omOmanen-OMOMRsephora.me/om-en
MENAmena-kwKuwaiten-KWKWDsephora.me/kw-en
MENAmena-qaQataren-QAQARsephora.me/qa-en
UKukUnited Kingdomen-GBGBPsephora.co.uk
IndiainIndiaen-ININRsephora.in
APACsea-nzNew Zealanden-NZNZDsephora.nz
APACsea-auAustraliaen-AUAUDsephora.com.au
APACsea-sgSingaporeen-SGSGDsephora.sg
APACsea-myMalaysiaen-MYMYRsephora.com.my
APACsea-thThailandth-THTHBsephora.co.th
APACsea-idIndonesiaid-IDIDRsephora.co.id
APACsea-phPhilippinesen-PHPHPsephora.ph
APACsea-hkHong Kongzh-HKHKDsephora.hk
APACsea-twTaiwanzh-TWTWDsephora.tw
APACsea-bnBruneien-BNBNDsephora.bn

MENA is one storefront, six markets. All six Middle East countries share the single host www.sephora.me and are told apart by the locale prefix in the path — https://www.sephora.me/ae-en/p/{slug}/P{id}. Paste those URLs as-is; the actor reads the prefix to pick the market. Arabic prefixes (ae-ar) resolve to the same market and return English content.

Output

Each dataset item follows the schema in .actor/dataset_schema.json. Example (NZ):

{
"market": "sea-nz",
"source": {
"id": 58792,
"crawlUrl": null,
"canonicalUrl": "https://www.sephora.nz/products/rare-beauty-true-to-myself-natural-matte-longwear-foundation",
"retailer": "SEPHORA",
"currency": "NZD"
},
"brand": "Rare Beauty",
"title": "True To Myself Natural Matte Longwear Foundation",
"description": "<p>A self-priming and self-setting foundation...</p>",
"shortDescription": "<p>3-in-1 foundation primes, covers and sets...</p>",
"ingredients": "Aqua/Water, Cyclopentasiloxane, Glycerin, Phenyl Trimethicone...",
"howToUse": "<p>Shake well. Apply a small amount onto the back of your hand and use a brush or fingertips to blend onto skin.</p>",
"currentSku": "770225",
"categories": ["makeup/face/foundation"],
"options": [
{ "name": "shade", "id": "66488", "values": [{"value": "1 Fair Neutral", "label": "1 Fair Neutral", "orderable": true}] }
],
"variants": [
{
"id": "276343",
"sku": "770225",
"price": { "current": 77.0, "original": 77.0, "stockStatus": "IN_STOCK" },
"options": [{"name": "shade", "value": "1 Fair Neutral"}],
"highlights": ["NEW", "Only at Sephora"],
"wishlisted": null
}
],
"medias": [{"url": "https://www.sephora.nz/.../foundation-shade.jpg", "type": "image"}],
"stats": { "reviewCount": 971, "rating": 4.8, "lovesCount": null },
"sentiments": null
}

Download as JSON, CSV, XLSX, or HTML from the Dataset tab.

Data fields

FieldTypeUSEUSEANotes
marketstringMarket identifier stamped by dispatcher
source.idnumber/stringUS: string P123; EU/SEA: numeric
source.crawlUrlstringUS-only
source.canonicalUrlstring
source.currencystringPer-market currency
descriptionstring (HTML)Full product description
shortDescriptionstring (HTML)Short description / benefits
ingredientsstringFull ingredient list. Empty for non-cosmetic SKUs
howToUsestring (HTML)Usage / application instructions
currentSkustringStorefront-default SKU; matches one of variants[].id
sizestringHeadline size/volume of the default SKU, e.g. "1 oz / 30 mL". US/CA-only
options[].values[].descriptionstringPer-shade undertone/finish text, e.g. "light, neutral peach". Colour shades only; US/CA-only
variants[].sizestringPer-SKU size/volume (ancillary minis differ from headline). US/CA-only
variants[].price.currentnumberLocal currency
variants[].price.stockStatusenumIN_STOCK / OUT_OF_STOCK / UNKNOWN
variants[].wishlistedbooleanSEA-only
stats.reviewCount / ratingnumber
stats.lovesCountnumberSEA does not expose loves; see wishlisted instead
sentimentsobjectUS-only AI review summaries

Tips / advanced options

  • Pin the proxy country to the target market. A residential exit in a mismatched country (e.g. a US IP hitting sephora.fr) is the single largest source of 403s from Sephora's Akamai layer. Set apifyProxyCountry to the storefront's country: US / CA for US, FR/IT/DE/ES/PL/RO for EU (PT routes through ES, CZ through PL, GR through RO), and the matching ISO code for each APAC country (NZ, AU, SG, MY, TH, ID, PH, HK, TW, BN). Unpinned residential works but expect a noticeably lower success rate.
  • US — set maxConcurrency between 2 and 5. Sephora US is aggressive about rate-limiting; higher concurrency increases 403 rates, not throughput.
  • EUmaxConcurrency=3 is the sweet spot. Higher concurrency triggers extra session-refresh churn with no throughput gain.
  • SEAmaxConcurrency=16 finishes a full-market catalog scrape in a few minutes.
  • Mixed runs — concurrency is enforced per-market (each market gets its own semaphore), so a mixed run at concurrency=5 doesn't blast any one storefront.
  • Smoke test first — set maxRequestsPerCrawl=10 before your first production run in a new market.

FAQ

Will my existing US run configs keep working? Yes. Pre-2.0 inputs — startUrls, maxConcurrency, proxy, maxRequestsPerCrawl — behave identically. The only output change is a new market key on every item, which is a soft addition (not a breaking change).

Do I need a new API token? No. Your existing Apify API token works unchanged.

What's the market field in the output? The dispatcher's auto-detected country/region tag. Useful for filtering when a single run scrapes multiple storefronts. Values match the table under Supported markets.

Why does stats.lovesCount show null for NZ/AU/etc.? Sephora SEA (the API that backs NZ/AU/SG/MY/TH/ID/PH/HK/TW/BN) doesn't expose a loves counter. Each variant has a boolean wishlisted field instead — use it if you need the SEA equivalent.

How do I scrape only a specific market? Paste only URLs from that market's hostname, OR set the market input field explicitly (e.g. eu-fr).

Why do I see sephora-scraper.internal/... URLs in the Run's Request Queue tab? Those are internal tracking identifiers, not the URLs the actor fetches. The actor resolves them at the moment of request and the resolved form is never written to the Console, logs, or the dataset. Your actual scrape targets the public Sephora stores you requested in startUrls.

Will re-running with the same input re-scrape everything? Yes. Each run starts with a fresh Request Queue (the default Apify queue, purged per run), so hitting Run twice will re-scrape every URL. If you need resume-on-rerun semantics for very long crawls, split the input into smaller batches.

Why did my run abort with "circuit breaker tripped"? Every 50 consecutive failed requests trigger an early abort — this protects you from burning compute when the target is entirely down. Check Sephora's availability, then re-run. Normal transient errors (429s, 5xxs on individual products) don't trip the breaker because they're mixed with successes.

Legality / Terms of Service. Scraping is a gray area that depends on jurisdiction and intended use. Review Sephora's ToS and consult counsel before running at scale. This actor is provided as-is for research, compliance, competitive monitoring, and other lawful use cases.

Support

Issues and feature requests: open an issue on the Apify listing or email the autofacts team. For custom-scope requests (historical backfills, loyalty data, sub-brand catalogs), contact us directly.