Boulanger.com - Prices, Discounts, Variants & Reviews
Pricing
from $1.00 / 1,000 product results
Boulanger.com - Prices, Discounts, Variants & Reviews
Scrape Boulanger (boulanger.com) electronics and home-appliance products: current price plus strike-through was-price, specials, colour/capacity variant matrix, brand, category, full spec sheet and customer reviews with ratings. Search by keyword or paste links.
Pricing
from $1.00 / 1,000 product results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
4
Total users
3
Monthly active users
8 hours ago
Last modified
Categories
Share
Boulanger Scraper: Prices, Discounts, Variants and Reviews
Boulanger Scraper turns Boulanger (boulanger.com), the French electronics, multimedia and home-appliance retailer, into structured product data. Get the current price alongside the strike-through reference price and computed discount whenever a product is genuinely marked down, the full colour, capacity and size variant matrix, a flattened spec sheet, and the product's own customer reviews. Search by keyword and/or category, or paste product, search-result and specials-collection links (Soldes, Bons plans) directly, then export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- Was-price and discount, never fabricated. When a product is marked down against boulanger.com's own reference price, both prices are captured plus the computed discount amount and percentage. With Fetch full product detail on, the exact reference price and the site's own promo label come from the product page; without it, the reference price is estimated back from the search card's rounded discount percent. A full-price product simply carries
nullthere, nothing is guessed. - Specials, first-class. Turn on discounted-items-only to keep only products genuinely showing a strike-through discount right now, or paste a specials collection link (Soldes, Bons plans, ventes flash) directly in URL mode.
- Real narrowing, not a filter that quietly does nothing. The first requested brand narrows through the site's own search facet; additional brands, a price band and discounted-items-only are re-checked against the site's real values; sort reorders the full server-side result set.
- Colour, capacity and size variant matrix. Products sold in more than one configuration return every sibling variant, each with its own id, url, price and availability.
- Reviews straight from the product page. Overall rating, rating count, a rating breakdown, and the page's own individual reviews (author, date, rating, title, body, verified-purchase flag where shown).
- Flattened spec sheet. Full detail returns every characteristic the product page itself declares (capacity, dimensions, energy class, EAN and whatever else that category carries) rather than a fixed field list, so nothing category-specific is silently dropped.
- Built for schedules. Turn on incremental mode to get only new and updated products on recurring runs (plus reappeared ones once Emit expired has completed a full scan), or continue one specific interrupted crawl with a resume id.
Use Cases
- Price and deal tracking: monitor a product line, or a whole specials collection, for price drops and new promotions.
- Catalogue and spec-sheet aggregation: build a structured database of specifications across categories for comparison tools.
- Review and sentiment analysis: collect ratings and written reviews to spot recurring complaints or standout products.
- Competitive intelligence: compare Boulanger's pricing and stock against other French electronics retailers.
- Recurring monitoring: schedule the actor to get only new and changed products from the same search or catalogue over time.
Data You Get
Sample shape: values are illustrative placeholders, not from a live product.
| Field | Example |
|---|---|
productId / ean | "8823410", "9999999999991" |
name | "Velunox AeroClean X200 Robot Vacuum" |
brand | "Velunox" |
category / breadcrumbPath | "Aspirateurs robots", ["Accueil", "Electromenager", "Aspirateurs", "Aspirateurs robots"] |
url | "https://www.boulanger.com/ref/8823410" |
price / currency | 225.00, "EUR" |
priceExclTax / sellerName | 187.50, "Sample Retailer" (search and listing results only) |
originalPrice / discountAmount / discountPercent | 300.00, 75.00, 25.0 |
isOnSpecial / promoLabel | true, "Ancien prix" |
onlineAvailable / condition | true, "new" |
unitPrice / storePickupAvailable / isBundle | "11.25 EUR/kg", true, false |
image / images | "https://static.example.com/000000000.jpg", ["https://static.example.com/000000000.jpg"] |
sku | "VLX-X200-BLK" (pasted product link only) |
description | full product description text (when full detail is fetched) |
characteristics | {"Suction power": "10 000 Pa", "Battery life": "45 min", "Made in": "Sample Country"} (when full detail is fetched) |
variants | [{"productId": "8823411", "axis": "couleur", "name": "Sample Colour", "url": "https://www.boulanger.com/ref/8823411", "price": 225.00, "available": true}] (when full detail is fetched) |
rating / reviewCount | 4.6, 82 |
reviews.averageRating / reviews.ratingCount / reviews.totalReviewCount | 4.6, 82, 82 |
reviews.ratingBreakdown | {"1": 0, "2": 0, "3": 0, "4": 1, "5": 2} |
reviews.items[] | [{"rating": 5, "title": "Sample title", "body": "Sample review text.", "author": "Jane D.", "date": "2026-01-01", "verifiedPurchase": null}] |
Incremental mode adds changeType (NEW, UPDATED with changedFields, UNCHANGED, REAPPEARED or EXPIRED), firstSeenAt and lastSeenAt to every record; reviews.ratingBreakdown and reviews.items always reflect only the reviews actually returned this run (capped by Max reviews per product, 0 means no cap), while reviews.averageRating, reviews.ratingCount and reviews.totalReviewCount come from the page's own overall rating widget and normally carry the same total. A review's date and verifiedPurchase never both come back populated: the page's embedded review data supplies a date with verifiedPurchase: null, while the on-page fallback list (used only when that data is empty) supplies verifiedPurchase with date: null. sku, full condition values and a pasted link's own record never appear alongside priceExclTax or sellerName, which only come from a search or listing card.
How to Use
- Pick a mode:
search(keyword and/or category) orurl(paste product, search-result or specials links). - For search mode, fill in the keyword and/or category and any filters (brand, price band, discount-only, sort). For URL mode, paste one or more links.
- Turn on Fetch full product detail and/or Fetch reviews for the fields you need, and set Max products to control run size and cost.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
1. Keyword search, first page, with reviews (default):
{"mode": "search","searchTerm": "aspirateur robot","maxItems": 20}
2. Keyword + category, filtered to a brand, discounted items only, sorted by price:
{"mode": "search","searchTerm": "smartphone","category": "reconditionne","brands": ["Apple"],"specialsOnly": true,"sortBy": "PRICE_ASC","maxItems": 50,"maxPages": 5}
3. Full product detail (spec sheet and variants) and reviews for a pasted product link:
{"mode": "url","urls": ["https://www.boulanger.com/ref/8823410"],"fetchDetails": true,"fetchReviews": true}
4. Daily monitoring: only what changed since the last run:
{"mode": "search","searchTerm": "aspirateur robot","incrementalMode": true,"maxItems": 50}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/boulanger-com-scraper").call(run_input={"mode": "search", "searchTerm": "aspirateur robot"})for product in client.dataset(run["defaultDatasetId"]).iterate_items():print(product["name"], product["price"], product["currency"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/boulanger-com-scraper').call({ mode: 'search', searchTerm: 'aspirateur robot' });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How far pagination goes
With Max pages per search left empty, a search or listing walk continues until it has covered the result total boulanger.com itself states for that query, counted by page number against the site's own fixed 40-slot result grid. A page is not treated as the end just because it returned fewer than 40 products: the site seeds sponsored tiles into that grid, so an ordinary page in the middle of a large search can come back short. Only a walk that reached the site's own stated total, or hit a genuinely empty page, counts as a complete scan, which is also the condition incremental mode requires before it will mark anything EXPIRED. A stop from the filter rule below, a repeated page, or a page that failed to load is reported in the run log; a stop from Max pages or Max products is not logged separately, since it is simply the cap you set being reached.
How filtering is bounded
Minimum/maximum price, any brand beyond the first, and discounted-items-only have no equivalent on boulanger.com's own search request (only the first requested brand is a real search facet), so they are checked after each result page is fetched rather than sent as a query parameter. A product with no brand at all still passes a brand filter, since there is nothing to check it against. To stop a very selective combination from paging through an entire search or category looking for survivors, a search stops after 5 consecutive result pages that contained new (not yet seen) products, none of which matched your filters. Pages with nothing new on them at all, for example the early pages of a resumed run being re-walked to confirm nothing changed, never count toward this limit.
The run log line "Stopping this search after page N" means the run gave up on that 5-page rule, more matches may exist further down, so narrow the search or widen the filters to see more.
Resume and recurring updates
- Resume from a previous run continues one specific interrupted crawl. Paste a previous run ID or dataset ID and this run skips every product that run already collected, picking up where it left off.
- Incremental mode is for running the same search or URL set again and again (daily, weekly, on a schedule) and getting only what changed. Every product is classified
NEW(first time seen),UPDATED(a comparable field changed, seechangedFields), orUNCHANGED(tracked but not returned unless Emit unchanged is on).EXPIREDis only produced once a run has fully scanned every tracked search/URL and Emit expired is on.REAPPEAREDis produced only for a product that a prior run already markedEXPIREDthrough that same mechanism and a later run finds again, it is never produced on a first run, and never produced at all unless Emit expired has been used in an earlier, complete, non-resumed run. State is kept per mode and search/URL set; in search mode the filters and sort are also part of that key, in URL mode they are not, so two URL-mode runs against the same links share one baseline even with different filters. Use State key to name or deliberately share a monitoring campaign. Incremental mode defaults to off, so a normal run's output is unchanged until you opt in. Combining it with Resume bootstraps a new monitoring campaign from that resumed crawl's results; if a baseline already exists for that state key, the run fails rather than silently mixing the two.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape, the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each product, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify, Settings, Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. If the picker is empty, you have not authorized a connector yet.
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (keyword and/or category) or url (paste product, search-result or specials links), continuing pagination automatically. |
searchTerm | string | (none; prefill "aspirateur robot") | Free-text keyword, uses boulanger.com's own product search. Search mode only. |
category | string | (none) | A category/department name, combined with Search keyword above into boulanger.com's own free-text search. Search mode only. |
sortBy | string | RELEVANCE | RELEVANCE, PRICE_ASC, PRICE_DESC, or TOP_RATED, boulanger.com's own sort order, reordering the full server-side result set. Search mode only. |
urls | array | (none; prefill one sample URL) | Product, search-result or specials-listing links to scrape. Pagination continues forward automatically. URL mode only. |
brands | array | (none) | Exact brand names to keep. In search mode, the first is narrowed server-side through the site's own search facet and the rest checked client-side; in URL mode, every brand is checked client-side. Applies in both modes. |
minPrice | number | (none) | Only return products priced at or above this amount, in euros. Checked after each page is fetched, not sent as a search parameter. Applies in both modes. |
maxPrice | number | (none) | Only return products priced at or below this amount, in euros. Checked after each page is fetched, not sent as a search parameter. Applies in both modes. |
specialsOnly | boolean | false | Keep only products currently showing a genuine strike-through discount against the site's own reference price. Applies in both modes. |
fetchDetails | boolean | false | Add full description, EAN/GTIN, breadcrumb path, flattened spec sheet, image gallery and the colour/capacity/size variant matrix from the product page. |
fetchReviews | boolean | true | Fetch the product's own customer reviews and rating breakdown. On by default, so most runs also fetch the product page and incur the detail & review enrichment charge per product, see Plan Requirement. |
maxReviewsPerProduct | integer | 10 | Cap on written reviews fetched per product when Fetch reviews is on. 0 means no cap. Does not disable the fetch or its charge, only trims how many reviews are returned. |
maxPages | integer | (none; empty = no page cap) | Stop after this many result pages per search/URL entry, bounded by Max products and the guards described above. |
maxItems | integer | 20 | Hard cap on total products returned across every search/URL entry. 0 = unlimited. |
resumeFromRunId | string | (none) | Previous run ID or dataset ID to continue one interrupted crawl without re-returning or re-charging products it already collected. |
incrementalMode | boolean | false | Recurring monitoring of the same search/URL set: returns only new and updated products against a remembered baseline by default (reappeared products need Emit expired too, plus a prior complete scan). |
stateKey | string | (none) | Name a monitoring campaign, or deliberately share state across differently-configured runs. Derived automatically when left empty. |
emitUnchanged | boolean | false | Also return (and bill) unchanged products. Incremental mode only. |
emitExpired | boolean | false | Also return (and bill) expired products, only once a run fully scans every tracked search/URL. Incremental mode only. |
proxy | object | {"useApifyProxy": true} | Connection settings. |
mcpConnectors | array | (none) | Optional MCP connectors to export results into (Notion, Linear, Airtable, Apify). |
notionParentPageUrl | string | (none) | Notion connector only: page under which item pages are created. |
maxNotifyListings | integer | 50 | Cap on items exported to each connector per run. Does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live product.
{"productId": "8823410","sku": "VLX-X200-BLK","ean": "9999999999991","name": "Velunox AeroClean X200 Robot Vacuum","brand": "Velunox","category": "Aspirateurs robots","breadcrumbPath": ["Accueil", "Electromenager", "Aspirateurs", "Aspirateurs robots"],"url": "https://www.boulanger.com/ref/8823410","price": 225.00,"priceExclTax": null,"currency": "EUR","originalPrice": 300.00,"discountAmount": 75.00,"discountPercent": 25.0,"isOnSpecial": true,"promoLabel": "Ancien prix","onlineAvailable": true,"condition": "new","sellerName": null,"unitPrice": "11.25 EUR/kg","storePickupAvailable": true,"isBundle": false,"image": "https://static.example.com/000000000.jpg","images": ["https://static.example.com/000000000.jpg"],"description": "Sample product description as shown on the site.","characteristics": { "Suction power": "10 000 Pa", "Battery life": "45 min", "Made in": "Sample Country" },"variants": [{ "productId": "8823411", "axis": "couleur", "name": "Sample Colour", "url": "https://www.boulanger.com/ref/8823411", "price": 225.00, "available": true }],"rating": 4.6,"reviewCount": 82,"reviews": {"averageRating": 4.6,"ratingCount": 82,"totalReviewCount": 82,"ratingBreakdown": { "1": 0, "2": 0, "3": 0, "4": 1, "5": 2 },"items": [{ "rating": 5, "title": "Sample title", "body": "Sample review text.", "author": "Jane D.", "date": "2026-01-01", "verifiedPurchase": null },{ "rating": 4, "title": "Sample title two", "body": "Another sample review text.", "author": "A. M.", "date": "2025-12-20", "verifiedPurchase": null },{ "rating": 5, "title": "Sample title three", "body": "A third sample review text.", "author": "L. B.", "date": "2025-12-05", "verifiedPurchase": null }]}}
Plan Requirement
The default proxy setting works out of the box, and the run automatically retries with a different connection when one is refused. For large or frequent runs, or when you need results as they appear for a specific country, the residential proxy group gives more headroom; pick it under Connection.
FAQ
How much does it cost?
Three things can be charged: a small run-start fee, a per-product charge for every product returned in the dataset, and a detail & review enrichment charge for every product returned in the dataset whose page was actually fetched for full detail and/or reviews. Fetch reviews is on by default, so on a default run almost every returned product also fetches its own page and incurs the enrichment charge, even for a product that turns out to have zero reviews, the charge is for the fetch and enrichment attempt, not for finding reviews. Turn off both Fetch full product detail and Fetch reviews to pay only the base per-product price. The Pricing tab shows the current rates; use Max products to cap the cost of any run.
Is it legal to scrape Boulanger?
This actor collects only publicly available product data. You are responsible for how you use it: follow Boulanger's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product descriptions, images and customer reviews may be subject to third-party rights.
Can I get only new or changed products on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated products (plus reappeared ones once Emit expired has completed a full, uncapped scan), and unchanged ones are not returned or billed unless you turn on Emit unchanged.
Why did I get an empty dataset instead of an error?
If every connection attempt is refused, the run logs a warning and finishes with whatever it already collected, which can be an empty dataset, rather than throwing an error, so "no matches for this search" is never confused with a crash. Two situations do stop the run outright with a clear failure message instead: an invalid Resume from a previous run id, and combining Incremental mode with Resume when a baseline already exists for that state key. In every other case, run it again in a few minutes.
Why did a search return fewer products than expected?
A very selective combination of brand, price range or discounted-items-only can discard every product on several pages in a row. To avoid paging through an entire catalogue looking for survivors, the run gives up on that search after 5 consecutive pages whose new products all failed your filters, and says so in the log. Narrow the search or category, or widen the filters, to see more. Max pages and Max products can also cap a run before it reaches the natural end of the results.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
๐ Want more electronics data?
Pair this actor with these related scrapers from the same team:
| ๐ Fnac Scraper Scrape Fnac (fnac.com) products: current price plus strike-through discount, colour/model... | ๐ Darty Scraper Scrape Darty (darty.com) products: current price plus strike-through reference price and... |
| ๐ PcComponentes Scraper Scrape PcComponentes (pccomponentes.com) products: current price plus strike-through... | ๐ MediaMarkt Germany Scraper Scrape MediaMarkt.de products by keyword or URL. Extract current and original prices... |
| ๐ Thegioididong Scraper Scrape thegioididong.com products with full specifications, current & original price... | ๐ Bic Camera Scraper Scrape Bic Camera (biccamera.com) products: JPY price, list price and discount, Bic Point... |
๐ Browse all abotapi scrapers
๐ฌ Support & custom scrapers
- ๐ Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- ๐ ๏ธ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
- โญ Enjoying it? A quick review on the actor page helps other users find it.