# Mueller.de Scraper — Drugstore Products & Prices (`studio-amba/mueller-de-scraper`) Actor

Scrape products, prices, brands, EAN codes and availability from mueller.de — a large German drugstore chain (cosmetics, household goods, toys, media). Search by keyword. No login needed.

- **URL**: https://apify.com/studio-amba/mueller-de-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Stats:** 1 total users, 1 monthly users, 53.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 result scrapeds

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Mueller.de Scraper — Drugstore Products & Prices

Scrape products, prices, brands, EAN codes and availability from [mueller.de](https://www.mueller.de), a large German drugstore chain covering cosmetics, personal care, household goods, toys, media and stationery. Search by keyword and get clean, structured JSON. No login required.

Built for price monitoring, catalog research, and competitive analysis in the German drugstore/retail space — the same category as our `rossmann-scraper`, `dm-scraper` and `kruidvat-scraper` actors.

### What it does

Mueller.de is a Next.js storefront that runs a Fastly JavaScript bot-challenge on every dynamic page (search results, product pages) — a plain HTTP request gets a `403 Client Challenge` response even when replaying cookies from a prior visit. This actor drives a real headless browser (Playwright) that solves the challenge like a normal visitor, then reads two data sources per product:

1. **Search-results tiles** — name, current price, strike-through (UVP) price, price-per-unit, capacity, delivery/availability badges, and the internal product ID.
2. **Product detail page** — a full `schema.org/Product` JSON-LD block embedded in every product page, which carries the brand, EAN/GTIN barcode, internal SKU, and the full product description that the search tile doesn't expose.

The actor merges both sources into one record per product.

- **Keyword search** — pass any search term (`shampoo`, `creme`, `zahnpasta`, `duschgel`) and get matching products.
- **Automatic pagination** — walks Mueller's search-results pages (fixed at 60 results/page) until it hits your `maxResults` or runs out of matches.
- **Deduplication** — products are deduplicated by internal product ID within a run.
- **Migration-safe** — because this actor does two requests per product (listing + detail hop), it persists progress via `Actor.useState` so a very large run resumes cleanly instead of restarting from scratch if Apify migrates the run between hosts.

### Output

Each product is one record. Real examples from a live test run (query `shampoo`):

```json
{
  "name": "Elvital Shampoo Dream Length",
  "brand": "L'ORÉAL PARIS",
  "price": 3.99,
  "currency": "EUR",
  "url": "https://www.mueller.de/p/elvital-shampoo-dream-length-IPN3074311/",
  "scrapedAt": "2026-07-27T10:03:11.000Z",
  "originalPrice": 4.49,
  "pricePerUnit": "13,30 € / 1 l",
  "discount": "-11%",
  "ean": "3600524138530",
  "sku": "3074311",
  "productId": "3074311",
  "inStock": true,
  "deliveryInfo": "Online verfügbar, In die Filiale lieferbar",
  "imageUrl": "https://images.prod.ecom.mueller.de/_next/image?url=https%3A%2F%2Fstatic.prod.ecom.mueller.de%2Fproducts%2F3600524138530%2FMarkant_3600524138530_FrontView_3600524138530_5076445.jpg&w=1200&q=75",
  "productDescription": "Das Elvital Dream Length Super Aufbau Shampoo von L'ORÉAL PARIS ist die ideale Reinigung für langes und geschädigtes Haar...",
  "category": "Haarshampoo",
  "categories": ["Drogerie", "Pflege", "Haarpflege", "Haarwäsche", "Haarshampoo"],
  "language": "de"
}
```

Another example — a children's product without a discount:

```json
{
  "name": "Bübchen Shampoo & Duschgel 2in1 Bluey",
  "brand": "BÜBCHEN",
  "price": 2.45,
  "currency": "EUR",
  "url": "https://www.mueller.de/p/buebchen-shampoo-duschgel-2in1-bluey-PPN3147149/",
  "scrapedAt": "2026-07-27T10:03:12.000Z",
  "pricePerUnit": "9,80 € / 1 l",
  "ean": "4065331005212",
  "sku": "3147149",
  "productId": "3147149",
  "inStock": true,
  "deliveryInfo": "Online verfügbar, In die Filiale lieferbar",
  "imageUrl": "https://images.prod.ecom.mueller.de/_next/image?url=https%3A%2F%2Fstatic.prod.ecom.mueller.de%2Fproducts%2F4065331005212%2F...",
  "productDescription": "Mit Bluey wird Pflege zum Abenteuer! Das Bübchen Shampoo & Duschgel reinigt sanft und pflegt mild...",
  "category": "Waschen & Baden",
  "categories": ["Drogerie", "Kind & Mama", "Babypflege", "Waschen & Baden"],
  "language": "de"
}
```

#### Fields

| Field | Description |
|-------|-------------|
| `name` | Product name |
| `brand` | Brand / manufacturer (from the product-page JSON-LD) |
| `price` | Current selling price as a number |
| `currency` | Currency code (`EUR`) |
| `url` | Full product page URL |
| `originalPrice` | Strike-through UVP price, when the item is discounted |
| `pricePerUnit` | Base price per standard unit, e.g. `"13,30 € / 1 l"` |
| `discount` | Computed discount percentage (e.g. `-11%`) |
| `ean` | EAN/GTIN barcode number |
| `sku` | Mueller's internal item number (matches the `IPN`/`PPN` suffix in the URL) |
| `productId` | Mueller's internal numeric product ID |
| `inStock` | Whether the product is currently available (online or in-store) |
| `deliveryInfo` | Human-readable availability text, e.g. `"Online verfügbar, In die Filiale lieferbar"` |
| `rating` | Average customer rating (0–5 scale), when present |
| `reviewCount` | Number of customer reviews, when present |
| `imageUrl` | Primary product image URL |
| `productDescription` | Full product description text |
| `category` | Deepest breadcrumb category name |
| `categories` | Full breadcrumb category path |
| `language` | Content language (`de`) |
| `scrapedAt` | ISO 8601 timestamp of the scrape |

Not every product carries a customer rating — Mueller only shows `rating`/`reviewCount` when the product has reviews, so treat those two fields as optional.

### How to scrape Mueller data

1. Open the actor and set a **Search Query** (for example `shampoo`, `creme`, `zahnpasta`, `parfum`). Leave it empty and it defaults to `shampoo`.
2. Set **Max Results** to the number of products you want.
3. Keep the default **Proxy Configuration** (residential, Germany) — mueller.de runs a JS bot-challenge on every dynamic page, so residential proxies aren't optional here, unlike some sibling drugstore actors.
4. Click **Start**. When the run finishes, download the dataset as JSON, CSV or Excel, or pull it from the API.

#### Input example

```json
{
  "searchQuery": "creme",
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "DE"
  }
}
```

#### Input example — quick test run

```json
{
  "searchQuery": "zahnpasta",
  "maxResults": 5
}
```

### Cost estimate

This actor runs on the STANDARD pay-per-result pricing tier. Each product costs two requests under the hood (one search-listing hit shared across up to 60 products, plus one product-detail page per item) and a full browser render on both — expect noticeably more compute per result than a plain-HTTP actor like `thomann-de-scraper`, since every page has to pass a JS bot-challenge. A 100-result run typically completes in a few minutes.

### Common use cases

- **Price monitoring** — track prices across drugstore categories (cosmetics, personal care, household) over time.
- **Catalog research** — pull structured data on Mueller's assortment for a category or brand.
- **Competitive analysis** — compare Mueller's pricing against Rossmann, dm, and Kruidvat.
- **Availability tracking** — monitor online/in-store availability on specific SKUs.

### Limitations

- Covers the German mueller.de storefront (EUR pricing) only.
- Customer ratings aren't present on every product — Mueller only publishes `aggregateRating` for items with reviews.
- Search relevance and result order follow Mueller's own Typesense-backed ranking; the actor doesn't re-rank results.
- Every page (listing and detail) requires a real browser pass through mueller.de's bot-challenge, so this actor is slower and more compute-intensive per result than actors targeting sites without that protection.

### FAQ

**Does this need a login?**
No. The actor only reads publicly published product data. No account, password or cookies are required.

**Does it use a headless browser?**
Yes. mueller.de runs a Fastly JavaScript challenge on every dynamic page — a plain HTTP request is blocked (`403 Client Challenge`) even with valid cookies. The actor uses Playwright to solve it like a real browser would.

**Why is `originalPrice` sometimes missing?**
Most products are listed at their normal price with no strike-through comparison. `originalPrice` and `discount` only appear when Mueller shows a markdown on that item.

**Why does this cost more per result than other drugstore actors?**
Every product requires a separate detail-page visit (for brand, EAN, and description) on top of the search listing, and both pages require a full browser pass to clear the site's bot-challenge — more compute than a plain-HTTP scraper.

**Is this legal?**
The actor collects publicly available product and pricing information. You are responsible for using the data in line with mueller.de's terms and applicable law.

### Related Scrapers

- [Rossmann Scraper](https://apify.com/studio-amba/rossmann-scraper) — Europe's second-largest drugstore chain (Germany, Poland, Hungary, Turkey)
- [dm Scraper](https://apify.com/studio-amba/dm-scraper) — Germany's largest drugstore chain
- [Kruidvat Scraper](https://apify.com/studio-amba/kruidvat-scraper) — Benelux drugstore chain

### Disclaimer

This actor is an independent tool and is not affiliated with, endorsed by, or connected to Müller Handels GmbH & Co. KG or mueller.de. All product data belongs to its respective owners.

# Actor input Schema

## `searchQuery` (type: `string`):

Search for products by keyword (e.g., 'shampoo', 'creme', 'zahnpasta'). Leave empty to use the default search.

## `maxResults` (type: `integer`):

Maximum number of products to return.

## `proxyConfiguration` (type: `object`):

Proxy settings for accessing mueller.de. Residential proxies are required — the site runs a JS bot-challenge on every dynamic page.

## Actor input object example

```json
{
  "searchQuery": "shampoo",
  "maxResults": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}
```

# 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 = {
    "searchQuery": "shampoo",
    "maxResults": 5,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "DE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/mueller-de-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 = {
    "searchQuery": "shampoo",
    "maxResults": 5,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "DE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/mueller-de-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "searchQuery": "shampoo",
  "maxResults": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}' |
apify call studio-amba/mueller-de-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=studio-amba/mueller-de-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/ULGZvZS3LujhwQ7RB/builds/t1N8HdBytMUWd33iA/openapi.json
