# Selver Scraper — Estonian Grocery Prices, EAN & Nutrition (`studio-amba/selver-ee-scraper`) Actor

Scrape the full e-Selver catalogue from selver.ee, Estonia's grocery chain. Get names, brands, EUR prices, was-prices, EAN, pack size, origin, ingredients, allergens and nutrition values.

- **URL**: https://apify.com/studio-amba/selver-ee-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.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?

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

## Selver Scraper

Pull product data from selver.ee, the online shop (e-Selver) of the Estonian grocery chain Selver. The actor returns names, brands, shelf prices, was-prices, comparison prices, EAN barcodes, pack sizes, country of origin, ingredients, allergens and nutrition values for the whole catalogue or for the categories you pick.

Selver sells food, drinks, household goods, cosmetics and a small non-food range, so one record shape covers all of those departments.

### How to scrape Selver data

There are three ways to run the actor. They can be combined.

#### Option 1: Whole catalogue

Leave `searchQuery` and `categoryUrls` empty and set `maxResults` to 20000. The catalogue holds about 11,900 products, so a full run returns all of them.

#### Option 2: Search by product name

Set `searchQuery` to a word from the product name, in Estonian, for example `piim` (milk), `leib` (bread), `juust` (cheese), `kohv` (coffee) or `munad` (eggs). Several words must all appear in the name. The match is on part of a word, so `piim` also finds `kohupiim`.

#### Option 3: Category pages

Paste Selver category URLs into `categoryUrls`, for example `https://www.selver.ee/piimatooted-munad-void`. A parent category includes all of its subcategories. To find a URL, open a category on selver.ee and copy the address from the browser.

Selver blocks plain requests. The actor sends every request through Bright Data Web Unlocker, so you do not need your own proxy or browser setup. It reads the shop's own product catalogue service, 100 products per request, which keeps the cost per product low.

### Input

| Field | Type | Description |
|---|---|---|
| `searchQuery` | text | Word from the product name, in Estonian |
| `categoryUrls` | list of URLs | Category pages from selver.ee |
| `language` | `et` or `ru` | Language of names and descriptions (default `et`) |
| `maxResults` | number | Maximum number of products across all categories (default 100) |
| `brightDataApiKey` | text | Optional. Falls back to the actor's own key when empty |

### What you get back

| Field | Description |
|---|---|
| `name` | Full product name |
| `brand` | Brand label |
| `manufacturer` | Manufacturer label |
| `price` | Shelf price in EUR including VAT |
| `currency` | Always `EUR` |
| `originalPrice` | Regular price, only present when the price is reduced |
| `discount` | Markdown percentage, for example `-20%` |
| `unitPrice` | Comparison price in EUR as Selver shows it (per kg, litre or piece) |
| `packSize` | Pack size, for example `500 g` |
| `ean` | Main EAN barcode |
| `sku`, `productId` | Selver identifiers |
| `countryOfOrigin` | Country of origin |
| `category`, `categoryPath`, `categoryUrl` | Deepest category, the full path and its page |
| `imageUrl` | Main product image |
| `description` | Short product description |
| `ingredients`, `allergens` | Ingredient list and allergen text |
| `nutrition` | Values per 100 g where listed: energy, fat, saturatedFat, carbohydrates, sugars, protein, salt |
| `ageRestricted` | True for age-restricted products such as alcohol |
| `country`, `language` | `ee` and `et` or `ru` |
| `url` | Product page URL |
| `scrapedAt` | ISO 8601 timestamp |

`originalPrice` and `discount` are absent on products that are not reduced. `nutrition`, `ingredients` and `allergens` are absent on products without that information, such as household goods. Both are correct and not missing data.

### Sample output

```json
{
  "name": "Kohupiimakreem mustika, ALMA, 300 g",
  "brand": "ALMA",
  "manufacturer": "VALIO EESTI AS",
  "price": 1.51,
  "currency": "EUR",
  "unitPrice": 5.03,
  "packSize": "300 g",
  "ean": "4740125612110",
  "countryOfOrigin": "Eesti",
  "category": "Kohupiimad, kodujuustud",
  "categoryPath": "Piimatooted, munad, võid > Kohupiimad, kodujuustud",
  "country": "ee",
  "url": "https://www.selver.ee/kohupiimakreem-mustika-alma-300-g",
  "scrapedAt": "2026-10-22T19:42:24.154Z"
}
```

### Use cases

- Price monitoring of Estonian groceries against Rimi, Barbora and Prisma.
- Matching products across shops through the EAN barcode.
- Tracking brand and assortment changes over time.
- Building a nutrition and allergen database for Estonian food products.
- Supplier and FMCG research on pack sizes, origin and shelf prices.

### Coverage

The actor works on the full e-Selver catalogue. Category URLs include their subcategories. A product listed in several categories is returned once.

Selver's catalogue service does not carry a usable stock flag, so the output has no `inStock` field. Prices are the online shop prices. Loyalty-card prices and store-specific prices are not included.

### Performance and cost

Each request returns up to 100 products, so the Bright Data cost per product is a small fraction of a cent. A run of 273 products cost about $0.006 in platform usage (under $0.00003 per product) and finished in under a minute. The usage cost of a run only settles after the run reports SUCCEEDED, so a cost checked during the run is too low.

### Limitations

- Search matches words in the product name only, not in descriptions or brands.
- Only the regular shelf price and the current markdown are returned.
- If Selver changes its catalogue service, the actor needs an update. The run logs a warning when fewer than 80% of the products on a page can be read.
- A search or category URL without matches ends the run as SUCCEEDED with zero items and a message in the status line.

### Related scrapers

- [Rimi Estonia Scraper](https://apify.com/studio-amba/rimi-ee-scraper) for Rimi grocery prices in Estonia
- [Barbora Estonia Scraper](https://apify.com/studio-amba/barbora-ee-scraper) for Barbora grocery prices in Estonia
- [Prisma Scraper](https://apify.com/studio-amba/prisma-scraper) for Prisma grocery prices

### Support

If a category does not resolve or a field is empty, open an issue on this actor's Apify Store page.

# Actor input Schema

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

Product name word to look for, in Estonian, e.g. "piim" (milk), "leib" (bread), "juust" (cheese). Several words must all appear in the product name. Leave empty to scrape without a search filter.

## `categoryUrls` (type: `array`):

Selver category pages, e.g. "https://www.selver.ee/piimatooted-munad-void". A parent category includes all of its subcategories. Leave empty to scrape the whole catalogue (about 11,900 products).

## `language` (type: `string`):

Language of product names and descriptions.

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

Maximum number of products to scrape across all categories. One request returns 100 products.

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

Not used. This actor reaches Selver through Bright Data Web Unlocker, which handles unblocking on its own. Kept for input-shape compatibility.

## `brightDataZone` (type: `string`):

Name of the Web Unlocker zone in your Bright Data account. Only needed together with your own Bright Data API key. Leave empty to use the actor's own zone.

## `brightDataApiKey` (type: `string`):

Bright Data API key (Web Unlocker zone) used to reach Selver, which blocks plain requests. Falls back to the actor's own BRIGHT_DATA_API_KEY environment variable if left empty.

## Actor input object example

```json
{
  "searchQuery": "piim",
  "language": "et",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "brightDataZone": "web_unlocker1"
}
```

# 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": "piim",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/selver-ee-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": "piim",
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/selver-ee-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": "piim",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call studio-amba/selver-ee-scraper --silent --output-dataset

```

## MCP server setup

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