# Sephora France Product Scraper (`axlymxp/sephora-france-scraper`) Actor

Scrape Sephora France (sephora.fr): products by category, brand, or keyword with full pagination. Get TTC & HT prices, discounts, ratings, stock, images, and size/shade variants — structured for price monitoring and market research. France-specialised and reliable. Pay only for results.

- **URL**: https://apify.com/axlymxp/sephora-france-scraper.md
- **Developed by:** [axly](https://apify.com/axlymxp) (community)
- **Categories:** E-commerce, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 dataset items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Sephora France Product Scraper

Extract the **Sephora France** (`www.sephora.fr`) catalogue at scale — products
from any **category**, **brand**, or **keyword**, with full pagination and
optional per‑product detail (long description, exact rating, and size/shade
variants with per‑SKU price and stock).

Unlike generic multi‑country Sephora tools, this actor is **built for the French
market**: it returns France‑specific pricing — both **TTC** (tax included) and
**HT** (tax excluded) — plus discounts, the French category taxonomy, and
variant‑level stock, through a reliable web extraction path.

### Who it's for

- **Beauty brands & market‑intelligence teams** — track your own and competitors'
  assortment, price positioning, discounts, and ratings across Sephora FR.
- **Resellers, arbitrage & price‑comparison sites** — monitor TTC/HT prices,
  price drops (`old_price`, `discount_pct`), and stock at the variant level.
- **E‑commerce & data teams / developers** — a stable JSON schema, incremental
  runs, webhooks, and MCP/AI integration you can build on.
- **Researchers & analysts** — structured French beauty‑market and pricing data.

### What you get (output fields)

| Field                                     | Description                                                                                                 |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `product_id`                              | Master product id (e.g. `P1000211448`).                                                                     |
| `variant_pid`                             | Default purchasable variant id (numeric).                                                                   |
| `name`                                    | Product name.                                                                                               |
| `brand`                                   | Brand / trademark.                                                                                          |
| `price`                                   | Current price, **tax included (TTC)**, EUR.                                                                 |
| `old_price`                               | Previous / crossed‑out price (TTC).                                                                         |
| `price_excl_tax`                          | Price **excluding tax (HT)**.                                                                               |
| `discount`                                | Discount amount reported by the storefront.                                                                 |
| `discount_pct`                            | Discount % computed from `old_price` vs `price`.                                                            |
| `currency`                                | Currency code (EUR).                                                                                        |
| `in_stock`                                | Availability flag.                                                                                          |
| `category_path`                           | Breadcrumb category path.                                                                                   |
| `range` / `nature` / `section` / `target` | Sephora product taxonomy fields.                                                                            |
| `rating`                                  | Average rating (0–5) — exact in detail mode.                                                                |
| `review_count`                            | Number of customer reviews.                                                                                 |
| `sku`                                     | SKU (detail mode).                                                                                          |
| `description`                             | Long product description (detail mode).                                                                     |
| `variants`                                | Size/shade variants: `variant_pid`, `label`, `selected`, and (with `includeVariants`) `price` & `in_stock`. |
| `image`                                   | Primary image URL.                                                                                          |
| `url`                                     | Product page URL.                                                                                           |
| `input_type` / `source`                   | Which input produced the row (`category`/`brand`/`search`/`pid`).                                           |
| `scraped_at`                              | ISO‑8601 scrape timestamp.                                                                                  |

### Use cases

- **Competitive price & promo monitoring** — schedule daily category runs and diff
  `price` / `discount_pct` / `in_stock` to catch price drops and promotions.
- **Assortment & availability tracking** — enable `scrapeDetail` + `includeVariants`
  to follow each shade/size SKU's price and stock.
- **Brand catalogue export** — pull a full brand's line‑up via `brandUrls` for
  merchandising, MAP monitoring, or catalogue enrichment.
- **Market research** — build a France beauty dataset (brands, ranges, ratings,
  HT/TTC pricing) for analysis.

### Input parameters

| Field                | Type    | Default                  | Notes                                                                         |
| -------------------- | ------- | ------------------------ | ----------------------------------------------------------------------------- |
| `categoryUrls`       | array   | `[]`                     | Category slugs (`shop/maquillage-c302`) or full listing URLs. Auto‑paginated.         |
| `brandUrls`          | array   | `[]`                     | Brand slugs (`guerlain-guerl`) or `/marques/de-a-a-z/…` URLs. Auto‑paginated. |
| `searchTerms`        | array   | `[]`                     | Keyword autocomplete lookups (top matches; no pagination/detail).             |
| `productPids`        | array   | `[]`                     | Numeric **variant** PIDs for direct full detail (advanced).                   |
| `scrapeDetail`       | boolean | `false`                  | Enrich each listed product with its detail page.                              |
| `includeVariants`    | boolean | `false`                  | With `scrapeDetail`, price every size/shade variant.                          |
| `includeOutOfStock`  | boolean | `true`                   | Skip out‑of‑stock products when off.                                          |
| `maxItems`           | integer | `500`                    | Global cap across all inputs.                                                 |
| `maxItemsPerInput`   | integer | `0`                      | Per category/brand cap (0 = unlimited).                                       |
| `proxyConfiguration` | object  | Apify Residential **FR** | **Required** — a French IP is mandatory (see below).                          |

At least one of `categoryUrls`, `brandUrls`, `searchTerms`, or `productPids` is
required.

#### Example input

```json
{
    "categoryUrls": ["shop/maquillage-c302", "shop/maquillage/teint/fonds-de-teint-c353"],
    "brandUrls": ["guerlain-guerl"],
    "scrapeDetail": true,
    "includeVariants": false,
    "maxItems": 300,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "FR"
    }
}
```

#### Example output row

```json
{
    "product_id": "P1000211448",
    "variant_pid": "787448",
    "name": "B12 Base Thinner - Sérum nacré vitaminé",
    "brand": "onesize",
    "price": 37.0,
    "old_price": 37.0,
    "price_excl_tax": 30.83,
    "discount": 0.0,
    "discount_pct": null,
    "currency": "EUR",
    "in_stock": true,
    "category_path": "summer vibes/sélection été par catégorie/maquillage",
    "rating": 4.3,
    "review_count": 3,
    "url": "https://www.sephora.fr/p/…-P1000211448.html",
    "input_type": "category",
    "source": "shop/maquillage-c302",
    "scraped_at": "2026-08-03T12:00:00Z"
}
```

### Proxy requirement

Sephora FR is protected by Akamai with a **hard French geo‑block** — any non‑French
IP is denied. This actor therefore **requires a French residential proxy**. The
default `proxyConfiguration` uses Apify Residential proxies with country `FR`; keep
it enabled.

### Scheduling & webhooks

Use **Schedules** to run the actor on a cadence (e.g. daily price checks) and
**Webhooks** to trigger your systems on run completion (`ACTOR.RUN.SUCCEEDED`) —
push new data straight into your database, sheet, or pipeline. Results are
available as JSON, CSV, Excel, or via the Dataset API.

### Use from AI assistants (MCP)

This actor works with the **Apify MCP server**, so AI assistants (Claude, ChatGPT,
Cursor, and other MCP clients) can run it and read its dataset as a tool. Point
your MCP client at Apify and call the actor with the same input shown above to pull
live Sephora FR data into your assistant.

### FAQ

**Which locale/currency is covered?** The French storefront `www.sephora.fr` only —
locale `fr_FR`, prices in EUR (TTC and HT).

**Why is a French proxy mandatory?** Akamai blocks non‑French IPs at the edge; a
French residential IP is required for every request. The default proxy setting
handles this.

**Can I fetch a product by its URL?** Detail requires a numeric `variant_pid`
(from `variant_pid` in listing rows). Master product URLs are challenge‑protected
and can't be fetched directly — browse the category/brand instead, then optionally
pass `productPids`.

**How fresh is the data?** Every run fetches live data at run time.

**Do search terms return everything?** `searchTerms` uses Sephora's autocomplete —
fast, but only the top matches per term. For complete coverage use `categoryUrls`
or `brandUrls`, which paginate the full grid.

**Is it reliable?** The client auto‑rotates French residential exits and retries on
transient blocks; per‑product failures are skipped and logged so a run keeps going.

**Is scraping this data legal?** The actor collects **publicly available** catalogue
data. You are responsible for using the output in compliance with applicable laws,
Sephora's terms, and data‑protection rules.

# Actor input Schema

## `categoryUrls` (type: `array`):

Sephora FR category pages to scrape (auto-paginated). Use a full listing URL (https://www.sephora.fr/shop/maquillage-c302/) or just the path slug (shop/maquillage-c302). Copy slugs from your browser URL bar or the site sitemaps.

## `brandUrls` (type: `array`):

Brand pages to scrape (auto-paginated). Use a full /marques/de-a-a-z/… URL or the short brand slug (e.g. guerlain-guerl).

## `searchTerms` (type: `array`):

Keyword lookups via Sephora's autocomplete. Fast but returns only a handful of top matches per term (no pagination, no detail enrichment).

## `productPids` (type: `array`):

Numeric variant PIDs (e.g. 787448) for direct full detail. These come from the variant\_pid field of a previous run — master product URLs cannot be used (they are challenge-gated).

## `scrapeDetail` (type: `boolean`):

For each listed product, also fetch its detail page (long description, exact rating, SKU, and size/shade variants). Adds one request per product.

## `includeVariants` (type: `boolean`):

With 'Scrape full product detail', also fetch the price and stock of every size/shade variant. Adds one request per variant.

## `includeOutOfStock` (type: `boolean`):

When off, products marked out of stock are skipped.

## `maxItems` (type: `integer`):

Global cap across all inputs. The run stops once this many products are pushed.

## `maxItemsPerInput` (type: `integer`):

Cap per category or brand (0 = unlimited within maxItems).

## `proxyConfiguration` (type: `object`):

A French residential proxy is REQUIRED — Sephora FR (Akamai) hard-blocks any non-French IP. Apify Residential proxies with country FR are used by default.

## Actor input object example

```json
{
  "categoryUrls": [
    "shop/maquillage-c302",
    "shop/maquillage/teint/fonds-de-teint-c353"
  ],
  "brandUrls": [
    "guerlain-guerl"
  ],
  "searchTerms": [
    "dior",
    "vitamine c"
  ],
  "productPids": [
    "787448"
  ],
  "scrapeDetail": false,
  "includeVariants": false,
  "includeOutOfStock": true,
  "maxItems": 500,
  "maxItemsPerInput": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "categoryUrls": [
        "shop/maquillage-c302"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "FR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axlymxp/sephora-france-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "categoryUrls": ["shop/maquillage-c302"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "FR",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("axlymxp/sephora-france-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "categoryUrls": [
    "shop/maquillage-c302"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}' |
apify call axlymxp/sephora-france-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axlymxp/sephora-france-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CcEP4juXZjD6Y6KuM/builds/hhh2BfXD7hmTGfzba/openapi.json
