LeroyMerlin.es Scraper: Products, Prices, Sellers & Reviews
Pricing
from $1.00 / 1,000 product results
LeroyMerlin.es Scraper: Products, Prices, Sellers & Reviews
Scrape Leroy Merlin Spain (leroymerlin.es) DIY and home-improvement products: price, strike-through original price and discount, seller identity (Leroy Merlin vs marketplace) with every competing offer, stock, rating and individual reviews. Search by keyword/category or paste product/listing links.
Pricing
from $1.00 / 1,000 product results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
11
Total users
3
Monthly active users
16 days ago
Last modified
Categories
Share
Leroy Merlin Spain Scraper: Prices, Discounts, Seller Offers & Reviews
Leroy Merlin Spain Scraper turns leroymerlin.es into a clean product data feed. Get the current price, the strike-through original price and discount when a product is genuinely on promotion, marketplace seller identity with every competing offer, stock and delivery time, rating, and individual customer reviews for tools, appliances and home-improvement products. Search by keyword, a real site category, or paste any product or listing link 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, structured, not scraped from a badge. When a product is marked down, both the current and original price come back plus the discount amount and percentage. Full-price products carry
null, never a fabricated discount. - Marketplace transparency. Leroy Merlin sells both directly and through third-party sellers on the same product page. Every record identifies the seller (Leroy Merlin vs marketplace) and, with detail on, lists every competing offer for that product, price, stock and delivery time per seller.
- Reviews straight from the product page. Overall rating, review count, and individual customer reviews (author, date, rating, body) come from the page itself, not a third-party review vendor.
- Two ways in. Keyword or category search with the site's own price, rating, promotion and seller filters and sort, or paste any product or listing link and let pagination continue automatically.
- Filters that actually narrow, not just trim afterward. Price, rating, promotion and seller filters are checked while pages are walked, so a small item cap still finds enough matching products instead of stopping on an unlucky first page.
- A sort you can trust. Price sort is re-applied after detail enrichment on the exact price that ships, so within each search or pasted listing link, row order and price values never disagree.
- Optional export to your apps. Send results into Notion, Linear, Airtable, or any Apify MCP connector alongside the dataset.
Use Cases
- Price and promotion tracking: watch was-price, discount percentage and stock across a keyword or category to catch sales as they go live.
- Competitive repricing: compare Leroy Merlin's own price against every third-party marketplace offer on the same product page.
- Marketplace share research: track seller composition and total offer count to see how many sellers compete for a given product line.
- Reputation research: pull rating history and individual review text for products you are sourcing, reviewing or comparing.
- Catalog audits: walk a full category to check assortment, stock status and delivery promises.
- Deal-alert bots: filter to on-promotion products only and feed the results into your own alerting tool.
Data You Get
Sample shape: values below are illustrative placeholders, not from a live product.
| Field | Example |
|---|---|
productId / sku | "123456" |
name | "Sample Cordless Drill 18V" |
brand | "SAMPLE BRAND" |
category / categoryPath | "Cordless drills" / ["Tools", "Power tools", "Drilling & screwing", "Drills", "Cordless drills"] |
url | "https://www.leroymerlin.es/productos/sample-cordless-drill-18v-123456.html" |
price / priceExclTax / currency | 99.99 / 82.64 / "EUR" |
originalPrice / discountAmount / discountPercent | 129.99 / 30.0 / 23.1 |
isOnSpecial | true |
rating | 4.7 |
sellerId / sellerName / sellerType | "002" / "Sample Retailer" / "1P" |
totalOfferCount / sellersComposition | 12 / "1P_3P" |
offerType | "NEW" |
sponsored | false |
ean | "4000000000000" |
description | full product description text |
image / numberOfImages | "https://media.example.com/sample.jpg" / 5 |
stock / stockStatus / deliveryTime | 19 / "ONSITE" / "1 OPENING_DAY" |
specs | {"Tensión (en V)": "4", "Batería incluida": "Sí", "Marca del producto": "BOSCH"} |
otherOffers[] | [{"sellerName": "Sample Marketplace Seller", "sellerType": "3P", "price": 105.40, "stock": 3, "deliveryTime": "3 OPENING_DAY"}] |
numberOfReviews / reviewCount | 275 / 275 |
imageUrl / inStock / scrapedAt | same image as image / true when stock is above 0 / ISO-8601 UTC timestamp of the scrape |
reviews.averageRating / reviews.totalReviewCount | 4.7 / 275 |
reviews.items[] | [{"rating": 5, "body": "Sample review text.", "author": "Sample Customer", "date": "2026-07-15"}] |
searchMode | "search" (also "category" or "url") |
specs is the product page's technical-attribute table as attribute name to text value (units are part of the name or the value, exactly as the site shows them); it is returned when Fetch product detail is on and omitted when the page has no table. otherOffers lists every competing marketplace offer visible on the product page at fetch time, price, stock and delivery per seller; a product sold exclusively by Leroy Merlin with no marketplace competition simply omits the field rather than returning an empty placeholder. reviews.items[] holds the product page's own most recent reviews (the page itself only ever surfaces a handful), while reviews.averageRating and reviews.totalReviewCount reflect the product's full review history, not just the reviews included in items[].
How to Use
- Pick a mode:
search(keyword and/or category, with filters and sort) orurl(paste product or listing links). - For search mode, fill in a keyword and/or a category path, and set any price, rating, promotion or seller filters plus a sort order. For url mode, paste one or more product or listing links.
- Leave Fetch product detail and Fetch reviews on for full records, or turn them off for a lighter listing-only run. Set Max products and Max pages to control run size and cost.
- Click Start. Download the dataset as JSON, CSV or Excel, or read it through the API.
Keyword search, first page, with detail and reviews (default):
{"mode": "search","searchTerm": "taladro","maxItems": 20}
Category browse, only products on promotion, sorted by price:
{"mode": "search","category": "herramientas/herramientas-electricas-portatiles/herramientas-electricas-para-taladrar-atornillar/taladros/taladros-de-bateria","onPromotionOnly": true,"sortBy": "price_asc","maxItems": 50,"maxPages": 5}
Only Leroy Merlin's own offers, minimum 4-star rating:
{"mode": "search","searchTerm": "grifo cocina","sellerFilter": "leroymerlin","minRating": 4,"maxItems": 30}
Full detail and reviews for a pasted product link:
{"mode": "url","urls": ["https://www.leroymerlin.es/productos/sample-cordless-drill-18v-123456.html"],"fetchDetails": true,"fetchReviews": true}
Accepted link shapes (url mode). Search results (https://www.leroymerlin.es/search?q=taladro), category listings (https://www.leroymerlin.es/productos/<category-path>/) and product pages (https://www.leroymerlin.es/productos/<slug>-<id>.html). Listing links accept p=<n> for the start page and sort=relevance|price-asc|price-desc. If you leave Links untouched, url mode scrapes one example of each shape (the three defaults); clear the field or paste your own links to change that. In search mode a category given by name is converted to its path, and a warning is logged if nothing matches.
Reviews. Reviews are on by default with a limit of 20 per product (maximum 1000). The product page itself exposes only its most recent handful, so the practical ceiling is lower than the cap.
Dataset views. Besides the default table, the Output tab has an Other offers view (one row per competing marketplace offer) and a Reviews view (one row per review).
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/leroymerlin-es-scraper").call(run_input={"mode": "search", "searchTerm": "taladro", "maxItems": 20})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/leroymerlin-es-scraper').call({ mode: 'search', searchTerm: 'taladro', maxItems: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
How filters narrow the page walk
Price, rating, promotion and seller filters are checked as each result page is read, not only after the whole batch is collected. That means Max products means "N products that actually pass your filters", so a run with onPromotionOnly on and a small maxItems keeps walking pages (up to Max pages) until enough promoted products are found, instead of stopping early on a page where none happened to qualify.
Price sort after enrichment
With Fetch product detail on (the default), each product's price can refresh to the detail page's own value after the listing page was already sorted. The run re-applies your chosen sort on that final price immediately before the dataset is written, so sortBy always matches the price values you actually see in the output.
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 haven't authorized a connector yet.
- For Notion, also set
notionParentPageUrlto the page where item pages should be created.
Leave the field empty to skip. A connector error never fails the run or changes the dataset; it is logged as a warning and the run continues.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search or url. |
searchTerm | string | none (prefill: taladro) | Free-text keyword (search mode). Leave empty and use Category only to browse without a keyword. |
category | string | none | A real leroymerlin.es catalog category path (search mode only). Ignored when searchTerm is set. |
sortBy | string | relevance | relevance, price_asc, or price_desc. Applies to keyword/category search and pasted listing URLs alike. |
minPrice | number | none | Only return products priced at or above this amount, in EUR. |
maxPrice | number | none | Only return products priced at or below this amount, in EUR. |
minRating | number | none | Only return products whose average rating is at least this many stars (0-5). |
onPromotionOnly | boolean | false | Keep only products currently showing the site's own strike-through original price and discount. |
sellerFilter | string | any | any, leroymerlin, or marketplace. |
urls | array | three example links, one per shape (keyword search, category listing, product page) | Product or listing links to scrape (url mode only). If you leave this field untouched, url mode scrapes those three examples; clear the field or paste your own links to change it. Pagination continues forward automatically from any ?p= already present. |
fetchDetails | boolean | true | Fetch EAN, description, image, breadcrumb category path, stock/delivery, and every competing marketplace offer. |
fetchReviews | boolean | true | Fetch the product's own reviews. Shares the same page fetch as fetchDetails. |
maxReviewsPerProduct | integer | 20 | Cap on reviews returned per product (maximum 1000). The site embeds only its most recent ~8 reviews per product page, so that is the practical ceiling; the rating and total count reflect the full history. |
maxPages | integer | none (an empty or zero value behaves as an internal cap of 100 pages per search, category, or URL entry) | Stop after this many result pages per search, category, or pasted listing URL. |
maxItems | integer | 20 | Hard cap on products returned across the whole run. With Incremental changes for scheduled runs on, it caps products scanned: unchanged products that are not returned still count toward it. 0 = unlimited (still bounded by Max pages). |
proxy | object | Apify Proxy, residential, country ES | Connection settings. See Plan Requirement. |
resumeFromRunId | string | none | A previous run ID or dataset ID: products already collected there are skipped and not charged again. |
incrementalMode | boolean | false | Return only new, updated and reappeared products versus the last run of the same search. Adds changeType, changedFields, firstSeenAt, lastSeenAt. |
stateKey | string | auto | Names the monitoring campaign (incremental mode only). Empty derives it from the search, filters and detail settings. |
emitUnchanged | boolean | false | Also return unchanged products, marked UNCHANGED (incremental mode only). |
emitExpired | boolean | false | Also return products no longer found, marked EXPIRED (incremental mode only; only after a full read of the search). |
ignoreFieldsForChanges | array | none | Field names that must not count as a change (incremental mode only). |
mcpConnectors | array | none | Optional: send a summary of each product to apps you authorized under Integrations. |
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 below are illustrative placeholders, not from a live product.
{"productId": "123456","sku": "123456","name": "Sample Cordless Drill 18V","brand": "SAMPLE BRAND","url": "https://www.leroymerlin.es/productos/sample-cordless-drill-18v-123456.html","price": 99.99,"priceExclTax": 82.64,"currency": "EUR","originalPrice": 129.99,"discountAmount": 30.0,"discountPercent": 23.1,"isOnSpecial": true,"rating": 4.7,"sellerId": "002","sellerName": "Sample Retailer","sellerType": "1P","totalOfferCount": 12,"sellersComposition": "1P_3P","offerType": "NEW","sponsored": false,"ean": "4000000000000","description": "Sample product description as shown on the site.","image": "https://media.example.com/sample.jpg","numberOfImages": 5,"categoryPath": ["Tools", "Power tools", "Drilling & screwing", "Drills", "Cordless drills"],"category": "Cordless drills","stock": 19,"stockStatus": "ONSITE","deliveryTime": "1 OPENING_DAY","otherOffers": [{ "sellerName": "Sample Marketplace Seller", "sellerType": "3P", "price": 105.40, "stock": 3, "deliveryTime": "3 OPENING_DAY" }],"numberOfReviews": 275,"reviews": {"averageRating": 4.7,"totalReviewCount": 275,"items": [{ "rating": 5, "body": "Sample review text.", "author": "Sample Customer", "date": "2026-07-15" }]},"searchMode": "search"}
Plan Requirement
leroymerlin.es sits behind a strict bot-protection check that refuses plain datacenter and residential connections alike with a short placeholder page, so a bare Apify Proxy setup is not enough on its own. By default the actor uses Apify Proxy with residential access in Spain, and it retries refused pages on a separate alternate connection lane that is slower, roughly 15 to 75 seconds per page. Expect runs to be slower than on a typical shop and success to depend on that lane being available at the time. A datacenter connection is not supported.
If the Apify residential connection is refused for your account (Apify free plans do not include residential proxies), the run prints a boxed warning once and continues on a backup connection, and logs "Served over the backup connection (the default connection was unavailable)." when that connection serves a page. The backup connection for a free plan is a datacenter connection, which this source usually refuses, so expect little or no data without a paid plan or your own proxy URLs. If you supply your own proxy URLs, or switch the proxy off, no backup connection is used.
A run in which no page could be loaded always ends as failed, never as an empty success, with one of these messages:
- "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid." when every connection was refused for your account.
- "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Leroy Merlin pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again." when the backup connection was reachable but the site never served a page.
- "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later." for any other run where no page loaded.
FAQ
How much does it cost?
This actor uses Apify's pay-per-event pricing. You are charged for each product returned in the dataset, plus a separate, smaller "detail-enrichment" charge: one unit per returned product where detail and/or review enrichment actually ran, whatever the number of reviews returned on it (counted during the run and charged once when the run finishes). Products that incremental mode suppresses as unchanged are neither returned nor charged, plus the standard per-run actor-start charge. The Pricing tab on the actor page shows the current rates. Use Max products and Max pages to cap the size, and cost, of any run.
Is it legal to scrape Leroy Merlin?
This actor collects only publicly available product data, prices, offers, ratings and reviews, shown on leroymerlin.es. You are responsible for how you use it: follow Leroy Merlin's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product names, descriptions and images may carry third-party rights.
Can I schedule it, or get only new or changed products?
Yes. Schedule the actor from the Schedules tab and turn on Incremental changes for scheduled runs (incrementalMode). The first run returns every matching product as NEW; later runs return only NEW, UPDATED and REAPPEARED products, each row carrying changeType, changedFields, firstSeenAt and lastSeenAt. Products that did not change are not returned and not charged, even though their page was read to compare them. Because those unchanged products were still scanned, they use up Max products: with a small cap, a run can return few or no rows when the first products it scans are unchanged. Turn on emitUnchanged or emitExpired only if you also want those rows (each returned row is a normal charged result). EXPIRED rows are produced only after a run read the whole tracked search, never when Max products or Max pages cut it short or when Resume was used. All returned fields are compared except the scrape timestamp, the review texts (a new review still moves the rating and review count) and the live stock and delivery-time counters (stock, deliveryTime, and the same two inside otherOffers); extend that list with ignoreFieldsForChanges. With incremental mode off the output is unchanged: each run returns the current full snapshot.
Why does a product's price sometimes differ from what I saw on the search results page?
When Fetch product detail is on (the default), the product's own detail page is the final source for its price, was-price and discount, and it can legitimately disagree with the listing card's price shown a moment earlier (VAT-inclusive versus exclusive display, or a real price change between the two page loads). The dataset always reflects the detail page's value once detail is fetched, and the run's price sort is re-applied after that refresh within each search or pasted listing link, so sort order and the price you see never disagree there.
Why did my run fail instead of returning an empty dataset?
A page that genuinely does not exist (bad category path, mistyped product slug, delisted listing) comes back as a normal "not found" and is accepted right away. A page that returns the site's placeholder check page instead of content is treated as a refusal, not as an empty result, and is retried with a fresh session, then on the alternate connection lane, then on the backup connection when one is available to your run. If a product's detail page still cannot be read, the product is kept with its listing data only and is not charged for enrichment. If no page at all could be read, the run fails with one of the three messages quoted in the Plan Requirement section rather than ending as an empty success. A run where every request succeeded but nothing matched your keyword, category or filters ends normally with zero items and the status message "No products matched".
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the Pipe results into your apps field to push a summary of each product into Notion, Linear, Airtable or another Apify MCP connector, alongside the full dataset.
🔗 Want more electronics data?
Pair this actor with these related scrapers from the same team:
| 🥦 El Corte Inglés Scraper Scrape El Corte Inglés elcorteingles.es products across fashion, electronics, home... | 🔌 Darty Scraper Scrape Darty (darty.com) products: current price plus strike-through reference price and... |
| 👗 OTTO.de Scraper Scrape OTTO.de products by search or URL. Extract prices, discounts, variants... | 🔌 Fnac Scraper Scrape Fnac (fnac.com) products: current price plus strike-through discount, colour/model... |
| 🛒 MediaMarkt.es Scraper Scrape MediaMarkt Spain (mediamarkt.es) products: current price, strike-through original... | 🛒 Decathlon.es Scrape Decathlon Spain (decathlon.es) sporting goods: current price plus strike-through... |
💬 Support
- 🐞 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 contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.