# Mr.Bricolage Scraper — French DIY & Home Improvement (`studio-amba/mrbricolage-scraper`) Actor

Scrape products, prices, and details from mr-bricolage.fr, the French Mr.Bricolage DIY and home improvement retailer network. Supports keyword search and category browsing. Uses a real headful Chrome browser to pass Cloudflare's managed challenge.

- **URL**: https://apify.com/studio-amba/mrbricolage-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 $5.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/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

## Mr.Bricolage Scraper

Extract product data, prices, and details from mr-bricolage.fr — the French Mr.Bricolage DIY and home improvement retail network. Built for teams that need reliable pricing and catalog data from a site that actively blocks scrapers with a Cloudflare managed challenge.

### What is Mr.Bricolage Scraper?

Mr.Bricolage is a French cooperative network of independently-run DIY, garden, and home improvement stores, competing directly with Leroy Merlin, Castorama, and Brico Dépôt. This scraper extracts structured product data from their online catalog: names, brands, prices, stock status, SKUs, EAN barcodes, and categories.

Here is what teams use it for:

- **French DIY price benchmarking** — compare Mr.Bricolage pricing against Leroy Merlin, Castorama, Brico Dépôt, and Bricomarché for the same product categories
- **EAN-based product matching** — match products across French retailers by barcode for genuine like-for-like comparisons
- **Catalog monitoring** — track new listings, price changes, and stock status over time
- **Renovation cost research** — pull pricing across paint, tools, garden, and building material categories for project budgeting

### What data does Mr.Bricolage Scraper extract?

Each product includes the following fields when available:

- **Product name** — full listing title in French
- **Brand** — manufacturer name, from the product's structured data
- **Price** — current price in EUR, read from the rendered page (what a shopper actually sees)
- **Original price** — pre-discount price, when the product is on promotion
- **Currency** — always `"EUR"`, included next to every price
- **EAN** — European Article Number (barcode/GTIN), when the manufacturer supplies one
- **SKU** — Mr.Bricolage internal product reference
- **In stock** — `true`, `false`, or `null` when the site doesn't state availability (see Limitations)
- **Rating** — customer rating out of 5, when a review widget is present on the page
- **Review count** — number of customer reviews, when present
- **Image URL** — main product image
- **Description** — product description, HTML stripped
- **Category** — category from the page breadcrumb

### Why this site needs a different approach

mr-bricolage.fr runs Cloudflare's interactive managed challenge on every page, including the homepage and robots.txt — a plain HTTP request gets `HTTP 403` with a `cf-mitigated: challenge` header, no exceptions. Datacenter proxies and headless browsers get stuck in the challenge loop.

This actor drives a real, headful Google Chrome browser (not headless Chromium) through Apify's residential proxy network. That combination consistently passes the challenge where headless automation fails — the same approach used across our fleet on other Cloudflare-managed-challenge sites. It costs more per result than a plain HTTP scraper: expect higher compute and proxy usage per page than our CheerioCrawler-based DIY actors (Brico Dépôt, Bricomarché). See "How much does it cost?" below for real numbers.

### How to scrape Mr Bricolage data

#### Search by keyword

```json
{
    "searchQuery": "peinture",
    "maxResults": 50
}
```

Useful French search terms: `"peinture"` (paint), `"perceuse"` (drill), `"carrelage"` (tiles), `"tondeuse"` (lawnmower), `"robinet"` (faucet), `"isolant"` (insulation), `"parquet"` (flooring).

#### Scrape a brand page

```json
{
    "startUrls": [
        { "url": "https://www.mr-bricolage.fr/marques/bosch.html" }
    ],
    "maxResults": 100
}
```

Note: not every `/maison/...`-style category link on the site is a live product grid — some are landing pages that only link to subcategories. Brand pages (`/marques/{brand}.html`) and search-result pages are reliably product grids; if a category URL comes back empty, fall back to `searchQuery` for that category's keyword instead.

#### Scrape specific product pages directly

```json
{
    "startUrls": [
        { "url": "https://www.mr-bricolage.fr/-adhesif-toile-10m.html" }
    ]
}
```

#### Default run

If you provide neither `searchQuery` nor `startUrls`, the scraper runs a default search (`"peinture"`) so an empty input still returns data.

#### Input reference

| Field | Type | Description |
|-------|------|-------------|
| `searchQuery` | String | French keyword (e.g., `"peinture"`, `"perceuse"`). Ignored if `startUrls` is set. |
| `startUrls` | Array | Category, brand, search-result, or direct product page URLs (max 50). |
| `maxResults` | Integer | Product limit (default: 50, max: 2,000 — kept low because each page load is a full headful browser navigation). |
| `proxyConfiguration` | Object | Residential proxies are required, not just recommended — Cloudflare's managed challenge blocks datacenter IPs before the page even loads. |

### Output

```json
[
    {
        "name": "ADHESIF TOILE 10M",
        "brand": "ALDES",
        "price": 7.20,
        "currency": "EUR",
        "originalPrice": null,
        "ean": "3542280351610",
        "sku": "AF283456",
        "inStock": true,
        "rating": null,
        "reviewCount": null,
        "imageUrl": "https://media.mr-bricolage.fr/media/catalog/product/a/f/af283456-adhesif-toile.jpg",
        "description": "Assure l'etancheite de votre reseau de gaines. Permet de fixer la gaine.",
        "category": "Colles et adhesifs",
        "url": "https://www.mr-bricolage.fr/-adhesif-toile-10m.html",
        "scrapedAt": "2026-08-21T14:30:00.000Z"
    }
]
```

Export in **JSON**, **CSV**, **Excel**, **XML**, or **RSS** from the Apify dataset.

### How much does it cost?

This actor drives a real headful Chrome browser through residential proxies for every page — both listing pages and each product's detail page — which costs more per result than our HTTP-based DIY scrapers.

| Scenario | Products | What it costs |
|----------|----------|----------------|
| Quick keyword search | 10 | Roughly a dozen browser page loads (1 listing page + 10 detail pages) |
| Category scrape | 50 | Roughly 55-60 browser page loads |
| Larger catalog pull | 200 | Roughly 210-220 browser page loads, several listing pages of pagination |

Compute and residential-proxy usage scale directly with page count, not with a flat per-run fee — size `maxResults` to your actual need. A run's usage cost only settles once Apify reports the run as **SUCCEEDED**; reading the dataset mid-run understates the eventual cost.

### Can I integrate?

Pipe Mr.Bricolage data into your tools:

- **Webhooks** — trigger actions when scraping finishes
- **Google Sheets** — sync products and prices to spreadsheets
- **Slack / Microsoft Teams** — alert on price changes or new products
- **Zapier / Make** — connect to thousands of apps
- **Amazon S3 / Google Cloud** — store datasets in cloud buckets
- **PostgreSQL / MySQL / BigQuery** — direct database push
- **API** — programmatic access from any language

### Can I use it as an API?

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("studio-amba/mrbricolage-scraper").call(run_input={
    "searchQuery": "peinture",
    "maxResults": 50,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['name']} - EUR {item['price']}")
```

#### JavaScript

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

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("studio-amba/mrbricolage-scraper").call({
    searchQuery: "peinture",
    maxResults: 50,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach(item => console.log(`${item.name} - EUR ${item.price}`));
```

### FAQ

**Why does this actor use a headful browser instead of a plain HTTP request?**
mr-bricolage.fr serves Cloudflare's interactive managed challenge on every page. A real, visible Chrome browser passes that challenge reliably; headless browsers and plain HTTP requests get stuck in a redirect loop.

**Does search work reliably?**
Yes. It calls the same `/catalogsearch/result/` endpoint the site's own search box uses, so results match what a shopper sees.

**Can I scrape a full category?**
Yes — pass a category or brand page URL (e.g. `https://www.mr-bricolage.fr/maison/decoration.html`) as a `startUrls` entry. The scraper follows pagination automatically up to `maxResults`.

**What about store-specific pricing?**
Mr.Bricolage is a network of independently-run franchise stores. The catalog price shown online (and returned here) is the network's online reference price; individual physical stores can price differently and the scraper does not simulate selecting a specific store.

**Why is `inStock` sometimes `null`?**
The site doesn't always publish an online-wide availability flag for every product — local stock is store-specific. `null` means "not stated," not "out of stock." Treat `true`/`false` as authoritative and `null` as unknown.

**How does this compare to Leroy Merlin or Castorama Scraper?**
Same DIY vertical, different retailer. Run both to compare Mr.Bricolage against the bigger chains, or combine with our full French DIY cluster for a complete market view.

### Limitations

- All data is in French from mr-bricolage.fr
- Requires residential proxies — the Cloudflare managed challenge blocks datacenter IPs outright
- `inStock` reflects online-wide availability where the site publishes it; it is not per-store stock
- Ratings/reviews are only populated when the site's review widget renders data for that product
- Runs are slower and cost more per result than plain-HTTP scrapers in this cluster, because every page (listing and detail) is a full headful-browser navigation

### Other DIY & hardware scrapers

Build complete European building material price intelligence with our scraper collection:

- [Leroy Merlin Scraper](https://apify.com/studio-amba/leroymerlin-scraper) — France
- [Brico Depot Scraper](https://apify.com/studio-amba/bricodepot-scraper) — France
- [Bricomarche Scraper](https://apify.com/studio-amba/bricomarche-scraper) — France
- [Bricorama Scraper](https://apify.com/studio-amba/bricorama-scraper) — France
- [Castorama Scraper](https://apify.com/studio-amba/castorama-scraper) — France/Poland
- [Brico Scraper](https://apify.com/studio-amba/brico-scraper) — Belgium
- [Hubo Scraper](https://apify.com/studio-amba/hubo-scraper) — Belgium/Netherlands
- [Gamma Scraper](https://apify.com/studio-amba/gamma-scraper) — Netherlands
- [Praxis Scraper](https://apify.com/studio-amba/praxis-scraper) — Netherlands
- [OBI Scraper](https://apify.com/studio-amba/obi-scraper) — Germany
- [Hornbach Scraper](https://apify.com/studio-amba/hornbach-scraper) — Germany/Europe
- [Bauhaus Scraper](https://apify.com/studio-amba/bauhaus-scraper) — Germany/Europe
- [Toom Scraper](https://apify.com/studio-amba/toom-scraper) — Germany
- [Hagebau Scraper](https://apify.com/studio-amba/hagebau-scraper) — Germany
- [Globus Baumarkt Scraper](https://apify.com/studio-amba/globus-baumarkt-scraper) — Germany
- [Byggmax Scraper](https://apify.com/studio-amba/byggmax-scraper) — Sweden
- [Clas Ohlson Scraper](https://apify.com/studio-amba/clasohlson-scraper) — Scandinavia
- [Jula Scraper](https://apify.com/studio-amba/jula-scraper) — Sweden
- [K-Rauta Scraper](https://apify.com/studio-amba/krauta-scraper) — Finland

### Your feedback

Running into problems or want additional features? Let us know through the actor's Apify Store page or the community forum. We maintain all our scrapers actively and prioritize fixes based on user feedback.

# Actor input Schema

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

Search for products by keyword (e.g., 'peinture', 'perceuse', 'carrelage'). Ignored if startUrls is provided. Defaults to 'peinture' if both are empty.

## `startUrls` (type: `array`):

Mr.Bricolage category or search result page URLs to scrape directly (e.g. https://www.mr-bricolage.fr/maison/decoration.html), or direct product page URLs. Overrides searchQuery when provided. Maximum 50 URLs per run. Left empty by default so the run uses searchQuery instead.

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

Maximum number of products to return.

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

Proxy settings. mr-bricolage.fr runs a Cloudflare managed challenge on every page — residential proxies are required, datacenter IPs get blocked before the browser even loads.

## Actor input object example

```json
{
  "searchQuery": "peinture",
  "startUrls": [],
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}
```

# 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": "peinture",
    "startUrls": [],
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "FR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/mrbricolage-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": "peinture",
    "startUrls": [],
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "FR",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/mrbricolage-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": "peinture",
  "startUrls": [],
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}' |
apify call studio-amba/mrbricolage-scraper --silent --output-dataset

```

## MCP server setup

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