# Carrefour Belgium Scraper — Grocery Prices (`studio-amba/carrefour-be-scraper`) Actor

Scrape products, prices, unit prices, stock status, and images from carrefour.be, Belgium's largest grocery retailer. Search any keyword and export clean structured grocery data.

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

## Pricing

from $1.20 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Carrefour Belgium Scraper — Grocery Prices

Scrape grocery products, prices, unit prices, and stock status from **carrefour.be**, Belgium's largest supermarket retailer. Search any keyword and export clean, structured grocery data.

### Why use this actor?

Carrefour is one of the biggest grocery catalogues in Belgium, and its prices, promotions, and stock status are useful for price monitoring, competitor analysis, and market research alongside Colruyt and Delhaize. This actor turns a keyword search into a structured dataset you can drop straight into a spreadsheet, database, or price-comparison pipeline.

### How to scrape Carrefour Belgium data

1. Enter a **search query** in French or Dutch (for example `lait`/`melk`, `cafe`/`koffie`, `pain`/`brood`, or `fromage`/`kaas`). The actor uses the French `/fr` storefront path, which returns the same national catalogue as the Dutch `/nl` path.
2. Set **Max Results** to how many products you want (each search request returns up to 100 products; the actor paginates automatically).
3. Provide a **Bright Data API key** (see "Anti-bot" below).
4. Run the actor. Results stream into the dataset and can be exported as JSON, CSV, Excel, or via the API.

Optionally enable **Fetch product details** to visit each product page and add a human-readable category and full description. This is slower and more expensive because it makes one extra request per product, and it is not needed for price, unit price, brand, or stock status — those come from the search page directly.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchQuery` | String | No | Search keyword in French (default: `lait`) |
| `maxResults` | Integer | No | Maximum products to return (default: 100) |
| `fetchDetails` | Boolean | No | Visit each product page for a readable category + description (default: false) |
| `brightDataApiKey` | String | Yes | Bright Data Web Unlocker API key (or set `BRIGHT_DATA_API_KEY` env var) |
| `proxyConfiguration` | Object | No | Kept for compatibility; fetching is handled by Bright Data |

### Output

Each result contains:

| Field | Type | Example |
|-------|------|---------|
| `productName` | String | `"Lait Demi-Écrémé 6 x 1 L"` |
| `brand` | String | `"Simpl"` |
| `price` | Number | `5.10` |
| `currency` | String | `"EUR"` |
| `unitPrice` | String | `"0,85 €/l"` |
| `originalPrice` | Number | Only when the site renders a strike-through "was" price |
| `discount` | String | `"-15%"` (only when on promotion) |
| `category` | String | `"Lait demi-écrémé"` (human-readable with Fetch product details, otherwise an internal category code) |
| `productId` | String | `"04875033"` — Carrefour's own internal product/SKU code |
| `inStock` | Boolean | `true` |
| `imageUrl` | String | Primary product image URL |
| `productDescription` | String | Full description (only with Fetch product details) |
| `url` | String | Full product page URL |
| `scrapedAt` | String | ISO 8601 timestamp |

### Example output

```json
{
    "productName": "Lait Demi-Écrémé 6 x 1 L",
    "brand": "Simpl",
    "price": 5.1,
    "currency": "EUR",
    "unitPrice": "0,85 €/l",
    "category": "Lait demi-écrémé",
    "productId": "04875033",
    "inStock": true,
    "imageUrl": "https://cdn.carrefour.eu/420_04875033_T1.webp",
    "url": "https://www.carrefour.be/fr/lait-demi-ecreme-6-x-1-l/04875033.html",
    "scrapedAt": "2026-09-14T19:43:33.319Z"
}
```

### Anti-bot: Bright Data Web Unlocker required

Carrefour.be is protected by Cloudflare Bot Management (an IP-reputation block, not a JS-only challenge — plain HTTP requests and a plain headless browser both receive a "Attention Required!" 403 page). To fetch pages reliably, this actor uses the [Bright Data Web Unlocker](https://brightdata.com) (zone `web_unlocker1`).

You need a Bright Data account with a Web Unlocker zone. Provide the API key either:

- in the input field **Bright Data API Key**, or
- as the environment variable `BRIGHT_DATA_API_KEY`.

Bright Data bills per request. Because each search request returns up to 100 products in a single request, the anti-bot cost per product is very low when you scrape the listing only (the default). Enabling **Fetch product details** adds one request per product and increases both time and cost significantly.

### Cost estimate

- **Listing only (default):** roughly one Bright Data request per 100 products, plus Apify compute. Scraping 1,000 products is about 10 page requests — fast and cheap.
- **With Fetch product details:** one extra request per product (about 1,010 requests for 1,000 products), so runs are much longer and cost more. Only enable it when you need the readable category or full description.
- A run's usage cost only settles after it reports **SUCCEEDED** — a failed or aborted run may still have consumed proxy requests up to that point, and reading the dataset mid-run will undercount the real cost.

### How pagination works

Carrefour Belgium's search uses `?q=<keyword>&start=<offset>&sz=<pageSize>` (Salesforce Commerce Cloud's standard offset pagination). The actor requests 100 results per page and keeps going until it reaches your Max Results or runs out of products, deduplicated by Carrefour's internal product ID so the same item is never exported twice.

For long runs with **Fetch product details** enabled, the actor persists its progress (seen products and page cursor) via `Actor.useState`. If Apify migrates the run to another host, it resumes where it left off instead of restarting, so you never get duplicate rows or a half-finished catalogue.

### Platform notes (for anyone comparing this to our other Carrefour scrapers)

We also run [Carrefour France](https://apify.com/store) and [Carrefour Spain](https://apify.com/store) scrapers. All three are genuinely different platforms under one brand, not config swaps of each other:

- **carrefour.fr** runs a React/Next storefront behind DataDome.
- **carrefour.es** runs Oracle ATG/Endeca behind Cloudflare Bot Management, with a broken server-side search (this actor resolves keywords against a bundled category-sitemap snapshot instead).
- **carrefour.be** (this actor) runs Salesforce Commerce Cloud behind Cloudflare Bot Management, with working server-side search.

Because of this, field coverage differs by market. Carrefour Belgium does not publicly expose EAN/GTIN barcodes or customer ratings anywhere on the storefront (verified on both private-label and branded products), so this actor does not return `ean`, `rating`, or `reviewCount` fields — that's a genuine storefront gap, not a scraping limitation.

### Limitations

- Prices and stock status are the national Carrefour Belgium catalogue values and may differ from a specific store or Drive/home-delivery slot.
- No EAN/GTIN barcodes or customer ratings — this storefront does not publish them.
- `category` returns an internal code from the search results unless **Fetch product details** is enabled, which resolves it to the human-readable breadcrumb category.
- A Bright Data Web Unlocker key is required; without it the actor cannot fetch pages.
- Data is scraped from the public website and may change without notice.
- Respect the website's terms of service and use responsibly.

### Related Scrapers

- [Colruyt Scraper](https://apify.com/store) — Belgian grocery prices
- [Delhaize Scraper](https://apify.com/store) — Belgian grocery prices
- [Carrefour France Scraper](https://apify.com/store) — French grocery prices with EAN barcodes
- [Carrefour Spain Scraper](https://apify.com/store) — Spanish grocery prices

### 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`):

Search carrefour.be for products by keyword, in French (e.g. 'lait', 'cafe', 'pain', 'chocolat'). Each search page returns up to 100 products; the scraper paginates until it reaches Max Results.

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

Maximum number of products to return.

## `fetchDetails` (type: `boolean`):

Visit each product page to enrich results with a human-readable category and full description. This makes one extra request per product, so runs take much longer and cost more. Price, unit price, brand and stock status are already captured from the search page without this.

## `brightDataApiKey` (type: `string`):

Your Bright Data API key for the Web Unlocker zone (web\_unlocker1). Required to bypass Carrefour Belgium's Cloudflare Bot Management protection. Get one at https://brightdata.com. Can also be provided via the BRIGHT\_DATA\_API\_KEY environment variable.

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

Proxy settings. Kept for compatibility — page fetching is handled by Bright Data Web Unlocker, so this does not affect scraping.

## Actor input object example

```json
{
  "searchQuery": "lait",
  "maxResults": 20,
  "fetchDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/carrefour-be-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,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/carrefour-be-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,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call studio-amba/carrefour-be-scraper --silent --output-dataset

```

## MCP server setup

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