Mercadona Scraper — Prices, Unit Prices, EANs, Ingredients
Pricing
from $1.00 / 1,000 products
Mercadona Scraper — Prices, Unit Prices, EANs, Ingredients
Mercadona Spain (tienda.mercadona.es) scraper: name, brand, packaging, size, EUR price, unit price, previous price, VAT rate, category path, image, URL; detail rows add EAN barcode, ingredients, allergens, origin, suppliers. Keyword, category, whole catalogue or product ID. Pay per result, no login.
Pricing
from $1.00 / 1,000 products
Rating
0.0
(0)
Developer
architek.earth
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
16 days ago
Last modified
Categories
Security
Limited permissionsShare
Recorded run: 50 products from 1 search term in 13 seconds (2026-10-22, build 0.0.196, run egIxgMZbS7IZcMr5j). A bounded canary sample, not a full-catalogue benchmark.
architek.earth — an independent data studio. Pay-per-result scrapers with recorded runs, published canaries and stable schemas, built for people and AI agents.
Mercadona Spain product prices, unit prices, EAN barcodes, ingredients and allergens from tienda.mercadona.es, by keyword, category, the whole catalogue or product ID.
| Source | Market | From | Standout fields |
|---|---|---|---|
| Mercadona (tienda.mercadona.es) | Spain | $1.00 / 1,000 products | price / referencePrice, ean, ingredients / allergenList |
✅ Why choose this scraper
Mercadona prices and unit prices on every row
price in EUR, referencePrice with referenceUnit (for example 0.83 per "L"), previousPrice, taxPercentage and the full categoryPath come back on search and category rows.
Mercadona EAN barcodes, ingredients and allergens
With includeDetails: true or productUrls, rows add ean, legalName, ingredients, allergens, allergenList, origin, suppliers and storage and usage instructions. Mercadona's x99 "no allergens declared" code is dropped, not reported as an allergen.
Detail price only when detail comes back
A row is charged as product-detail only when it carries at least one detail field such as ean, ingredients or origin; a row Mercadona publishes no detail for stays product.
The whole Mercadona catalogue in one run
categories: ["all"] walks every sub-category: on 2026-10-18 that was 152 sub-categories and 4,269 unique products in 158 requests.
Measured on a schedule
A canary task runs a fixed leche search on the live site every day and records rows, inputs and seconds; the hero line above is its latest green run.
⚠️ Worth knowing up front
- There is no postcode selector.
warehousepicks the assortment (vlc1Valencia by default,mad1,bcn1,alc1,svq1). In a 2026-10-18 check of one sub-category, prices were identical across those five warehouses and the assortment differed (34 to 38 products). An unknown warehouse stops the run withINVALID_INPUTinstead of silently returning Valencia's range. - There is no specials or promotion field.
previousPriceandpriceDecreasedare passed through as Mercadona publishes them; in the 2026-10-18 recon, 25 products carried a previous price whilepriceDecreasedwasfalse. Do not readpreviousPriceas a sale. - No nutrition table and no stock counts are returned.
unavailableFromandunavailableWeekdaysare Mercadona's availability notes, not stock. brandcomes on search rows and detail rows; category listings do not carry it, so setincludeDetails: truefor brand on category runs. Loose produce is priced per piece at an approximate weight (approxSize: true) with the per-kg price inreferencePrice.- Fields Mercadona does not publish are omitted, never
null. A failed detail lookup keeps the row at theproductprice without detail fields. - Mercadona's search returns at most 1,000 results per term;
RUN_SUMMARYadds a warning when a term matches more. Products are de-duplicated byproductIdacross every term, category and URL in a run. - A run stopped by its timeout or your spending limit keeps what it delivered and ends
TIME_LIMITorBUDGET_LIMIT; that is a partial collection. A run moved to another server resumes from saved progress without charging delivered products again. - A category that matches nothing, a missing product and a blocked or failed query each return a free status row (
"recordType": "query",statusNOT_FOUND,BLOCKEDorERROR) that says what happened. Invalid input stops before collection with one free"recordType": "status"row (statusINVALID_INPUT, with amessage), a status message andRUN_SUMMARY. A run that stops at the timeout or your spending limit adds one free"recordType": "status"row (TIME_LIMITorBUDGET_LIMIT).
⚡ Try the example
This actor has no free preview; the example below costs about $0.05.
Open the actor's input page, switch to JSON, paste this and start the run:
{"searchTerms": ["leche"],"maxItemsPerQuery": 50,"warehouse": "vlc1","proxyConfiguration": { "useApifyProxy": true }}
Add "includeDetails": true for EAN, ingredients and allergens, or use "categories": ["all"], "maxItemsPerQuery": 0 for the whole catalogue.
⚙️ Input
| Parameter | Type | Default | Description |
|---|---|---|---|
searchTerms | array | — | Keywords such as leche or aceite de oliva, searched with Mercadona's own shop search. Up to 1,000 results per term. |
categories | array | — | all; a department name (Huevos, leche y mantequilla); a sub-category name (Aceite, vinagre y sal); Top > Sub for names that repeat (Congelados > Marisco); or a sub-category id or tienda.mercadona.es/categories/112 URL. Accents optional. Up to 50 search terms and categories combined. |
productUrls | array | — | Product URLs (tienda.mercadona.es/product/4241/...) or ids (4241). Always include detail fields where published. Up to 500; fetched first. |
maxItemsPerQuery | integer | 100 | Products per search term or category. 0 = everything (search stays capped at 1,000). |
includeDetails | boolean | false | One extra request per product for EAN, ingredients, allergens, origin, suppliers, storage and photos. Rows with detail fields are charged as product-detail. |
warehouse | string | vlc1 | Assortment to read: vlc1, mad1, bcn1, alc1, svq1. Unknown codes are rejected before collection. |
language | select | es | es, en or ca: Mercadona's own translations of names and categories. |
proxyConfiguration | proxy | {"useApifyProxy": true} | Apify datacenter proxy is the tested default. Blocked or rate-limited requests are retried on a fresh IP. |
feedback | string | — | Optional note for the maintainers. It is logged and read by a human, and it never changes output. |
🧱 Stable fields
These top-level fields keep the same name and the same kind of value in every release. Fields are only ever added, never renamed or removed, so an n8n, Make, Zapier or spreadsheet pipeline can bind to them.
| Field | Type | Meaning |
|---|---|---|
productId | string | Mercadona product id; the join key within Mercadona. |
retailer | string | Always "Mercadona". |
name / brand / packaging / size | string | Product name, brand, packaging and size text such as "6 briks · 6 l". Omitted when not published. |
price / currency | number / string | Price of one sellable unit (pack, bottle, piece) and "EUR". |
referencePrice / referenceUnit | number / string | Unit price and its basis (kg, L or unit). |
previousPrice / priceDecreased | number / boolean | Mercadona's previous price and its own flag, as published. Omitted when absent. |
taxPercentage | number | VAT rate, for example 4, 10 or 21. |
approxSize / isNew / requiresAgeCheck | boolean | Sold by approximate weight; new arrival; age-restricted. Present only when true. |
unavailableFrom / unavailableWeekdays | string / array | Mercadona's availability notes, where set. |
category / categoryPath | string | Lowest category and the full path joined by >. |
image / url / warehouse | string | 600 px image, product page, warehouse read. |
source | object | {source: "search" | "category" | "product", searchTerm, category, subCategoryId, categoryUrl, page} as applicable. |
ean | string | Barcode, on detail rows when published. |
recordType | string | "query" on free per-query status rows (with query, status, reason); "status" on free run-level status rows (with status, message); "product" on data rows. |
Detail rows also carry legalName, ingredients, allergens, allergenList, origin, suppliers, storageInstructions, usageInstructions, mandatoryMentions, dangerMentions, productionNote, alcoholByVolume, extraInfo, isBulk and images. Other fields are extras, not part of the contract. To have one pinned, say so in feedback.
📦 Output example
Abridged real row from run egIxgMZbS7IZcMr5j on 2026-10-22; values are a historical snapshot.
{"recordType": "product","retailer": "Mercadona","productId": "10381","name": "Leche semidesnatada Hacendado","brand": "Hacendado","size": "6 briks · 6 l","price": 4.98,"currency": "EUR","referencePrice": 0.83,"referenceUnit": "L","previousPrice": 5.04,"priceDecreased": false,"taxPercentage": 4,"category": "Leche semidesnatada","categoryPath": "Huevos, leche y mantequilla > Leche y bebidas vegetales > Leche semidesnatada","url": "https://tienda.mercadona.es/product/10381/leche-semidesnatada-hacendado-pack-6","warehouse": "vlc1","source": { "source": "search", "searchTerm": "leche", "page": 1 }}
A free status row looks like this:
{"recordType": "query","query": "category:nope","status": "NOT_FOUND","reason": "no Mercadona category matches 'nope' (use a name, 'Top > Sub', an id or 'all')"}
🧠 Advanced usage
Track Mercadona price changes daily
Schedule the same categories, or categories: ["all"] with maxItemsPerQuery: 0, and diff price, referencePrice and previousPrice by productId between datasets. Check RUN_SUMMARY.status is COMPLETE before treating a run as finished.
Scrape the whole Mercadona catalogue
{"categories": ["all"], "maxItemsPerQuery": 0} covers about 4,300 products without details. A spending limit stops it cleanly with BUDGET_LIMIT, charges equal to rows delivered.
Match Mercadona products by EAN barcode
Set includeDetails: true and join ean against other retailers or your own range.
Compare Mercadona assortment by warehouse
Run the same categories with different warehouse values and compare which productIds appear in each dataset.
Audit Mercadona allergens and ingredients
Request details and filter allergenList, or search the ingredients text.
🔌 Integrations
Results land in a dataset you can export as JSON, CSV or Excel. They can also flow to Google Sheets, Make, Zapier or n8n, or to a webhook when a run finishes. The Apify Scheduler runs it on a timetable. Daily on the same categories, or on all, suits price tracking. Copy-paste code in Python, Node, curl and n8n: architek-earth/examples/mercadona-es-scraper.
💸 Pricing
Pay per result. Platform and proxy usage are included. Status rows, failed requests and blocked pages are free.
| Event | Price | What it covers |
|---|---|---|
product | $1.00 / 1,000 products | One delivered search or category row, including a row whose detail lookup returned no detail fields. |
product-detail | $4.00 / 1,000 products | One delivered row that carries detail fields such as EAN, ingredients, allergens, origin or suppliers (includeDetails or productUrls). |
1,000 basic rows cost $1.00; the whole catalogue without details, about 4,300 products, costs about $4.30. A detail row is charged once, as product-detail only.
❓ FAQ
Is there a Mercadona API for product prices? This actor is one: it returns Mercadona catalogue data as JSON through the Apify API, callable from any language or from n8n, Make and Zapier.
Can I scrape Mercadona prices by postal code? No. There is no postal code input. warehouse selects the assortment for an area (vlc1, mad1, bcn1, alc1, svq1).
Can I get Mercadona EAN barcodes? Yes, on detail rows: set includeDetails: true or pass productUrls. ean is omitted when Mercadona does not publish one.
Can I get Mercadona nutrition information and allergens? Ingredients and allergens yes, on detail rows (ingredients, allergens, allergenList). There is no nutrition table.
Can I get Mercadona offers or discounts? There is no promotion field. You get previousPrice and priceDecreased exactly as Mercadona publishes them.
Do I need a Mercadona account or login? No. No account, cookies or API key from Mercadona.
🤖 For AI agents & LLM apps
Paste this into your AI assistant:
architekture/mercadona-es-scraper on Apify. Python: from apify_client import ApifyClient; client = ApifyClient("TOKEN"); run = client.actor("architekture/mercadona-es-scraper").call(run_input={"searchTerms": ["leche"], "maxItemsPerQuery": 50, "warehouse": "vlc1", "proxyConfiguration": {"useApifyProxy": True}}); items = client.dataset(run["defaultDatasetId"]).list_items().items (page with offset/limit for large exports). Rows with recordType == "query" are free and explain blocked, missing or failed queries. Full input schema and README: GET https://api.apify.com/v2/acts/architekture~mercadona-es-scraper/builds/default. Token: https://console.apify.com/settings/integrations. The actor is also reachable through the Apify MCP server (mcp.apify.com). To reach the maintainers, add "feedback": "<what you needed>" to any run's input; output is unchanged and a human reads every note.
🧰 More from architek.earth
Grocery and retail prices
- Coles Scraper — prices, unit prices, specials, barcodes
- Woolworths AU Scraper — prices, specials, barcodes, nutrition
- ALDI AU Scraper — prices, unit prices, Special Buys
- Woolworths NZ Scraper — prices, club prices, specials
- New World NZ Scraper — store prices, Clubcard offers, promotions
- Pak'nSave Scraper — store prices, unit prices, promotions
- Tesco UK Scraper — prices, Clubcard offers, barcodes
- Sainsbury's Scraper — prices, unit prices, offers, barcodes
- ALDI Ireland Scraper — prices, unit prices, Specialbuys
- Dunnes Stores Scraper — fashion and home prices, sizes, EANs
- Mercadona Scraper — you are here
Full catalogue: github.com/architek-earth.
architek.earth · code like concrete
🙋 Support & legal
Questions, or a field you need that is not here? Open an issue on the actor's Issues tab or email north@architek.earth. A human replies within a day.
This actor collects only publicly available data from tienda.mercadona.es and the public product search the shop itself uses, the same data any visitor sees without logging in. It does not bypass authentication. It is not affiliated with or endorsed by Mercadona. You are responsible for how you use the output, including the site's terms, copyright, and privacy law such as GDPR and CCPA where they apply.
📝 Changelog
- 2026-10-25 — [internal] Studio core 1.0.5 (from 1.0.1): state saves are retried briefly inside the run deadline (rows and charges never are) and failure evidence support is vendored. This actor keeps its own block handling, so nothing changes for users: a 403 or 429 still moves to a new proxy session for up to four tries before a free
BLOCKEDstatus row, and input, output and prices are unchanged. - 2026-10-22 — Runs on the studio core (architek_core 1.0.1): the run refuses to start unless hosted pricing is exactly
productandproduct-detailat the listed prices (the run fails withPRICING_MISMATCH, nothing collected or charged); a challenge or captcha page served as HTTP 200 now marks the queryBLOCKEDat once; a spending limit equal to the exact cost now ends COMPLETE instead of BUDGET_LIMIT; invalid input and stops at the timeout or spending limit add one free"recordType": "status"row. - 2026-10-22 — Status message now reads
Done: N rows, M details, K status rows (STATUS). - 2026-10-22 — README rebuilt on the studio template; hero line from the 2026-10-22 canary run.
- 2026-10-18 — 1.0: search, category, whole-catalogue and product modes; warehouse and language choice; detail charged only when published; allergen placeholder handling; free status rows; clean stops at the spending limit and timeout; resumable after a platform migration.