E.Leclerc Scraper - Local Prices, Stock & Promotions avatar

E.Leclerc Scraper - Local Prices, Stock & Promotions

Pricing

from $1.20 / 1,000 product results

Go to Apify Store
E.Leclerc Scraper - Local Prices, Stock & Promotions

E.Leclerc Scraper - Local Prices, Stock & Promotions

Scrape E.Leclerc France (e.leclerc) grocery and retail products. Search by keyword or category, or paste product and category links. Pick a store by postal code so prices and stock are the real ones for that store. Returns price, unit price, stock, promotions, rating and images.

Pricing

from $1.20 / 1,000 product results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

2

Bookmarked

22

Total users

9

Monthly active users

a day ago

Last modified

Share

E.Leclerc Scraper: Product Prices, Promotions, Stock and Ratings

E.Leclerc Scraper turns the E.Leclerc France grocery and general retail catalogue into a clean product data feed. Search by keyword or category, or paste product, category and search-result links, or bare EAN barcodes. Every product comes back as one flat record with title, description, images, price, unit price, a genuine promotion, stock and, where the storefront carries one, an aggregate rating, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.

Why This Scraper?

  • Two ways to find products. Search by keyword and/or category, then filter and sort the results, or paste product, category and search-result links, or bare EAN barcodes (an EAN lookup, one barcode per line, no link needed), mixed freely in one list.
  • One flat record, one batched call. Title, description, images, price, promotion and stock all come from a single price call per product, always included, never gated behind an extra fetch. Unit price and brand come from search and category result pages, so a pasted product link or bare EAN does not carry them.
  • Genuine promotions only. A "Ticket E.Leclerc" loyalty cashback, paid in full now and credited back later on the loyalty card, is reported separately and never disguised as a discounted price.
  • Reproducible store attribution. Choose a store by postal code or an exact store sign code, and every record is stamped with it, so a run's results stay attributable and repeatable. Price and stock do not change by store, see the FAQ for how that was measured.
  • Built for schedules. Incremental mode returns only new and changed products on recurring runs, and a run fails loudly instead of silently returning nothing when a store cannot be resolved.
  • Resume and checkpoint protection. Continue one interrupted crawl with a pasted run id, and a long run picks up after the last completed keyword, category or link on a platform migration.
  • Send results into the apps you use. Optional Notion, Linear, Airtable or Apify connectors, on top of the dataset, which is never changed by the export step.

Use Cases

  • Grocery price monitoring: track price, promotion and stock changes for a shopping list of products on a recurring schedule.
  • Category and catalogue research: pull a full category listing, for example laundry detergents, with ratings and unit prices for assortment analysis.
  • Promotion tracking: filter for products currently on a genuine promotion, kept separate from loyalty cashback offers.
  • Competitive and market intelligence: compare E.Leclerc's national price and promotion for a list of EANs against other retailers.
  • Product catalogue enrichment: pull title, description, images and a category breadcrumb for a list of EANs to enrich an existing catalogue.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
productId"3700281702286"
ean"3700281702286"
title"ULTRA-HYDRATANT Lait Corps 500 ml"
brand"Topicrem" (search and category results only, absent for a pasted product link or EAN)
description"L'Ultra-Hydratant lait corps Topicrem est une emulsion onctueuse..."
images["https://media.e.leclerc/3700281702286_1"]
categoryPath"Cremes hydratantes > Topicrem > Les Essentiels"
price11.04
unitPriceDisplay"4.16 EUR / L" (search and category results only, absent for a pasted product link or EAN)
wasPrice9.99 (only on a genuine promotion; the key is absent otherwise, never null)
discountAmount1.5 (only on a genuine promotion; the key is absent otherwise, never null)
onPromotiontrue
loyaltyCashbackPercent30.0
loyaltyCashbackLabel"Ticket E.Leclerc avec la carte"
inStocktrue
stock537
rating4.8
reviewCount28
storeSignCode"1375"
storeName"Montparnasse"
storePostalCode"75014"
canonicalUrl"https://www.e.leclerc/fp/ultra-hydratant-lait-corps-500-ml-3700281702286" (search and category results only, absent for a pasted product link or EAN)
searchMode"search"
scrapedAt"2026-09-15T08:00:00Z"

A record can also carry lastUpdateDate (when the catalogue entry was last updated), logisticClassCode (E.Leclerc logistics class, when carried), creationDate and publicationDate (catalogue timestamps), color (only for products that declare a variant colour), currency (always "EUR"), unitPrice and unitPriceUnit as the numeric parts of unitPriceDisplay (same search/category-only scope), discountPercent alongside discountAmount, availabilityStatus and warehouse from the price call, descriptionHtml alongside description, source ("listing" or "product", showing which kind of page the record was built from), promotionStartDate and promotionEndDate on any promotion including a loyalty cashback (the promotion's first and last day), offersTotal (the number of seller offers the storefront lists for the product; 0 when it is not sold here), promotionLabel on a non-loyalty promotion only, and a reviews array on any product that has a rating: up to Max reviews per product reviews, each with reviewId, reviewer, reviewRating, reviewDate, reviewTitle, reviewText, reviewVerifiedBuyer, reviewRecommended, reviewSource, reviewHelpfulVotes, reviewUnhelpfulVotes and reviewReplies (shop answers). The array is empty when reviews are off or the product has none. When Incremental mode is on, every record also carries changeType (NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED), changedFields (populated only for UPDATED), firstSeenAt and lastSeenAt.

How to Use

  1. Choose your store: enter a French postal code, or paste an exact store sign code copied from storeSignCode in a previous run's output. The run picks the nearest Hyper, Super or Express E.Leclerc store to a postal code.
  2. Pick a mode: search (keywords and/or category links, with filters and sorting) or url (paste product, category or search-result links, or bare EAN barcodes).
  3. Fill in the fields for that mode, and set Max products to control run size and cost.
  4. Click Start. Download the dataset as JSON, CSV or Excel, or read it through the API.

Search by keyword:

{
"postalCode": "75014",
"mode": "search",
"queries": ["lait"],
"maxItems": 20
}

Browse a category, filtered to promotions in stock, cheapest first:

{
"postalCode": "75014",
"mode": "search",
"categories": ["https://www.e.leclerc/cat/lessives-marque-repere"],
"onPromotionOnly": true,
"inStockOnly": true,
"sortBy": "price_asc"
}

Paste product links and a bare EAN:

{
"postalCode": "75014",
"mode": "url",
"urls": [
"https://www.e.leclerc/fp/physiolac-lait-infantile-bio-1er-age-800g-3518646124167",
"3700281702286"
]
}

Daily monitoring of the same store and search:

{
"postalCode": "75014",
"mode": "search",
"queries": ["lait"],
"incrementalMode": true
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/leclerc-fr-scraper").call(run_input={"postalCode": "75014", "mode": "search", "queries": ["lait"]})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
print(product["title"], product.get("price"), product.get("onPromotion"))

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/leclerc-fr-scraper').call({ postalCode: '75014', mode: 'search', queries: ['lait'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Store selection and national pricing

Price, promotion and stock returned by this actor are the storefront's national reference offer: measured live against two deliberately distant stores, every one of 30 checked products came back identical, and an invalid store code returns the same response as a valid one. Choosing a store still matters because it stamps every record with storeSignCode, storeName and storePostalCode for a reproducible run, and because it keys the incremental baseline. If both Postal code and Store sign code are filled, Store sign code wins.

Resume and recurring updates

Two different things, pick the one that matches what you are doing.

Resume (resumeFromRunId) continues one specific interrupted or previous large crawl: paste a run id or dataset id and the run skips products already collected there. An automatic checkpoint also protects a long run against a platform migration without any input needed.

Incremental mode (incrementalMode) is for a recurring schedule over the same store and search: the actor remembers the previous run by itself, so no run id is pasted. The first run returns every product as NEW. Later runs return NEW and UPDATED products (changedFields lists what changed). A product is UPDATED when any returned field changed (price, was-price, promotion, stock, title, brand, images, description and so on); these fields are returned but never compared: the scrape timestamp (scrapedAt), the catalogue metadata lastUpdateDate, logisticClassCode, color, creationDate and publicationDate, the seller-offer count offersTotal, and promotionStartDate (a promotion change still shows through promotionEndDate, price and was-price); you can also list any field in ignoreFieldsForChanges (a top-level name such as reviewCount, or a dotted path such as name.key for a key nested inside an object or list). Ignored fields are still returned; they just never trigger UPDATED or appear in changedFields. Unchanged products are suppressed and not billed unless emitUnchanged is on. A product is only classified REAPPEARED if an earlier run had Emit expired products on, completed a full scan of the tracked search, and marked that product EXPIRED, and this run finds it again. Without ever turning Emit expired products on, REAPPEARED is never produced. EXPIRED rows themselves are only added when Emit expired products is on and the run reached the natural end of every tracked search, not when Max products or Max pages capped it, not when a link could not be read, and not on a Resume run. When Max products leaves only a few rows of headroom, at most that many EXPIRED rows are produced per run and the remaining ones are kept for the next run. Set stateKey to name or deliberately share a monitoring campaign; a different store gets its own state automatically unless you set the same stateKey for both.

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.

  1. Authorize a connector once under Apify, Settings, Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. If the picker is empty, you have not authorized a connector yet.
  3. For Notion, also set notionParentPageUrl to the page where items should be created.

Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
postalCodestringnone (prefill: "75014")A French postal code. The run picks the nearest Hyper, Super or Express store to it. One of postalCode or storeSignCode must be set for the run to start.
storeSignCodestringnoneOptional exact-store override. Wins over postalCode when both are set.
modestring"search"search or url.
queriesarraynone (prefill: ["lait"])Search keywords (search mode).
categoriesarraynoneE.Leclerc category page links (search mode).
urlsarray5 distinct examples (a category, a lait search, a chocolat search page 2, a product link, an EAN-only product link); the prefill offers all 9 link shapes, including page, sort and no-www variants that resolve to the same rowsProduct links, bare EANs, category links and search-result links (url mode). A url-mode run with this field left untouched scrapes those 5 examples; clear the field and add your own links to scrape something else.
sortBystring"relevance"relevance, price_asc, price_desc, unit_price_asc, unit_price_desc, or name.
minRatingstring"0"Minimum average rating: 0, 3, 4, or 5.
onPromotionOnlybooleanfalseKeep only products with a genuine reduced price.
inStockOnlybooleanfalseKeep only products currently in stock.
minPriceintegernoneKeep only products priced at or above this amount, in EUR.
maxPriceintegernoneKeep only products priced at or below this amount, in EUR.
maxReviewsPerProductinteger20Customer reviews collected per product that has reviews (each stored in the reviews array as reviewId, reviewer, reviewRating, reviewDate, reviewTitle, reviewText, reviewVerifiedBuyer, reviewRecommended, reviewSource, reviewHelpfulVotes, reviewUnhelpfulVotes, reviewReplies), 10 per page. 0 turns reviews off; the maximum is 1000, which bounds run time and cost.
fetchDetailsbooleantrueFetch each product's page for a human-readable category breadcrumb. Price, stock, promotion and rating are always fetched regardless of this toggle. The product page is also always fetched for a pasted product link or EAN, and whenever Minimum rating is set, even with this off.
maxItemsinteger20Stop after this many products (0 = no limit; maximum 100000).
maxPagesinteger0Result pages walked per keyword, category or link (0 = unlimited).
resumeFromRunIdstringnoneContinue one interrupted or previous run.
incrementalModebooleanfalseReturn only new and changed products on recurring runs of the same store and search.
stateKeystringnoneName or share an incremental-mode state.
emitUnchangedbooleanfalseAlso return (and bill) unchanged products.
emitExpiredbooleanfalseAlso return (and bill) products no longer found, once a run has fully scanned the search.
ignoreFieldsForChangesarray[]Field names (or dotted name.key paths) left out of change detection in incremental mode.
proxyobject{"useApifyProxy": true}Connection settings. A datacenter connection is used by default.
mcpConnectorsarraynoneOptional: send a summary of each product to apps you authorized under Integrations.
notionParentPageUrlstringnoneNotion connector only: page under which item pages are created.
maxNotifyListingsinteger50Cap on items written to each connector per run.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"productId": "3661112223334",
"ean": "3661112223334",
"title": "Lessive liquide 40 lavages",
"brand": "Marque Repere",
"description": "Lessive liquide concentree pour un lavage efficace au quotidien.",
"descriptionHtml": "<p>Lessive liquide concentree pour un lavage efficace au quotidien.</p>",
"images": ["https://media.e.leclerc/3661112223334_1"],
"categoryPath": "Entretien > Lessives > Lessives liquides",
"price": 8.49,
"currency": "EUR",
"unitPrice": 0.21,
"unitPriceUnit": "lavage",
"unitPriceDisplay": "0.21 EUR / lavage",
"wasPrice": 9.99,
"discountAmount": 1.5,
"discountPercent": 15.0,
"onPromotion": true,
"availabilityStatus": "in-stock",
"inStock": true,
"stock": 214,
"rating": 4.3,
"reviewCount": 112,
"reviews": [],
"storeSignCode": "1375",
"storeName": "Montparnasse",
"storePostalCode": "75014",
"canonicalUrl": "https://www.e.leclerc/fp/lessive-liquide-40-lavages-3661112223334",
"searchMode": "search",
"source": "listing",
"scrapedAt": "2026-09-15T08:00:00Z"
}

The Console dataset has four views: Products (overview), Product details (breadcrumb, description, stock and logistics fields), Reviews (one row per review, with the product title and link next to the review... columns) and Changes (incremental mode) (change type, changed fields, first and last seen). Every field is also available through the API and in all export formats.

Plan Requirement

A proxy connection is required. The default proxy setting (a datacenter exit through the Apify proxy) was measured to load E.Leclerc search, category and product pages with real product data and no challenge page, so residential is optional and not needed. Apify free plans do not include any proxy access: on a free plan a run stops with a message saying a paid plan is required, or, when only residential was selected, continues on a backup connection with a warning that some pages may be unavailable. If every connection fails the run ends with "Could not load any results page (the requests failed)" rather than an empty dataset. You can also supply your own proxy URLs. The Pricing tab shows the current per-event rates for this actor: a charge per product returned, plus a detail-enrichment charge for pages fetched and for each 10 reviews delivered.

FAQ

How much does it cost?

You pay per product returned, plus a detail-enrichment charge only for a product that is actually returned in the dataset and whose page was fetched and read. The page is fetched when Fetch product details is on, for every pasted product link or EAN, and whenever Minimum rating is set. The Pricing tab shows the current rates. Reviews add a detail-enrichment charge of one unit per 10 reviews delivered (rounded up across the run), only for reviews inside rows that are actually returned. Use Max products and Max reviews per product to cap the cost of any run.

This actor collects only publicly available product data. You are responsible for how you use it: follow E.Leclerc's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product names, prices and stock are generally facts, but images and description text may be subject to third-party rights.

Why does the price and stock look the same for every store I try?

This is expected, not a bug. The price, promotion and stock this actor returns are the storefront's national reference offer, verified live to be identical across distant stores. Choosing a store still stamps every record with storeSignCode, storeName and storePostalCode, and keeps a separate incremental baseline per store unless you set the same stateKey for both, but it does not change the price or stock values.

Can I get only new or changed products on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental changes for scheduled runs. Each run then returns only new and updated products, and unchanged ones are not billed. A product only comes back as REAPPEARED if an earlier run had Emit expired products on and had already marked it EXPIRED; turning emitExpired on for the first time will not retroactively produce REAPPEARED rows.

Why did my run fail instead of returning an empty dataset?

If the postal code or store sign code you provided cannot be resolved to a real E.Leclerc store, the run stops with a clear message instead of silently returning nothing. Check the code and try again. If the store resolves but no products match your keywords, links or filters, the run finishes normally with an empty dataset and a status message explaining why.

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 grocery data?

Pair this actor with these related scrapers from the same team:

🥦 Auchan France Scraper
Scrape Auchan.fr products: grocery, drinks, household and general merchandise. Real price...
🥦 Carrefour Spain Scraper
Scrape Carrefour Spain (carrefour.es) products. Search by keyword, browse a category, or...
🥦 REWE.de Scraper
Scrape REWE Germany (rewe.de) grocery products: current price, was-price and discount...
🥦 Mercadona Scraper
Scrape Mercadona products by delivery-area postal code. Search by keyword or category, or...
🥦 Instacart Scraper
Scrape Instacart grocery catalogs with per-store prices. Run keywords across several...
🥦 Flashfood Scraper
Scrape Flashfood discounted groceries and stores by location or store. Extract current...

👉 Browse all abotapi scrapers

💬 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.