# Système U (CoursesU.com) Scraper — French Grocery Prices (`studio-amba/coursesu-scraper`) Actor

Scrape products, prices, unit prices, EAN barcodes, ratings and images from coursesu.com, Système U's French grocery drive/delivery site. Search by keyword and export clean structured data.

- **URL**: https://apify.com/studio-amba/coursesu-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 result scrapeds

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/actors/running/actors-in-store.md#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

## Système U (CoursesU.com) Scraper — French Grocery Prices

Scrape grocery products, prices, unit prices, EAN barcodes and ratings from **coursesu.com**, the online drive/delivery site for Système U (Super U, Hyper U, U Express), France's #3 grocery chain by store count. Search by keyword and export clean, structured grocery data.

### Why use this actor?

Système U runs thousands of stores across France under a cooperative model, and coursesu.com prices are store-specific — the site shows no price on any product at all until a shopper picks a store. This actor drives that store-selection step automatically, the same way a real shopper would, and returns priced products in structured form. Every product carries its EAN barcode, price, unit price, and Bazaarvoice rating, so the data is directly usable for price monitoring, competitor analysis, and product matching against other French grocery retailers.

### How to scrape Système U data

1. Enter a **search query** in French (for example `lait`, `pain`, `cafe`, `fromage`, or `yaourt`). coursesu.com has a genuine free-text search, so any French grocery keyword works.
2. Optionally set a **store address / postal code**. If left empty, the actor picks the first store suggested near the Bright Data exit node's location — coursesu.com always shows at least one nearby store to pick from.
3. Set **Max Results** to how many products you want.
4. Provide a **Bright Data Scraping Browser** endpoint (see "Anti-bot" below).
5. Run the actor. Results stream into the dataset and can be exported as JSON, CSV, Excel, or via the API.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchQuery` | String | No | French grocery keyword (default: `lait`) |
| `postalCode` | String | No | Store address / postal code. Leave empty to use the nearest suggested store |
| `maxResults` | Integer | No | Maximum products to return (default: 40) |
| `sbrWsCdp` | String | Yes | Bright Data Scraping Browser CDP endpoint (or set `SBR_WS_CDP` env var) |
| `proxyConfiguration` | Object | No | Kept for compatibility; rendering is handled by Bright Data Scraping Browser |

### Output

Each result contains:

| Field | Type | Example |
|-------|------|---------|
| `name` | String | `"Lait UHT demi-écrémé Bleu Blanc Coeur - 6 bouteilles de 1L"` |
| `brand` | String | `"U"` (Système U's own "PRODUIT U" private label; omitted for third-party brands — see Limitations) |
| `price` | Number | `6.48` |
| `currency` | String | `"EUR"` |
| `pricePerUnit` | String | `"1,08 €/l"` |
| `ean` | String | `"3256225425617"` |
| `productId` | String | `"7634896"` |
| `rating` | Number | `4.7` |
| `reviewCount` | Number | `1191` |
| `imageUrl` | String | Primary product image URL |
| `url` | String | Full product page URL |
| `scrapedAt` | String | ISO 8601 timestamp |

### Example output

```json
{
    "name": "Lait UHT demi-écrémé Bleu Blanc Coeur - 6 bouteilles de 1L",
    "brand": "U",
    "price": 6.48,
    "currency": "EUR",
    "pricePerUnit": "1,08 €/l",
    "ean": "3256225425617",
    "productId": "7634896",
    "rating": 4.7,
    "reviewCount": 1191,
    "imageUrl": "https://static.coursesu.com/dw/image/v2/BBQX_PRD/on/demandware.static/-/Sites-digitalu-master-catalog/default/dw84d02ca3/3256225425617_A1N1_7634896_S13.png?sw=172&sh=172&sm=fit",
    "url": "https://www.coursesu.com/p/lait-uht-demi-ecreme-bleu-blanc-coeur---6-bouteilles-de-1l/7634896.html",
    "scrapedAt": "2026-09-13T20:01:37.729Z"
}
```

### Anti-bot: Bright Data Scraping Browser required

coursesu.com sits behind Cloudflare bot management on every path — plain HTTP requests (curl, a headless browser with no anti-bot help) get a hard 403 "Attention Required" challenge page. Clearing that challenge is only half the problem: verified live during build that no product shows a price — not on the search results page, not in a product's schema.org JSON-LD — until a store has been picked. Store selection is a stateful, JavaScript-driven flow (homepage → nearby-store list → "Choisir ce magasin"), which a single stateless HTTP request cannot carry across requests even if it gets past Cloudflare.

This actor uses the [Bright Data Scraping Browser](https://brightdata.com) — a real remote Chromium session — to clear the Cloudflare challenge and drive the store pick exactly like a shopper would, once per run. You need a Bright Data account with a Scraping Browser zone. Provide the CDP endpoint either:

- in the input field **Bright Data Scraping Browser endpoint**, or
- as the environment variable `SBR_WS_CDP`.

The actor blocks image, font, and media requests during the browser session (it only needs the page's text, not the image bytes), which keeps Scraping Browser bandwidth — and cost — down on an image-heavy grocery grid.

### Cost estimate

Scraping Browser is billed per GB of traffic rather than per request. With image/font/media blocking enabled, one store-selection visit plus a page of ~19 search results typically transfers well under 1 MB of text/JS payload. Search results paginate cleanly (`?page=1`, `?page=2`, ...), so a `maxResults` of 100 costs about 5-6 page loads on top of the one-time store selection — a small, largely fixed overhead regardless of how many results are requested.

### Limitations

- **Brand is only populated for Système U's own "PRODUIT U" private label.** Third-party brands (Lactel, Candia, Bocage, etc.) are not exposed as a separate field anywhere in the search results grid — only in the product name text itself. Rather than guess a brand from free text, this field is left empty for those products.
- Prices are specific to the store selected (by `postalCode`, or the nearest store suggested if left empty) and may differ from other Système U stores or the national average.
- A Bright Data Scraping Browser endpoint is required; without it the actor cannot clear the Cloudflare challenge or render the store-selection flow.
- Data is scraped from the public website and may change without notice.
- Respect the website's terms of service and use responsibly.
- Usage cost for a run only settles once the run finishes with status **SUCCEEDED** — a run that fails partway through is not billed for completed results.

### Related Scrapers

- [Intermarché Scraper](https://apify.com/store) — French grocery prices with EAN barcodes
- [Carrefour Scraper](https://apify.com/store) — French grocery prices with EAN barcodes
- [Monoprix France Scraper](https://apify.com/store) — French grocery prices and promotions
- [Auchan Scraper](https://apify.com/store) — French grocery prices and products
- [Leclerc Scraper](https://apify.com/store) — French grocery prices and products

### Need this data on a schedule, or a custom version?

We run this scraper as a managed service for businesses: scheduled runs,
deduplication, delta detection, and delivery to your inbox, Google Sheets,
or API — maintenance included. We can also build a custom version with your
exact fields and filters, or combine multiple sources into one feed.

See [studioamba.dev/services](https://studioamba.dev/services/) or email
<hello@studioamba.dev> for a free data sample.
We maintain 300+ European web scrapers and answer within one business day.

# Actor input Schema

## `searchQuery` (type: `string`):

A French grocery keyword (e.g. 'lait', 'pain', 'cafe', 'fromage', 'yaourt'). Passed directly to coursesu.com's free-text search — no category dictionary needed.

## `postalCode` (type: `string`):

French address or postal code used to select a nearby Système U store. Prices are store-specific — coursesu.com will not show any price without a selected store. If left empty, the actor picks the first store suggested near the Bright Data exit node's location.

## `maxResults` (type: `integer`):

Maximum number of products to return. Results are paginated at roughly 19 products per page.

## `sbrWsCdp` (type: `string`):

CDP WebSocket endpoint for a Bright Data Scraping Browser zone. Required to bypass coursesu.com's Cloudflare protection and render the store-selection flow. Can also be provided via the SBR\_WS\_CDP environment variable.

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

Proxy settings. Kept for compatibility — page rendering is handled by Bright Data Scraping Browser, so this does not affect scraping.

## Actor input object example

```json
{
  "searchQuery": "lait",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "searchQuery": "lait",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/coursesu-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 = {
    "searchQuery": "lait",
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/coursesu-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 '{
  "searchQuery": "lait",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call studio-amba/coursesu-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/coursesu-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/schJa1U6Hxa8saWdM/builds/yJ4P7YoE6TjUGVsDR/openapi.json
