# Netto Scraper: German Discount Grocery Prices & Offers (`studio-amba/netto-scraper`) Actor

Scrape products, prices, deals, and availability from netto-online.de. Germany's popular Netto Marken-Discount supermarket. Supports search queries and category browsing.

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

## Pricing

from $2.00 / 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.

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

## Netto Marken-Discount Scraper

Know current Netto prices, stock, and weekly deals on any product without checking [netto-online.de](https://www.netto-online.de) by hand. This scraper turns Netto's German online shop into structured JSON, including EAN barcodes, brand, stock state and descriptions, and adds the in-store weekly offers ("Filiale" deals) that Netto shows next to the online results. No login or cookies required.

Search by keyword or browse a category. Built for price monitoring, competitor analysis, and grocery assortment tracking.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchQuery` | String | No | Search term (e.g., `"kaffee"`, `"waschmittel"`, `"nudeln"`). Returns every matching online-shop product, paginated. |
| `categoryUrl` | String | No | Netto category URL, e.g. `https://www.netto-online.de/lebensmittel/c-N01` or `https://www.netto-online.de/angebote/c-N07`. Pagination is followed. |
| `maxResults` | Integer | No | Item cap, online products and store offers combined (default: 100, hard cap: 50000) |
| `includeStoreOffers` | Boolean | No | Also return the in-store weekly offers shown on search and category pages (default: true) |
| `proxyConfiguration` | Object | No | Proxy settings. Default: Apify residential, Germany. |

With no `searchQuery` and no `categoryUrl` the scraper starts from the homepage (featured products plus the first five categories).

### Output

Every item has a `channel` field:

- `online`: a product from the netto-online.de shop. Has a product page, EAN when Netto publishes it, brand, description, stock state. `category` and `pricePerUnit` are not filled for online products.
- `store`: an in-store weekly offer ("Filiale" tile). No product page. Carries the offer price, the previous price, the discount label, the pack text and the validity window.

| Field | Type | Example |
|-------|------|---------|
| `name` | String | `"Dallmayr Classic Mild 500 g, 12er Pack"` |
| `brand` | String | `"Dallmayr"` (empty on store offers, Netto does not publish it there) |
| `price` | Number | `87.99` |
| `originalPrice` | Number | `0.79` (only when a previous price is shown) |
| `discount` | String | `"-12 %"` (store offers) |
| `pricePerUnit` | String | `"2.39 / l"` (store offers only) |
| `currency` | String | `"EUR"` |
| `channel` | String | `"online"` or `"store"` |
| `ean` | String | EAN barcode (online products, when published) |
| `sku` | String | Netto article number |
| `inStock` | Boolean | `true`, `false`, or absent when the site does not state it |
| `imageUrl` | String | Product image |
| `description` | String | Product description |
| `validFrom` / `validTo` | String | Store offer window, `"2026-09-14"` / `"2026-09-19"` |
| `bundleText` | String | Store offer pack text, `"Stück"`, `"500 g"` |
| `url` | String | Product page (online) or listing page plus `#store-<sku>` (store offer) |
| `language` | String | `"de"` |
| `scrapedAt` | String | ISO 8601 timestamp |

```json
{
    "name": "Dallmayr Classic Mild 500 g, 12er Pack",
    "brand": "Dallmayr",
    "price": 87.99,
    "currency": "EUR",
    "channel": "online",
    "sku": "1889936000",
    "inStock": true,
    "url": "https://www.netto-online.de/dallmayr-classic-mild-500-g-12er-pack/p-1889936000",
    "scrapedAt": "2026-09-16T10:00:00.000Z"
}
```

```json
{
    "name": "Käse-Schinken-Croissant",
    "brand": "",
    "price": 0.69,
    "originalPrice": 0.79,
    "discount": "-12 %",
    "currency": "EUR",
    "channel": "store",
    "sku": "448684",
    "bundleText": "Stück",
    "validFrom": "2026-09-14",
    "validTo": "2026-09-19",
    "url": "https://www.netto-online.de/lebensmittel/c-N01#store-448684",
    "scrapedAt": "2026-09-16T10:00:00.000Z"
}
```

### How many results to expect

- A keyword search returns the full netto-online.de result list. `kaffee` returned 1,256 online products, `milch` 34 and `waschmittel` 18 (checked 11 Oct 2026). Set `maxResults` to what you need, the scraper stops there.
- The online shop sells mostly multipacks, drinks, household and non-food. Fresh groceries (bread, eggs, dairy) mostly appear as `store` offers, so keep `includeStoreOffers` on for those.
- A term with no match on netto-online.de ends the run as FAILED with a message naming the term. Nothing is charged for a failed run.

### Cost

Pay per result: $0.002 per item plus $0.005 per GB of memory at run start (4 GB by default, so $0.02). The full `kaffee` run of 1,256 products cost about $2.53 in result charges. One online product is one detail-page request; store offers are read from the listing page and cost no extra request. Runs use residential proxy by default because netto-online.de sits behind Akamai and blocks datacenter IPs. Platform usage for a run only settles after the run has SUCCEEDED; read the cost after the run finishes, a run that is still going shows a partial figure.

### Notes

- German discount supermarket (netto-online.de). Prices in EUR, text in German.
- Price per unit is only available on store offers.
- JSON-LD is the primary data source for online products; store offers come from the listing markup.
- `inStock` is only set when the site states availability. Absent means unknown, never "out of stock".

### Why use Netto Marken-Discount Scraper

- **Price monitoring**: track prices, stock, and weekly promotions across Netto Marken-Discount at scale
- **Competitive intelligence**: compare your catalog against Netto pricing and assortment
- **Market research**: analyze category trends and new arrivals
- **Data products**: build product datasets for comparison tools, affiliate sites or feeds
- **No login or cookies required**: works out of the box

### How to use Netto Marken-Discount Scraper

1. Open the **Input** tab and provide a search query or a category URL
2. Set `maxResults` and, if you only want online-shop products, switch off `includeStoreOffers`
3. Click **Start** and wait for the run to complete
4. Download results from the **Output** tab in JSON, CSV, Excel, XML, or HTML
5. Schedule recurring runs from the **Schedule** tab if you need ongoing data

### How to scrape Netto Marken-Discount data

This Actor extracts structured product data from netto-online.de. You can run it from the Apify console, the Apify API, or the official SDKs (JavaScript, Python). The scraper handles pagination, retries, and rate limiting.

Typical workflows:

- **One-off export**: paste a category URL or keyword, set `maxResults`, and run
- **Scheduled monitoring**: set a daily cron in the Schedule tab to track prices over time
- **Programmatic integration**: trigger runs from your backend via the Apify API and pull the dataset when finished
- **Webhook automation**: receive a callback the moment a run completes and pipe the results into Zapier, Make, n8n, BigQuery, or Google Sheets

#### Example: API call

```bash
curl -X POST "https://api.apify.com/v2/acts/studio-amba~netto-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQuery": "waschmittel", "maxResults": 200}'
```

#### Example: Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("studio-amba/netto-scraper").call(run_input={
    "categoryUrl": "https://www.netto-online.de/angebote/c-N07",
    "maxResults": 300,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["channel"], item["name"], item["price"])
```

### Tips for best results

- **Start small**: run with `maxResults: 20` before launching large jobs
- **Use German keywords**: the site search is German (`kaffee`, not `coffee`)
- **Category URLs**: any `https://www.netto-online.de/<slug>/c-N<id>` page works, including the offer categories `angebote/c-N07`, `online-wochenangebote/c-N0794` and `lebensmittel-angebote/c-N07941`
- **Store offers page**: `https://www.netto-online.de/filialangebote` is a store picker with no product markup. The scraper redirects it to the offers category; store offers are also included on every category page.
- **Schedule runs**: store offers change weekly (Monday), online prices more often

### FAQ and support

**Is it legal to scrape Netto Marken-Discount?** This Actor extracts publicly available data. Review the website's Terms of Service before scraping at scale, and respect rate limits.

**Why is `brand` empty on some items?** Store offer tiles do not carry a brand field. Online products have it from the product page.

**Why did my run fail with "Zero results"?** The search term matched nothing on netto-online.de, or every request was blocked. Try a broader German keyword or a category URL. A failed run is not charged.

**Can I extract a single product?** Search for its exact name (e.g. `"Dallmayr Classic Mild 500 g"`) with `maxResults: 1`.

**The site blocks me, what should I do?** Keep the default residential proxy (Germany). Datacenter IPs are blocked by Akamai on this site.

For issues, feature requests, or bug reports, open a ticket in the Issues tab on the Actor page. We monitor every actor and ship fixes when the site changes.

# Actor input Schema

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

Search for products by keyword (e.g., 'kaffee', 'waschmittel', 'nudeln'). Returns every online-shop product matching the term (netto-online.de search, paginated), plus the in-store weekly offers matching it when 'Include in-store offers' is on.

## `categoryUrl` (type: `string`):

A Netto category page URL to scrape, e.g. https://www.netto-online.de/lebensmittel/c-N01 or https://www.netto-online.de/angebote/c-N07. Pagination is followed. If empty and no search query, scrapes featured products from the homepage.

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

Maximum number of items to return (online products and in-store offers combined). Hard cap: 50000. Each online product costs one detail-page request; in-store offers are read from the listing page.

## `includeStoreOffers` (type: `boolean`):

Also return the in-store weekly offers ('Filiale' tiles) that appear on search and category pages. These have channel = 'store', a validity window and no product page. Off = online-shop products only.

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

Proxy settings. netto-online.de sits behind Akamai; German residential IPs pass most reliably (Danish IPs were measured at ~25% 403s).

## Actor input object example

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

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

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

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/netto-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 '{
  "searchQuery": "kaffee",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}' |
apify call studio-amba/netto-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/netto-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/PBgltr6UAadgfkf8D/builds/diArtwNZAyUoUeUKm/openapi.json
