Complete Guide: How to Scrape El Corte Inglés Products Using Python
Extract product prices, original prices, discounts, GTIN barcodes, and marketplace sellers from El Corte Inglés with Python and the Apify API.

This comprehensive guide demonstrates how to extract structured catalog data from the Spanish department store El Corte Inglés (elcorteingles.es) using Python and the Apify platform. You will learn how to configure category scrapers, extract pricing and discount metrics, capture GTIN barcodes, and differentiate between direct store inventory and third-party marketplace vendors.
El Corte Inglés is a Spanish department store with an online catalog that includes fashion and consumer electronics. Attempting to harvest product listings with direct HTTP clients or simple headless browsers encounters modern anti-bot protection. During reach tests conducted on 2026-10-21, standard direct requests as well as datacenter and residential proxy connections received an "Access Denied" page from the site's Akamai Bot Manager, whereas Apify Unblocker returned the real category pages.
In this tutorial, you will use Python and the El Corte Inglés Scraper (reventadata/elcorteingles-scraper) Actor. All example numbers and dataset fields cited in this guide originate from a verbatim capture dated 2026-10-21 processed through the Actor's own extraction engine.
TL;DR
In this guide, you will set up a Python script using the official Apify API client to extract product listings from El Corte Inglés category pages into structured JSON records.
Key workflow steps include installing apify-client, exporting your API token, defining your target category paths in run_input, triggering the execution on Apify, and fetching structured rows from your default dataset. The extracted dataset contains current prices in euros, original prices, discount percentages, brands, GTIN barcodes, and merchant names.
The Actor is available on the Apify Store at apify.com/reventadata/elcorteingles-scraper.
Prerequisites and setup
Before running the extraction script, verify that your local development environment meets the following technical prerequisites:
- Python 3.11 or newer: The official
apify-client3.x library requires Python 3.11+. - Apify account: You can sign up with an email address or GitHub account at apify.com.
- Apify API token: Located under API & Integrations in the Apify Console.
Install the Apify Python client library using pip:
pip install -U "apify-client~=3.0"
Next, configure your API token as an environment variable in your terminal:
export APIFY_API_TOKEN="your_apify_token_here"
The Apify Console serves as your cloud workspace where you can inspect Actor runs, monitor execution logs, review storage datasets, and configure scheduled tasks.
Understanding El Corte Inglés Scraper
El Corte Inglés Scraper extracts catalog data from elcorteingles.es through specialized handling of the site's architecture:
- Robots.txt compliance and category routing: The site's
robots.txtexplicitly disallows search paths (/search-nwx/,/*/search) and parameterised filter URLs (such asbrand::orprice::). To comply with site rules, the Actor also refuses any query string and search URL up front. It requests clean category paths (e.g.,/electronica/moviles-y-smartphones/or/moda-mujer/zapatos/) and handles all brand, price, and discount filtering post-fetch. - Embedded state parsing: Category pages are server-rendered Vue pages containing an inline JavaScript state object (
window.__MOONSHINE_STATE__). While listing grid HTML contains skeleton placeholders filled client-side, the state script already holds complete product metadata. The Actor parses this state directly, joiningstate.productswithstate._datalayer[0].products. - Akamai Bot Manager navigation: A direct request from a Mac got HTTP 403 and an "Access Denied" body, and the datacenter and residential connections tried from the platform got a deny body too. The Actor routes requests through Apify Unblocker, which returned the real page.
- Site pagination boundaries: Each page holds 12 products. The site enforces a hard ceiling of 833 pages per category (9,996 products), answering page 834 with HTTP 404.
Step-by-step walkthrough
Step 1: Initialize the client and define inputs
In your Python project, import os and ApifyClient, initialize the client with your environment token, and define the run configuration dictionary:
import os
from apify_client import ApifyClient
# 1. Initialize ApifyClient with the token from the environment
client = ApifyClient(os.environ["APIFY_API_TOKEN"])
# 2. Configure El Corte Inglés category URL: 2 pages, up to 24 items
run_input = {
"categoryUrls": [
"https://www.elcorteingles.es/electronica/moviles-y-smartphones/"
],
"maxPagesPerCategory": 2,
"maxItems": 24,
}
The categoryUrls parameter accepts one or more category listing URLs. Setting maxPagesPerCategory: 2 limits the crawl to the first two numbered pages (up to 24 items), which provides a fast baseline test.
Step 2: Trigger execution on Apify
Invoke the Actor using the .call() method on the Actor client, passing run_input:
# 3. Start the Actor run and wait for it to finish
print("Starting El Corte Inglés extraction...")
run = client.actor("reventadata/elcorteingles-scraper").call(run_input=run_input)
if run is None or run.status != "SUCCEEDED":
status = run.status if run else "unknown"
raise SystemExit(f"Run did not succeed (status: {status}).")
# 4. Fetch the saved products
items = client.dataset(run.default_dataset_id).list_items().items
print(f"Retrieved {len(items)} products.\n")
The .call() method initiates cloud execution and blocks until the run settles into a terminal state (SUCCEEDED, FAILED, or TIMED-OUT).
Step 3: Inspect dataset records
Once the run finishes successfully, access the dataset items stored in run.default_dataset_id:
for item in items:
print(item["name"])
print(f" Brand: {item.get('brand')} | Seller: {item.get('seller')} | Marketplace: {item.get('isMarketplace')}")
print(f" Price: {item.get('price')} {item.get('currency')} | Original: {item.get('originalPrice')}")
print(f" Discount: {item.get('discountPercent')}% | On sale: {item.get('onSale')}")
print(f" Barcode: {item.get('gtin')} | Status: {item.get('status')}")
print(f" {item['url']}")
print("-" * 40)
The record below is a verbatim sample captured from page 16 of /moda-mujer/zapatos/, parsed with the Actor's own extraction engine from a fixture dated 2026-10-21:
{
"id": "MP_0623819_252BZ131810522",
"name": "Zapatillas deportivas de mujer retro 13 18 con cordones Marrón",
"brand": "Bimba y Lola",
"url": "https://www.elcorteingles.es/moda-mujer/MP_0623819_252BZ131810522-marron-pr-zapatillas-deportivas-de-mujer-retro-13-18-con-cordones/",
"image": "https://dam.elcorteingles.es/producto/www-8445394427095-00.jpg",
"gtin": "8445394427149",
"price": 68.6,
"currency": "EUR",
"originalPrice": 98.0,
"discountPercent": 30,
"discountAmount": 29.4,
"onSale": true,
"category": "Moda mujer > Zapatos > Zapatillas > Zapatillas deportivas",
"categories": [
"Moda mujer",
"Zapatos",
"Zapatillas",
"Zapatillas deportivas"
],
"seller": "BIMBA & LOLA",
"isMarketplace": true,
"colourCount": 1,
"status": "ADD",
"isNew": false,
"categoryPath": "/moda-mujer/zapatos/",
"page": 16,
"position": 1
}
Working with the API
The Python client offers two distinct execution methods for this Apify Actor. Calling client.actor("reventadata/elcorteingles-scraper").call(run_input=run_input) starts the execution and blocks until the run finishes, returning a populated run model or None. For background tasks, scheduled scripts, or job queues, .start(run_input=run_input) triggers cloud execution immediately and returns the run object right away, allowing you to track progress later using its unique ID.
Authentication relies on the API token loaded from APIFY_API_TOKEN; keep this secret out of version control. Once a run finishes, client.dataset(run.default_dataset_id).list_items().items fetches dataset records in a single batch, while .iterate_items() allows streaming large datasets item by item to optimize local memory usage.
For event-driven architectures, you can configure webhooks on the ACTOR.RUN.SUCCEEDED event. As detailed in Apify documentation, the webhook payload's resource object contains the response of the Get Actor run endpoint, providing direct access to defaultDatasetId so your application can ingest fresh rows without polling.
Error handling: check run.status after execution. Supported terminal statuses include SUCCEEDED, FAILED, and TIMED-OUT. El Corte Inglés Scraper intentionally raises a RuntimeError if zero rows are saved, preventing silent failures. When diagnosing runs, inspect logs programmatically with client.log(run.id).get(); each page logs its product count and the site's category total, and the final line tallies the filter rejections.
Advanced usage patterns
El Corte Inglés Scraper can be adapted to several enterprise data extraction patterns:
Multi-category batch extraction
Pass multiple category paths in categoryUrls, such as ["/electronica/moviles-y-smartphones/", "/moda-mujer/zapatos/"]. The Actor walks each category in the specified sequence and aggregates records into one unified dataset. Product deduplication tracks IDs across categories, so items listed in multiple category hierarchies are stored only once, and the run halts once maxItems is reached.
Marketplace vendor auditing
By setting sellerType: "marketplace", you can isolate catalog entries fulfilled by third-party retailers to audit merchant pricing, shipping terms, and catalog assortment. Conversely, setting sellerType: "elcorteingles" restricts the dataset exclusively to direct department store retail inventory.
Discount threshold monitoring
Combine onlyDiscounted: true with minDiscountPercent: 25 to capture substantial price drops. Because filtering occurs within the Actor before records are saved to storage, your dataset contains only relevant promotional records.
Automated scheduled sweeps
Save your preferred input configuration as a task (a reusable named preset) in the Apify Console. Configure an Apify schedule using standard cron expressions; for instance, 0 8 * * * triggers the scraper every morning at 8 AM. When combined with webhooks, new catalog updates flow directly into your analytics data warehouse.
Understanding your data
The dataset produced by El Corte Inglés Scraper provides 23 structured fields designed for retail analytics:
- Product code structure (
id): Direct retail inventory features anAprefix followed by numerical identifiers (e.g.,A200977771), whereas third-party marketplace stock uses the formatMP_<seller>_<sku>(e.g.,MP_0623819_252BZ131810522). - Comprehensive price metrics: The
pricefield reflects the active offer price in EUR. When items are on promotion,originalPrice,discountPercent, anddiscountAmountare populated, andonSaleevaluates totrue. On page 16 of our footwear fixture, 9 of 12 items carried discounts between 16% and 31%. For items selling at standard retail price, discount fields remainnull. - Merchant attribution: The
sellerstring indicates the merchant of record (e.g.,"El Corte Ingles, S.A.","BIMBA & LOLA", or"GRUPO MUSTANG"), accompanied by theisMarketplaceboolean flag. - Barcodes and taxonomy: The
gtinfield holds standard EAN barcodes, whilecategoryandcategoriessupply hierarchical taxonomy paths.
Troubleshooting guide
When configuring and running El Corte Inglés Scraper, refer to these common operational scenarios:
- Run FAILED with zero records saved: The Actor intentionally raises
RuntimeError: 0 rows for categories...if no products pass your filter criteria. This design ensures that empty results trigger immediate alerts rather than completing silently. Verify that yourbrands,minDiscountPercent, or price ranges are not overly restrictive for the chosen category. - Input validation errors: If the Actor raises a
ValueErrorfor a category URL, it contains query strings (?), search paths (/search/,/search-nwx/), or attribute filter prefixes (brand::). Strip parameters to supply only clean category paths. - Fewer rows than
maxItems: For smaller categories (such as smartphones with 135 items across 12 pages), the Actor stops after the last page computed from the site's product count (page 12 for 135 products), even ifmaxPagesPerCategoryis set higher. - Inspecting execution logs: Retrieve detailed run logs using
client.log(run.id).get(). The log records product counts per page, the site's category total, and a final tally of filter rejections.
Best practices
Follow these best practices to ensure reliable and efficient catalog extraction:
- Target canonical category paths: Copy URLs directly from main category navigation on
elcorteingles.esand omit query parameters. - Set appropriate caps: Always define
maxItemsandmaxPagesPerCategoryto control execution scope and keep runs bounded. - Use post-fetch filters for discount audits: Use
onlyDiscounted: trueorminDiscountPercentto drop full-price inventory before records are pushed to the dataset. - Rely on GTIN for catalog matching: Match items across retail competitors using standard
gtinbarcode values rather than relying on variable product names. - Handle execution status explicitly: Always check
run.status == "SUCCEEDED"before reading records from the dataset client.
Pricing
For current pricing and details, see the Store page.
Conclusion and next steps
You have learned how to automate product extraction from El Corte Inglés using Python and Apify. You configured category targets, applied post-fetch discount filters, executed cloud runs, and exported structured records containing prices, discounts, GTIN barcodes, and marketplace seller designations.
Next steps include setting up Apify Schedules for automated daily tracking or connecting webhooks to stream data into your analytics database.
Try El Corte Inglés Scraper yourself and let me know what you build!
About the author: reventadata builds and maintains marketplace and retail scrapers on the Apify Store.
Resources
About the author
- Hi, I’m the engineer behind ReventaData. I build automated web scrapers, reverse-engineer undocumented APIs, and design data pipelines on Apify that turn complex, unstructured websites into clean, reliable feeds. Here on Hashnode, I share practical tutorials on modern web scraping with Python, bypassing aggressive anti-bot protections (Cloudflare, Akamai, PerimeterX), and data pipeline automation, reverse-engineering hidden endpoints, and automating data extraction. Explore our turnkey scrapers: https://apify.com/reventadata
Comments
Join the discussionNo comments yet. Be the first to comment.



