Lidl.es Products, Weekly Offers, Prices & Reviews Scraper avatar

Lidl.es Products, Weekly Offers, Prices & Reviews Scraper

Pricing

from $1.00 / 1,000 product results

Go to Apify Store
Lidl.es Products, Weekly Offers, Prices & Reviews Scraper

Lidl.es Products, Weekly Offers, Prices & Reviews Scraper

Scrape Lidl.es grocery and non-food products across weekly offers, tools, home, garden, kitchen, fashion, kids, sport and more. Search by keyword, department or URL. Extract prices, was-prices, discounts, package formats, images, ratings and full shopper reviews.

Pricing

from $1.00 / 1,000 product results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

7

Total users

0

Monthly active users

5 days ago

Last modified

Security

Limited permissions

Share

Lidl.es Scraper: Prices, Weekly Offers & Shopper Reviews

Lidl.es Scraper turns Lidl Spain's storefront into structured product data, spanning both the grocery/supermarket weekly-offer range and the "bazaar" (non-food) catalogue: tools, home & garden, kitchen, fashion, baby & kids, and sport & leisure. Search by keyword and department with brand, price, rating and weekly-offer filters, or paste product, search, or department links directly. Every record carries the current price, a genuine strike-through was-price and discount % only when a product is genuinely on offer, the package format, images, and the site's own shopper rating; turn on review fetching for as many shopper reviews as Max reviews per product allows (default 20, up to 100; highest-rated first) plus the full rating summary and histogram. Export to JSON, CSV or Excel, or pull results through the API.

Why This Scraper?

  • Covers both catalogues. Lidl.es sells grocery weekly offers (fresh produce, pantry, drinks) and a much larger bazaar/non-food range (tools, home, garden, fashion, toys, sport) through the same storefront; this scraper reaches both from one input.
  • Was-price captured only when it's real. This scraper reads the site's own strike-through price object per item and only ever sets a was-price, discount amount and discount % when the site's own prior price is genuinely populated and higher than the current price. Full-price items get null, never a fabricated markdown.
  • Real shopper reviews from the site itself. Ratings and reviews come from Lidl's own on-site review feed (average, histogram, the Max reviews per product highest-rated reviews (default 20, up to 100) with author and votes), included on request or automatically for a pasted product URL.
  • Package format plus a derived unit price. The package size/format Lidl itself displays (e.g. "750g", or a loose/bulk format) is included whenever Lidl shows it; a EUR/kg or EUR/L unit price is derived only when the package is an unambiguous single weight or volume, never guessed for a bulk or multi-pack item.
  • Two ways in. Keyword and department browsing with brand, price, rating and weekly-offer filters and sort, or paste any product, search/specials, or department link.
  • Optional export to your apps. Send results into Notion, Linear, Airtable, or any Apify MCP connector alongside the dataset.

Use Cases

  • Price and discount tracking: monitor Lidl's weekly-offer feed for genuine markdowns (was-price, discount %) across any department, on a recurring schedule.
  • Bazaar and non-food sourcing: pull the tools, home & garden, kitchen, fashion or baby & kids ranges by department for comparison shopping or catalog building.
  • Grocery price monitoring: track the Alimentacion (grocery) department's current prices and weekly specials for a price-comparison tool.
  • Brand and assortment research: collect every product under one brand across the whole catalogue to track SKU count, pricing and availability.
  • Shopper sentiment analysis: pull the site's rating summary, histogram and top reviews for specific products to track shopper sentiment over time.

Data You Get

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

FieldExample
productId / title"900000001", "Taladro percutor inalambrico 20V (ejemplo)"
brand"SAMPLEBRAND"
categoryPath / category["Bricolaje y jardin", "Herramientas", "Herramientas electricas"], "Herramientas electricas"
productUrl"https://www.lidl.es/p/producto-ejemplo/p900000001"
price / currency39.99, "EUR"
wasPrice / discountAmount / discountPercent49.99, 10.0, 20.0 (only when genuinely on offer)
isOnSpecial / promoLabeltrue, "Megadescuento"
packageFormat"1 ud." (the site's own package/format text)
unitPrice / unitOfMeasurenull, null (only set for an unambiguous single weight/volume like "750g")
hasVat / onlineAvailable / inStoreOnly / stockAvailabilitytrue, true, false, "En stock"
images / internalArticleNumbersfull-resolution image URL list, ["555123"]
description / badgesshort plain-text product description as shown on the site, ["Top rated"]
averageRating / reviewCount / recommendedYes / recommendedNo4.6, 823, 780, 15
name / erpNumber / itemNumber / productKey"Taladro percutor inalambrico 20V (ejemplo)", "900000001", "555123", "ES:900000001"
country / source / scrapedAt / categoryLvl0 / labels"ES", "lidl.es", scan timestamp (UTC), top-level department, the site's badge texts
priceEur / priceNormal / comparePrice / compareUnitsame as price; pre-markdown price when on offer, else price; same as unitPrice / unitOfMeasure
packaging / unitSize / unitMeasure"750g" as shown, 750.0, "g" (size and unit only for a plain single weight or volume)
availableFrom / availableUntiloffer window (UTC) when Lidl publishes one, else null
isOnOffer / discountText / inStocktrue, "Megadescuento", true (orderable online)
imageUrl / portalUrlmain image, product page link
reviewsempty shape by default; full feed only with fetchDetails, or automatically for a pasted product URL

reviews always carries the same six keys: averageRating, totalReviewCount, recommendedYes, recommendedNo, starHistogram and items (each with stars, title, text, author, recommended, votesUp, votesDown). Without enrichment it is averageRating: null, totalReviewCount: 0, items: []. The extra fields repeat or reshape data already on the card, are not part of incremental change detection (so they never cause an UPDATED row by themselves), and the actor covers the Spanish store only. Package price (price) comes straight from Lidl's own product data; unitPrice/unitOfMeasure are never derived for a loose/bulk item ("A granel") or a multi-pack, where dividing by the printed pack size would misstate the true per-unit price.

How to Use

  1. Pick a mode: search (keyword + department browse with filters) or url (paste product, search/specials, or department links).
  2. In search mode, set your keyword and/or department, then narrow with brand, price, rating or weekly-offer filters and pick a sort order.
  3. Turn on Fetch shopper reviews if you want up to Max reviews per product shopper reviews (default 20, up to 100) plus the rating summary on every returned product, and set Max products total / Max search pages to control run size and cost.
  4. Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.

Keyword + department search (default mode):

{
"mode": "search",
"searchTerm": "taladro",
"category": "bricolaje-jardin",
"maxItems": 20
}

Weekly offers only, biggest discount first:

{
"mode": "search",
"specialsOnly": true,
"sortBy": "BIGGEST_DISCOUNT",
"maxItems": 50
}

One brand within a department, with the full shopper review feed:

{
"mode": "search",
"category": "bricolaje-jardin",
"brand": "PARKSIDE",
"fetchDetails": true,
"maxItems": 20
}

Paste product, search/specials, or department links directly:

{
"mode": "url",
"urls": [
"https://www.lidl.es/p/producto-ejemplo/p900000001",
"https://www.lidl.es/c/bricolaje-y-jardin/s99999999",
"https://www.lidl.es/q/query/bateria"
],
"maxItems": 50
}

Leaving urls untouched in URL mode now scrapes one example of each distinct link target (the field's default is that sample list) instead of nothing. The alternate search form returns the same products as the search link, so it is not in the default. Replace it with your own links to scrape only those.

Link typeExample shape
Product pagelidl.es/p/<slug>/p<id>, also the short or slug-less lidl.es/p/p<id>, the bare lidl.es host, with or without tracking parameters
Keyword searchlidl.es/q/query/<term> or lidl.es/q/search?q=<term>
Search with filterslidl.es/q/query/<term>?category=<department name>&brand=<brand>&offset=<n>; every filter (and the start offset) is taken from the link and wins over the run's filter fields
Specialslidl.es/q/query/descuentos?discountFlag=1
Department pagelidl.es/h/<slug>/h<id>, optionally ?offset=48
Department hublidl.es/c/<slug>/s<id> (the site may redirect a hub to a page with no products; that link then logs a warning and is skipped)
Campaign pagelidl.es/c/<slug>/a<id>

A search link whose category or brand matches nothing logs a clear warning instead of returning silently. Category must be the exact department name.

A pasted product URL always gets up to Max reviews per product shopper reviews (default 20, up to 100) plus the rating summary, and is still billed one detail-enrichment per product, regardless of the Fetch shopper reviews toggle; the user explicitly asked for that one product.

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/lidl-es-scraper").call(run_input={"mode": "search", "searchTerm": "taladro", "maxItems": 20})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
print(product["title"], product["price"], product["currency"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/lidl-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 maxItems and maxPages interact

Search mode pages through results in batches, stopping once either Max products total or Max search pages is reached, whichever comes first. Leave Max search pages empty for no page limit (bounded only by Max products total). URL mode gives each pasted URL a fair share of what is left of Max products total; a URL that needs fewer rows (for example a single product link) passes its unused share on to the later URLs, and every URL gets at least one row.

Output views

The dataset has four views in the Console: Products (core price, offer and rating columns), Reviews (nested) (one row per product with its rating summary and review list nested, when reviews were fetched), Changes (incremental) (change type, changed fields, first/last seen, previous price) and Details & availability (package format, offer window, stock and extra attributes). All views read the same records.

Send results into your apps (MCP connectors)

Optionally pipe results into the apps you already use through Model Context Protocol (MCP) connectors. Authorize a connector once under Apify, Settings, Integrations, then select it in the mcpConnectors field. Each connector receives a condensed, human-readable summary per product (title plus key fields), while the complete record always stays in the Apify dataset. For Notion, set notionParentPageUrl to the page the item pages should be created under, and use maxNotifyListings to cap how many items are exported per connector per run. Supported connectors: Notion, Linear, Airtable, and Apify. Leave the field empty to skip; it never changes the dataset output.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch browses by keyword/department filters; url scrapes pasted product, search/specials, or department links.
searchTermstringno default (prefill: bateria)Free-text keyword against Lidl's own search index (search mode only). Leave empty with a department set to browse the whole department.
categorystring"" (Any department)One of Lidl's real top-level departments, spanning both the bazaar/non-food and grocery ranges (search mode only).
brandstringno defaultExact brand name to keep, as Lidl shows it, e.g. PARKSIDE (search mode only).
specialsOnlybooleanfalseKeep only products on a genuine current weekly offer (search mode only).
inStockOnlybooleanfalseDrop products that cannot be ordered online right now; Max products counts only the rows kept.
strictMatchbooleanfalseSearch mode: keep a product only when every word of the keyword appears in its title, brand or category.
minPricenumberno defaultMinimum price in EUR to keep (search mode only).
maxPricenumberno defaultMaximum price in EUR to keep (search mode only).
minRatingnumberno defaultMinimum shopper rating (1-5) to keep (search mode only).
sortBystringRELEVANCERELEVANCE, PRICE_ASC, PRICE_DESC, NEWEST, TOP_RATED, BESTSELLERS, or BIGGEST_DISCOUNT (search mode only).
urlsarrayone sample link per supported link typeProduct, search/specials, or department listing URLs to scrape (url mode only); filter fields above are ignored in this mode.
maxReviewsPerProductinteger20Shopper reviews returned per product when reviews are fetched (1 to 100, highest-rated first). Does not change the per-product review charge.
fetchDetailsbooleanfalseFetch up to maxReviewsPerProduct (default 20) shopper reviews plus the rating summary and star histogram for each product. Always on, regardless of this toggle, for a pasted product URL.
maxPagesintegerno default (empty = unlimited)Stop after fetching this many search result pages.
maxItemsinteger20Hard cap on total products returned across the run (up to 1,000,000; 0 is read as that maximum).
resumeFromRunIdstringemptyID of an earlier run (or dataset) of this actor. Products already in it are skipped and not charged, so the run returns only new products. A resumed run never marks products as expired.
proxyobject{"useApifyProxy": true}Apify Proxy configuration used to route requests. The default works out of the box.
incrementalModebooleanfalseRecurring monitoring. The first run returns every match as NEW; later runs return only NEW, UPDATED and REAPPEARED products, each with changeType, changedFields, firstSeenAt, lastSeenAt (and previousPrice on a price move). Compared: price, was price, discount, offer flag, online availability, stock status, title, brand, category, package format, description, badges and link. Never compared (kept in the row): shopper rating, review count, review feed, image list. Max products counts returned rows only, so a recurring run walks the whole search.
stateKeystringno defaultNames a monitoring campaign so its saved state stays stable. Leave empty to derive it from your search, URLs and filters.
emitUnchangedbooleanfalseAlso return products with no change, marked UNCHANGED. Each returned row is billed like any other product.
emitExpiredbooleanfalseAlso return products no longer listed, marked EXPIRED, only after a complete scan (never after a Max products / Max search pages stop, a pasted department listing page, or a state key reused with different filters). A listing drop and a delisting look the same: read onlineAvailable and stockAvailability for availability.
changeScopestringallpriceAndStock returns an UPDATED row only when price, was price, discount, offer flag, online availability or stock status moves. Changing it without a stateKey starts a new automatic baseline.
compactUpdatesbooleanfalseUPDATED and EXPIRED rows are short (id, title, link, price, availability, priceChanges old/new). NEW rows stay complete. Shopper reviews are not fetched or billed for compact rows.
expireAfterMissedScansinteger1With emitExpired: expire a product only after it was missing from this many complete scans in a row.
ignoreFieldsForChangesarrayno defaultIncremental mode only: extra field names (or dotted paths) that never make a product UPDATED.
mcpConnectorsarrayno defaultOptional MCP connectors to export results into (Notion, Linear, Airtable, Apify).
notionParentPageUrlstringno defaultNotion connector only: page under which item pages are created.
maxNotifyListingsinteger50Cap 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": "900000001",
"title": "Taladro percutor inalambrico 20V (ejemplo)",
"brand": "SAMPLEBRAND",
"categoryPath": ["Bricolaje y jardin", "Herramientas", "Herramientas electricas"],
"category": "Herramientas electricas",
"productUrl": "https://www.lidl.es/p/producto-ejemplo/p900000001",
"price": 39.99,
"currency": "EUR",
"wasPrice": 49.99,
"discountAmount": 10.0,
"discountPercent": 20.0,
"isOnSpecial": true,
"promoLabel": "Megadescuento",
"packageFormat": "1 ud.",
"hasVat": true,
"unitPrice": null,
"unitOfMeasure": null,
"onlineAvailable": true,
"inStoreOnly": false,
"stockAvailability": "En stock",
"images": ["https://www.lidl.es/assets/sample-image.jpg"],
"internalArticleNumbers": ["555123"],
"description": "Descripcion corta de ejemplo del producto, tal como aparece en el sitio.",
"badges": ["Top rated"],
"averageRating": 4.6,
"reviewCount": 823,
"recommendedYes": 780,
"recommendedNo": 15,
"name": "Taladro percutor inalambrico 20V (ejemplo)",
"erpNumber": "900000001",
"itemNumber": "555123",
"productKey": "ES:900000001",
"country": "ES",
"categoryLvl0": "Bricolaje y jardin",
"priceEur": 39.99,
"priceNormal": 49.99,
"packaging": "1 ud.",
"isOnOffer": true,
"discountText": "Megadescuento",
"inStock": true,
"source": "lidl.es",
"scrapedAt": "2026-01-01T00:00:00Z",
"reviews": {
"averageRating": 4.6,
"totalReviewCount": 823,
"recommendedYes": 780,
"recommendedNo": 15,
"starHistogram": { "1": 8, "2": 10, "3": 30, "4": 150, "5": 625 },
"items": [
{ "stars": 5, "title": "Buena relacion calidad-precio", "text": "Texto de resena de ejemplo.", "author": "Comprador de ejemplo", "recommended": true, "votesUp": 4, "votesDown": 0 }
]
}
}

Plan Requirement

The default Apify Proxy setting (datacenter) works for this site: it was measured on product, search, specials, department and campaign pages and returned the same results as the residential group, so no special plan or proxy group is needed. Residential is optional and only adds headroom for very large or very frequent runs. If your Apify plan does not allow proxy access at all, or a run cannot load any page, the run ends as failed with a plain message telling you so (see the FAQ). The Pricing tab shows the current rates for your plan.

FAQ

How much does it cost?

Billing is pay per event, and the Pricing tab lists the exact rates for your plan. Three events exist: a one-time charge when the run starts; one Product result event per product returned in the dataset; and one detail-enrichment event per product whose full shopper review feed was fetched and delivered (once per product, whatever the review count or the maxReviewsPerProduct value; via Fetch shopper reviews, or automatically for a pasted product URL). A failed review fetch, a compact incremental row and a suppressed unchanged row are not charged for enrichment. The enrichment event is charged right after each enriched product is delivered, so an interrupted run is billed only for what it returned. Use Max products total to cap the cost of any run.

This actor collects only publicly available product data (prices, offers, descriptions, ratings and reviews) as shown on Lidl.es. You are responsible for how you use it: follow Lidl's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product images and review text may be subject to third-party rights.

Can I schedule it to catch new weekly offers?

Yes, schedule the actor from the Schedules tab, e.g. with specialsOnly: true and a department set. Turn on incrementalMode to receive only what changed since the previous scheduled run (new products, price or availability moves); without it every run returns the current matching products in full. Billing: with incremental mode on, only the rows returned are billed (UNCHANGED rows only if you ask for them), and shopper reviews are fetched only for returned, non-compact rows.

Why are wasPrice and unitPrice sometimes null?

Both are reported only when genuinely applicable. wasPrice/discountAmount/discountPercent/isOnSpecial are set only when Lidl's own strike-through price field is genuinely populated and higher than the current price; most full-price items simply carry no was-price. unitPrice/unitOfMeasure are derived only when the package format is an unambiguous single weight or volume (e.g. "750g"); a loose/bulk item or a multi-pack always gets null rather than a guessed figure.

What happens when a run cannot load Lidl pages?

A run that could not load a single page does not finish as an empty success: it ends as failed with a plain message and nothing is billed for products. The messages are: "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" (account without proxy access, or invalid custom proxy URLs); "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 Lidl pages" (you chose residential on a plan without it); and "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." When pages loaded but your filters matched nothing, the run succeeds with the status "No products matched the given filters." and the log says "No products matched. Nothing was pushed for this run." A partial failure mid-run keeps the products already collected. If the chosen connection is unavailable the run continues on a backup connection and logs that it did so.

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:

🥦 Mercadona Scraper
Scrape Mercadona products by delivery-area postal code. Search by keyword or category, or...
🥦 El Corte Inglés Scraper
Scrape El Corte Inglés elcorteingles.es products across fashion, electronics, home...
🥦 Carrefour Spain Scraper
Scrape Carrefour Spain (carrefour.es) products. Search by keyword, browse a category, or...
🥦 Auchan France Scraper
Scrape Auchan.fr products: grocery, drinks, household and general merchandise. Real price...
🥦 FoodHero Scraper
Scrape FoodHero surplus grocery deals across Canada by area, store or offer ID. Extract...
🥦 ResQ Club Scraper
Scrape ResQ Club surplus food offers in Finland, Sweden and Estonia: name, price, 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.