# MediaMarkt Scraper \[$1.50/1K💰] | DE Prices | Saturn Data (`ahmed_jasarevic/mediamarkt-scraper`) Actor

Scrape mediamarkt.de and saturn.de product data: price, promo price, discount, EAN, brand, availability, seller and full specs. Ideal for German electronics price monitoring and price comparison.

- **URL**: https://apify.com/ahmed_jasarevic/mediamarkt-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## MediaMarkt Scraper: German Electronics Prices & Saturn Data

Scrape product data from **mediamarkt.de** and **saturn.de** (MediaMarktSaturn, Europe's largest consumer-electronics retailer) and export title, brand, EAN, MPN, price, promo price, strike price, discount, availability, seller, ratings, category, rank and full specs as clean structured JSON. A single actor covers both German storefronts, and no browser is needed.

Built for EU price-monitoring teams, MAP-enforcement, electronics resellers and market-research firms who need reliable German electronics price data.

### Main use cases

- **Price monitoring and preisvergleich**: track MediaMarkt and Saturn prices, promos and discounts across a product catalogue.
- **MAP and pricing-intelligence**: detect promo prices, strike prices and discount percentages for brand and channel enforcement.
- **Electronics product data / produktdaten**: build a structured catalogue with EAN, MPN, brand and full specification sheets.
- **Competitor and assortment analysis**: compare prices, availability and seller (first-party vs marketplace) across both storefronts.
- **Reseller and marketplace research**: monitor third-party marketplace offers, seller ratings and shipping costs.
- **Price-drop alerting**: schedule runs and detect new discounts and availability changes over time.

### How it works

Both sites are server-rendered and embed the **entire Apollo GraphQL cache** into every page as a JavaScript blob:

```
window.__PRELOADED_STATE__ = { reduxInitialStore, apolloState, ... }
```

The `apolloState` object is the normalized Apollo cache and contains everything the actor needs: product record (title, EAN, manufacturer, breadcrumbs, URL), price features (price, promo price, strike price, shipping cost, currency), online-status features (availability, delivery and pickup flags), marketplace offer (seller, rating, shipping), the full specification map, the review rating distribution, and search/category result lists in ranking order. The blob is JavaScript rather than strict JSON (it can contain `undefined`/`NaN` literals), so the parser sanitizes those tokens before `JSON.parse`.

Search result pages are fetched from the site's own internal JSON API (the same one the storefront calls): one request returns roughly 330 KB of JSON in well under a second, carrying products plus price, availability, EAN, rating and review count. Product detail pages are parsed from HTML. If the JSON call fails for any reason, the crawler **automatically falls back to the HTML path**, so an internal change costs speed, never results. No browser and no DOM scraping are used.

### Scrape MediaMarkt & Saturn Prices Without An Official API

MediaMarkt/Saturn sit behind **Cloudflare bot management**, which blocks on two layers:

1. **IP reputation**: datacenter IPs (including Apify's) get a hard `403` at the edge, even with a perfect fingerprint. Requests therefore run through the **Apify residential proxy by default** (`proxy` input, `groups: ["RESIDENTIAL"]`), so every request leaves from a real residential IP.
2. **TLS fingerprint (JA3/JA4)**: plain HTTP clients such as `got-scraping` and `undici` are rejected, while browser-grade TLS passes. Pages are fetched with `apify-node-curl-impersonate`, presenting a coherent Chrome fingerprint (headers and `sec-ch-ua` included).

Occasional managed challenges (`Just a moment...`) still surface; each retry gets a **fresh proxy session/IP**, so they clear within one or two attempts. All requests share one sticky residential session and a shared cookie jar, so Cloudflare sees a single continuing browser session instead of a new visitor per request; a new session/IP is only drawn on a retry.

**Known limitations**

- The full spec sheet (`specs` beyond the highlighted features) and `mpn` are available when `enrichProductDetails` is enabled, since they live on the product detail page. EAN, rating, review count, price and availability are included in listing-only runs too.
- `mpn` is extracted from the "Hersteller-Nr." spec feature; not every product exposes it.
- Prices are in EUR and reflect the German storefront (de-DE).
- MediaMarkt and Saturn are fully contingent on their embedded page state; if the site changes the state format, the parser's single sanitize-and-parse layer is the place to update.

### Input Parameters

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `searchQueries` | array (stringList) | No | `["iphone 15"]` | Search terms to look up on each marketplace, e.g. `iphone 15`, `playstation 5`, `samsung tv`. |
| `marketplaces` | array (enum) | No | `["mediamarkt.de", "saturn.de"]` | Which sites to run the search queries on. Allowed: `mediamarkt.de`, `saturn.de`. |
| `startUrls` | array (requestListSources) | No | one product URL | Product, category or search URLs to scrape directly. Product URLs are parsed in full; category/search URLs are treated as listings. |
| `maxItems` | integer | No | `50` | Maximum products to output (hard cap 500). Listing pages are crawled automatically until this many products are collected. |
| `enrichProductDetails` | boolean | No | `true` | Fetch each product's detail page for EAN, specs and ratings. Disable for a cheaper listing-only run (title, price, availability, seller, ranking only). |
| `proxy` | object (proxy) | No | Apify proxy, RESIDENTIAL group | MediaMarkt/Saturn block datacenter IPs, so requests go through the Apify residential proxy by default. Switch to a custom proxy URL or disable it to test direct access. |

### Output Fields

One dataset item per product. The default `overview` view shows Title, Price, Promo, Availability, Rating, Ratings and URL.

| Field | Type | Description |
|---|---|---|
| `url` | string | Absolute URL of the product page. |
| `productId` | string | MediaMarkt/Saturn internal product ID (SKU). |
| `sku` | string | Alias of `productId`. |
| `title` | string | Full product title. |
| `brand` | string | Brand / manufacturer name. |
| `manufacturer` | string | Manufacturer name. |
| `ean` | string | European Article Number (GTIN-13) of the product. |
| `mpn` | string | Manufacturer Part Number (Hersteller-Nr.) when available. |
| `price` | number | Current price in EUR. |
| `currency` | string | Currency code (EUR). |
| `promoPrice` | number | Promotional price in EUR (null when no promo is active). |
| `strikePrice` | number | Original/strike-through price in EUR (null when no discount). |
| `discountPercentage` | number | Computed discount percentage when a promo price is lower than the regular price. |
| `availability` | string | Online status: `AVAILABLE`, `MP_OFFER`, `NOT_AVAILABLE`, etc. |
| `availableForDelivery` | boolean | Whether the product can be delivered. |
| `availableForPickup` | boolean | Whether the product can be picked up in store. |
| `shippingCost` | number | Shipping cost in EUR. |
| `seller` | string | Seller name (MediaMarkt/Saturn for first-party, marketplace seller name otherwise). |
| `sellerRating` | number | Marketplace seller rating (0-5). |
| `sellerReviewsCount` | number | Number of visible reviews for the marketplace seller. |
| `rating` | number | Average customer rating (0-5), computed from the rating distribution. |
| `ratingCount` | number | Total number of customer ratings. |
| `categoryPath` | array | Breadcrumb category path, e.g. `["Smartphone & Tarife", "Apple iPhone"]`. |
| `category` | string | Leaf category name from the breadcrumb. |
| `rank` | number | Position of the product in the search/category listing (1-based). |
| `categoryRanking` | string | Human-readable ranking, e.g. `#3 in /de/search.html`. |
| `specs` | object | Key/value map of product specifications (Produkttyp, Betriebssystem, Speicherkapazität, ...). |
| `marketplaceOffer` | object | Best third-party marketplace offer details (offerId, price, seller, shipping) when present. |
| `source` | string | Source site URL. |
| `scrapedAt` | string | ISO timestamp of when the product was scraped. |

### Example Input And Output

**Input**

```json
{
  "searchQueries": ["iphone 15", "playstation 5"],
  "marketplaces": ["mediamarkt.de", "saturn.de"],
  "maxItems": 50,
  "enrichProductDetails": true
}
```

**Output (one dataset row)**

```json
{
  "url": "https://www.mediamarkt.de/de/product/_apple-iphone-15-128gb-2959931.html",
  "productId": "2959931",
  "sku": "2959931",
  "title": "Apple iPhone 15 128 GB Schwarz",
  "brand": "Apple",
  "manufacturer": "Apple",
  "ean": "0194253441610",
  "mpn": "MTP03ZD/A",
  "price": 849.0,
  "currency": "EUR",
  "promoPrice": 799.0,
  "strikePrice": 899.0,
  "discountPercentage": 11,
  "availability": "AVAILABLE",
  "availableForDelivery": true,
  "availableForPickup": true,
  "shippingCost": 0,
  "seller": "MediaMarkt",
  "sellerRating": null,
  "sellerReviewsCount": null,
  "rating": 4.6,
  "ratingCount": 3214,
  "categoryPath": ["Smartphone & Tarife", "Apple iPhone"],
  "category": "Apple iPhone",
  "rank": 3,
  "categoryRanking": "#3 in /de/search.html",
  "specs": { "Produkttyp": "Smartphone", "Betriebssystem": "iOS", "Speicherkapazität": "128 GB" },
  "marketplaceOffer": null,
  "source": "https://www.mediamarkt.de",
  "scrapedAt": "2026-10-11T09:00:00.000Z"
}
```

### Integrations & Automation

Every Apify actor is reachable through the **Apify API**, and this one plugs into **webhooks**, **Zapier** and **Make** so results can flow into a Google Sheet, Airtable base, database or price-comparison tool. For price monitoring, run it on a **schedule**: a daily or weekly snapshot of your target products or categories is enough to catch promo prices, discounts and availability changes, and recurring runs also improve the actor's Store recommendation signals.

### Related Actors

- [mediamarkt-saturn-product-scraper](https://apify.com/truenorth/mediamarkt-saturn-product-scraper): a MediaMarktSaturn product scraper covering both brands.
- [mediamarkt-scraper](https://apify.com/unfenced-group/mediamarkt-scraper): a multi-country MediaMarkt scraper (DE/BE/AT/ES/PL).
- [ikea-scraper](https://apify.com/ahmed_jasarevic/ikea-scraper): EU retail product data with prices, to broaden a European price dataset.
- [newegg-scraper](https://apify.com/ahmed_jasarevic/newegg-scraper): electronics product and pricing data for cross-market comparison.
- [allegro-scraper](https://apify.com/ahmed_jasarevic/allegro-scraper): EU e-commerce marketplace products with prices.

### FAQ

#### Is there an official MediaMarkt API?

No public product API is documented. MediaMarkt and Saturn are server-rendered and embed their full Apollo GraphQL state (`window.__PRELOADED_STATE__`) into each page. This actor reads that state directly (plus the storefront's internal JSON search API), so you get structured product data without an API key.

#### What are the alternatives to this actor / this data source?

For German price data you can combine this with Geizhals, Idealo or Amazon.de scrapers. MediaMarkt and Saturn are the leading consumer-electronics retailers in Germany, so they are worth having alongside comparison portals to capture first-party and marketplace prices.

#### How do I monitor MediaMarkt and Saturn prices over time?

Schedule this actor against your target `searchQueries` or `startUrls`, keeping `enrichProductDetails` on, and store each run's dataset. Comparing runs over time surfaces new promo prices, discounts and availability changes without manual checks.

#### Does a run need the proxy?

Yes for reliable results: MediaMarkt and Saturn return `403` to datacenter IPs. The actor uses the Apify residential proxy by default, plus browser-grade TLS impersonation to pass Cloudflare. Disabling the proxy makes requests return `403`.

#### Why are `specs` and `mpn` missing on some rows?

The full specification sheet and `mpn` live on the product detail page and are returned only when `enrichProductDetails` is enabled. EAN, rating, review count, price and availability are included even in listing-only runs.

#### Can the same run cover both MediaMarkt and Saturn?

Yes. Set `marketplaces` to `["mediamarkt.de", "saturn.de"]` (the default) and each search query is run on both storefronts in one run.

### SEO Keywords

mediamarkt, media markt, saturn, mediamarkt scraper, mediamarkt preise, saturn preise, preisvergleich, produktdaten, elektronik preise, price monitoring, e-commerce daten, mediamarkt api, online preise vergleichen, elektronikprodukte daten, mediamarkt alternative, saturn scraper, german electronics prices, mediamarkt products, saturn products, price comparison germany

### For AI Agents & LLM Apps

Purpose: return one structured product row per MediaMarkt/Saturn product for a given search query and marketplace set.

Minimal working input:

```json
{ "searchQueries": ["iphone 15"], "marketplaces": ["mediamarkt.de"], "maxItems": 20 }
```

Variant input (scrape specific product/category URLs):

```json
{ "startUrls": [{ "url": "https://www.mediamarkt.de/de/product/_apple-iphone-18-pro-256gb-burgundy-3071600.html" }], "maxItems": 1 }
```

Output fields: `url, productId, sku, title, brand, manufacturer, ean, mpn, price, currency, promoPrice, strikePrice, discountPercentage, availability, availableForDelivery, availableForPickup, shippingCost, seller, sellerRating, sellerReviewsCount, rating, ratingCount, categoryPath, category, rank, categoryRanking, specs, marketplaceOffer, source, scrapedAt`.

Behaviors an agent should know:

- Provide either `searchQueries` (run on each entry in `marketplaces`) or `startUrls` (product, category or search URLs).
- `marketplaces` defaults to both `mediamarkt.de` and `saturn.de`. Allowed values are exactly those two.
- `maxItems` defaults to **50**, hard cap **500**; listing pages are paginated automatically until reached.
- `enrichProductDetails` defaults to `true` and is what enables `ean`, `mpn` and the full `specs`; setting it to `false` returns listing-only rows (title, price, availability, seller, ranking) more cheaply.
- Prices are in EUR and reflect the German (de-DE) storefront.
- The residential proxy is on by default and should stay on; without it requests return `403`.
- `mpn` and some `specs` can be absent per product; do not treat that as a failure.

Billing: pay-per-event: **$0.0015 per result** ($1.50 / 1,000 products) plus a $0.00005 actor-start event.

### Legal & Compliance Disclaimer

This actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by MediaMarktSaturn Retail Group, MediaMarkt or Saturn**. It accesses only publicly available MediaMarkt/Saturn product pages and internal JSON surfaces; it does not log in, bypass authentication, or solve CAPTCHAs on anyone's behalf. Users are responsible for ensuring their use complies with the sites' Terms of Service and with applicable data-protection law.

# Actor input Schema

## `searchQueries` (type: `array`):

Search terms to look up on MediaMarkt / Saturn (e.g. "iphone 15", "playstation 5", "samsung tv"). Each query is run on the selected marketplaces.

## `marketplaces` (type: `array`):

Which sites to run the search queries on.

## `startUrls` (type: `array`):

Product, category or search URLs on mediamarkt.de / saturn.de to scrape directly. Product URLs are parsed in full; category/search URLs are treated as listings.

## `maxItems` (type: `integer`):

Maximum number of products to output (hard cap 500). Listing pages are crawled automatically until this many products are collected.

## `enrichProductDetails` (type: `boolean`):

Fetch each product's detail page to get EAN, specs and ratings. Disable for a cheaper listing-only run (title, price, availability, seller, ranking only).

## `proxy` (type: `object`):

MediaMarkt/Saturn block datacenter IPs, so requests go through the Apify residential proxy by default. Switch to a custom proxy URL or disable it to test direct access.

## Actor input object example

```json
{
  "searchQueries": [
    "iphone 15"
  ],
  "marketplaces": [
    "mediamarkt.de",
    "saturn.de"
  ],
  "startUrls": [
    {
      "url": "https://www.mediamarkt.de/de/product/_apple-iphone-18-pro-256gb-burgundy-3071600.html"
    }
  ],
  "maxItems": 50,
  "enrichProductDetails": true,
  "proxy": {
    "useApifyProxy": true,
    "groups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "iphone 15"
    ],
    "marketplaces": [
        "mediamarkt.de",
        "saturn.de"
    ],
    "startUrls": [
        {
            "url": "https://www.mediamarkt.de/de/product/_apple-iphone-18-pro-256gb-burgundy-3071600.html"
        }
    ],
    "proxy": {
        "useApifyProxy": true,
        "groups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/mediamarkt-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": ["iphone 15"],
    "marketplaces": [
        "mediamarkt.de",
        "saturn.de",
    ],
    "startUrls": [{ "url": "https://www.mediamarkt.de/de/product/_apple-iphone-18-pro-256gb-burgundy-3071600.html" }],
    "proxy": {
        "useApifyProxy": True,
        "groups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/mediamarkt-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "iphone 15"
  ],
  "marketplaces": [
    "mediamarkt.de",
    "saturn.de"
  ],
  "startUrls": [
    {
      "url": "https://www.mediamarkt.de/de/product/_apple-iphone-18-pro-256gb-burgundy-3071600.html"
    }
  ],
  "proxy": {
    "useApifyProxy": true,
    "groups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call ahmed_jasarevic/mediamarkt-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/mediamarkt-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/E54nmolwJZBiRTXJH/builds/pyLTca0GFloSo83cZ/openapi.json
