# PLUS Scraper — Dutch Supermarket Prices & Products (`studio-amba/plus-nl-scraper`) Actor

Scrape products, prices, brands, EAN barcodes and categories from PLUS supermarket (plus.nl), the Netherlands' #3 grocery chain. Search by keyword. No login or cookies required.

- **URL**: https://apify.com/studio-amba/plus-nl-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 0.0% 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/actors/running/actors-in-store.md#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

## PLUS Scraper — Dutch Supermarket Prices & Products

Scrape product data from **PLUS** ([plus.nl](https://www.plus.nl)), the Netherlands' third-largest supermarket chain by market share. Search the PLUS assortment by keyword and get clean, structured JSON with names, prices, brands, EAN barcodes and full category paths.

No login. No cookies. Just give it a search term and it returns the matching products.

### What this Actor does

This Actor searches PLUS's own website search and returns every matching product with its current shelf price and category data. It is built for price monitoring, assortment research, competitive analysis against Albert Heijn and Jumbo, and building Dutch grocery price datasets.

For each product you get:

- **Name** — full product title (e.g. "Zuivelmeester Halfvolle melk")
- **Brand** — the product brand (e.g. "Arla", "Zuivelmeester", or "PLUS" for private label)
- **Price** — current shelf price in euros
- **Price per unit** — normalized price per litre or kilo, where the site publishes a reference quantity
- **Category** — the full PLUS category breadcrumb (e.g. "Zuivel, eieren, boter > Verse zuivel > Melk, karnemelk")
- **EAN** — the product barcode / GTIN
- **SKU** — PLUS's internal product code
- **In stock** — whether the product is currently available
- **Image URL** — product image
- **URL** — link to the product page on plus.nl
- **Scraped at** — ISO timestamp of the run

### How to scrape PLUS supermarket data

1. Open this Actor in Apify Console (or call it via the Apify API).
2. Set a **Search Query** — a Dutch keyword such as `melk`, `brood`, `koffie`, `kaas` or a brand name.
3. Set **Max Results** — how many products you want back (default 50).
4. Leave the **Proxy Configuration** on the default. PLUS.nl sits behind an Imperva/Incapsula CDN and serves Dutch-only pricing and availability, so a Netherlands residential proxy is prefilled.
5. Click **Start**. The Actor loads the search results, scrolls PLUS's product list to page through matches, then visits each product page for the full record.
6. Download the results as JSON, CSV, Excel or feed them straight into your own pipeline via the API.

That is the whole flow. One keyword in, a clean product dataset out.

#### Example input

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

#### Example output

```json
{
    "name": "Zuivelmeester Halfvolle melk",
    "brand": "Zuivelmeester",
    "price": 1.69,
    "currency": "EUR",
    "pricePerUnit": "0.84 EUR/L",
    "ean": "8718989028404",
    "sku": "145701",
    "inStock": true,
    "imageUrl": "https://images.ctfassets.net/s0lodsnpsezb/145701_M/ccbe3a44d38520fe2645e71f8a0e12b8/145701.png",
    "category": "Zuivel, eieren, boter > Verse zuivel > Melk, karnemelk",
    "categories": ["Zuivel, eieren, boter", "Verse zuivel", "Melk, karnemelk"],
    "url": "https://www.plus.nl/product/zuivelmeester-halfvolle-melk-can-2000-ml-145701",
    "scrapedAt": "2026-09-12T19:46:41.827Z"
}
```

### Input reference

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `searchQuery` | string | no | Dutch keyword or brand to search for. Defaults to `brood`. |
| `maxResults` | integer | no | Maximum number of products to return. Default 50. |
| `proxyConfiguration` | object | no | Proxy settings. Defaults to Apify residential proxy in the Netherlands. |

### Output reference

Each dataset item is a single product. Fields:

| Field | Type | Description |
| --- | --- | --- |
| `name` | string | Full product title |
| `brand` | string | Product brand |
| `price` | number/null | Current price in euros |
| `currency` | string | Always `EUR` |
| `pricePerUnit` | string/null | Normalized price per litre or kilo, when available |
| `ean` | string/null | Barcode / GTIN-13 |
| `sku` | string/null | PLUS internal product code |
| `category` | string/null | Full category breadcrumb, joined with " > " |
| `categories` | array/null | Category breadcrumb as a list, top level first |
| `imageUrl` | string/null | Product image URL |
| `inStock` | boolean/null | Availability |
| `url` | string | Product page URL |
| `scrapedAt` | string | ISO timestamp |

### Why a Netherlands residential proxy is used

plus.nl runs behind an Imperva/Incapsula CDN and its prices and product availability are scoped to the Dutch market. The default proxy configuration uses Apify's residential proxy pool scoped to the Netherlands. You normally do not need to change it.

### Common use cases

- **Price monitoring** — track PLUS prices for a basket of products over time.
- **Competitive analysis** — compare PLUS against Albert Heijn, Jumbo and other Dutch supermarkets.
- **Assortment research** — see how many products PLUS lists for a category or brand.
- **Dataset building** — collect grocery names, EANs and prices for analytics or ML.

### Cost estimate

This actor is billed $0.02 per run plus $0.002 per result — **1,000 results cost about $2.02**. Usage cost only settles once a run reports **SUCCEEDED** — reading a dataset mid-run will show a cost far below the real total.

### Notes and limits

- Search is keyword-based, one keyword per run. Run the Actor multiple times for multiple keywords.
- Prices are scraped live at run time and reflect PLUS's national webshop pricing, not local store promotions.
- `pricePerUnit` is only populated when PLUS publishes a machine-readable reference quantity (common for liquids and weighed goods, less common for piece-counted items).
- The Actor only reads public catalog data. It does not log in or access any account.
- If a run returns zero items it fails on purpose, so you never get a silent empty dataset.

### Related scrapers

- **Albert Heijn Scraper** — the largest Dutch supermarket chain.
- **Jumbo Scraper** — the second-largest Dutch supermarket chain.

### Frequently asked questions

#### Do I need a PLUS account?

No. The Actor reads the public product catalog. No login, no cookies.

#### Can I scrape a whole category instead of searching?

This version is keyword-based. Use a broad keyword or a brand name to pull a large slice of a category — PLUS's own search matches across name, brand and category text.

#### Why do I get fewer items than `maxResults`?

A search only has so many matching products. The Actor stops when PLUS runs out of matches for your keyword.

#### Is the price in euros or cents?

Euros, as published by PLUS. Prices are read directly from the product page's structured pricing data.

# Actor input Schema

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

Search for products by name or keyword (e.g. 'melk', 'brood', 'koffie'). One search per run.

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

Maximum number of products to return.

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

Proxy settings. PLUS.nl shows Dutch prices/availability and sits behind an Imperva CDN, so a Netherlands residential proxy is used by default.

## Actor input object example

```json
{
  "searchQuery": "brood",
  "maxResults": 15,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NL"
  }
}
```

# 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": "brood",
    "maxResults": 15,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "NL"
    }
};

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

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

```

## MCP server setup

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