Mercadona Scraper — Prices, Unit Prices, EANs, Ingredients avatar

Mercadona Scraper — Prices, Unit Prices, EANs, Ingredients

Pricing

from $1.00 / 1,000 products

Go to Apify Store
Mercadona Scraper — Prices, Unit Prices, EANs, Ingredients

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

architek.earth

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

16 days ago

Last modified

Categories

Security

Limited permissions

Share

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.

SourceMarketFromStandout fields
Mercadona (tienda.mercadona.es)Spain$1.00 / 1,000 productsprice / 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. warehouse picks the assortment (vlc1 Valencia 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 with INVALID_INPUT instead of silently returning Valencia's range.
  • There is no specials or promotion field. previousPrice and priceDecreased are passed through as Mercadona publishes them; in the 2026-10-18 recon, 25 products carried a previous price while priceDecreased was false. Do not read previousPrice as a sale.
  • No nutrition table and no stock counts are returned. unavailableFrom and unavailableWeekdays are Mercadona's availability notes, not stock.
  • brand comes on search rows and detail rows; category listings do not carry it, so set includeDetails: true for brand on category runs. Loose produce is priced per piece at an approximate weight (approxSize: true) with the per-kg price in referencePrice.
  • Fields Mercadona does not publish are omitted, never null. A failed detail lookup keeps the row at the product price without detail fields.
  • Mercadona's search returns at most 1,000 results per term; RUN_SUMMARY adds a warning when a term matches more. Products are de-duplicated by productId across 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_LIMIT or BUDGET_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", status NOT_FOUND, BLOCKED or ERROR) that says what happened. Invalid input stops before collection with one free "recordType": "status" row (status INVALID_INPUT, with a message), a status message and RUN_SUMMARY. A run that stops at the timeout or your spending limit adds one free "recordType": "status" row (TIME_LIMIT or BUDGET_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

ParameterTypeDefaultDescription
searchTermsarray—Keywords such as leche or aceite de oliva, searched with Mercadona's own shop search. Up to 1,000 results per term.
categoriesarray—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.
productUrlsarray—Product URLs (tienda.mercadona.es/product/4241/...) or ids (4241). Always include detail fields where published. Up to 500; fetched first.
maxItemsPerQueryinteger100Products per search term or category. 0 = everything (search stays capped at 1,000).
includeDetailsbooleanfalseOne extra request per product for EAN, ingredients, allergens, origin, suppliers, storage and photos. Rows with detail fields are charged as product-detail.
warehousestringvlc1Assortment to read: vlc1, mad1, bcn1, alc1, svq1. Unknown codes are rejected before collection.
languageselecteses, en or ca: Mercadona's own translations of names and categories.
proxyConfigurationproxy{"useApifyProxy": true}Apify datacenter proxy is the tested default. Blocked or rate-limited requests are retried on a fresh IP.
feedbackstring—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.

FieldTypeMeaning
productIdstringMercadona product id; the join key within Mercadona.
retailerstringAlways "Mercadona".
name / brand / packaging / sizestringProduct name, brand, packaging and size text such as "6 briks · 6 l". Omitted when not published.
price / currencynumber / stringPrice of one sellable unit (pack, bottle, piece) and "EUR".
referencePrice / referenceUnitnumber / stringUnit price and its basis (kg, L or unit).
previousPrice / priceDecreasednumber / booleanMercadona's previous price and its own flag, as published. Omitted when absent.
taxPercentagenumberVAT rate, for example 4, 10 or 21.
approxSize / isNew / requiresAgeCheckbooleanSold by approximate weight; new arrival; age-restricted. Present only when true.
unavailableFrom / unavailableWeekdaysstring / arrayMercadona's availability notes, where set.
category / categoryPathstringLowest category and the full path joined by >.
image / url / warehousestring600 px image, product page, warehouse read.
sourceobject{source: "search" | "category" | "product", searchTerm, category, subCategoryId, categoryUrl, page} as applicable.
eanstringBarcode, on detail rows when published.
recordTypestring"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.

EventPriceWhat it covers
product$1.00 / 1,000 productsOne delivered search or category row, including a row whose detail lookup returned no detail fields.
product-detail$4.00 / 1,000 productsOne 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

Full catalogue: github.com/architek-earth.

architek.earth · code like concrete

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 BLOCKED status 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 product and product-detail at the listed prices (the run fails with PRICING_MISMATCH, nothing collected or charged); a challenge or captcha page served as HTTP 200 now marks the query BLOCKED at 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.