# Spar.si Scraper — SPAR Slovenia Grocery Products (`studio-amba/spar-si-scraper`) Actor

Scrape grocery products from online.spar.si, SPAR Slovenia's webshop. Get product names, brands, prices (incl. promo prices), units, categories, EAN codes and images by search keyword. No login required.

- **URL**: https://apify.com/studio-amba/spar-si-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 $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/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

## Spar.si Scraper

Extract **grocery products from [online.spar.si](https://online.spar.si/)**, the webshop of SPAR Slovenia. Search by keyword and get product names, brands, prices (including active promo prices), package units, categories, EAN barcodes and images — all in structured, ready-to-use data.

This Actor pulls data directly from the site's server-rendered search results. No login, no session, no browser automation, and it never touches SPAR's underlying GraphQL API. It reads the same product data the page itself renders on the server, so runs are fast and stable.

### What does Spar.si Scraper do?

Give it a Slovenian keyword (for example `mleko`, `kruh`, `jogurt`, or `kava`) and the Actor pages through online.spar.si's search results, extracting the full product listing for every match: name, brand, current price, original price when discounted, unit price, category, SKU, EAN codes, image, product URL and availability.

Because it runs on the Apify platform, you also get scheduling, monitoring, proxy rotation, and integrations (webhooks, Make, Zapier, Google Sheets) out of the box.

### Why use Spar.si Scraper?

- **Price monitoring.** Track SPAR Slovenia prices and active promotions over time.
- **Market research.** Compare product ranges and pricing against other Slovenian grocery retailers.
- **Assortment tracking.** See which brands and products are listed under a given category or keyword.
- **Barcode/EAN mapping.** Pull EAN codes alongside SPAR's internal SKU for catalogue matching.
- **No anti-bot headaches.** The search page is plain server-rendered HTML — no CAPTCHAs, no browser fingerprinting to work around.

### How to scrape Spar.si data

1. Open the Actor and go to the **Input** tab.
2. Enter a **Search Query** in Slovenian (e.g., `mleko`, `kruh`, `sir`, `jogurt`, `kava`).
3. Set **Max Results** to control how many products you want (the site serves 50 products per results page).
4. Click **Start**. When the run finishes, open the **Output** tab and download your data as JSON, CSV, Excel, or HTML.
5. To track prices over time, schedule the Actor to run daily or weekly and compare exports.

That's it — no account, no API key, no store selection needed.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `searchQuery` | string | Slovenian search keyword. Defaults to `mleko` if left empty. |
| `maxResults` | integer | Maximum number of products to return. Default `100`. |
| `proxyConfiguration` | object | Apify Proxy settings. Datacenter proxies work fine — the search page has no anti-bot protection. |

Example input:

```json
{
  "searchQuery": "mleko",
  "maxResults": 20,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output

Each item in the dataset looks like this:

```json
{
  "productName": "MLEKO 3,5% M.M., POMURSKO MLEJKO, 200ML",
  "brand": "Pomurske Mlekarne",
  "price": 0.65,
  "currency": "EUR",
  "unitPrice": 3.25,
  "unitPriceUnit": "KG",
  "category": "TRAJNO MLEKO",
  "sku": "413677",
  "ean": ["3831040002283", "3831040002306"],
  "imageUrl": "https://cdn1.interspar.at/cachableservlets/articleImage.dam/si/413677/dt_zoom.jpg",
  "url": "https://online.spar.si/p/mleko-35-mm-pomursko-mlejko-200ml-413677",
  "isAvailable": true,
  "scrapedAt": "2026-07-13T00:10:00.000Z"
}
```

| Field | Description |
| --- | --- |
| `productName` | Full product name as listed on the site |
| `brand` | Brand name, when provided |
| `price` | Current selling price — the active promo price if the product is discounted |
| `priceBeforeDiscount` | Original price, only present when a promotion is active |
| `currency` | Always `EUR` |
| `unitPrice` | Price per `unitPriceUnit` (e.g. per KG or per L) |
| `unitPriceUnit` | Unit the unit price is expressed in |
| `category` | Most specific product category on the site |
| `sku` | SPAR/Instaleap internal product code |
| `ean` | EAN/barcode(s), when present |
| `imageUrl` | Main product photo URL |
| `url` | Direct product page link |
| `isAvailable` | Whether the product is currently orderable |
| `scrapedAt` | ISO 8601 timestamp of when the item was collected |

### How it works

`online.spar.si` is a Next.js storefront running on the Instaleap e-grocery platform. The client app talks to a GraphQL endpoint for live search-as-you-type and cart operations, but the initial search results page is fully server-rendered: Next.js embeds the complete product list — price, brand, SKU, EAN, categories, stock — inside the page's React Server Component "flight" payload (the `self.__next_f.push(...)` script chunks used for client hydration).

This Actor fetches `https://online.spar.si/search?name={query}&currentPage={n}` with a plain HTTP GET, reassembles the flight payload, and extracts every embedded product object directly — no GraphQL call, no API key, no session cookie required. This is both simpler and more stable than reversing the GraphQL schema, since the site's own SSR step already assembled exactly the data this Actor needs.

### Is it legal to scrape Spar.si?

This Actor only collects publicly available product listing data (names, prices, categories) that anyone can see by browsing online.spar.si. It doesn't access any account data, doesn't bypass paywalls or logins, and doesn't collect personal information. Always check the target site's terms of service and applicable law (e.g. GDPR if you plan to process personal data) before scraping, and use the data responsibly.

### Tips

- Slovenian keywords return the most results — try `mleko`, `kruh`, `sir`, `jajca`, `kava`, `čokolada`.
- A broader keyword returns more pages; a narrow one is faster if you only need a specific product line.
- Promotions are time-boxed — re-run periodically if you're tracking price changes, since `priceBeforeDiscount` only appears while a promo is active.

### Support

Found a product field missing or a page that doesn't scrape correctly? Open an issue on the Actor's Apify Store page and we'll take a look.

# Actor input Schema

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

Keyword to search for on online.spar.si, in Slovenian. Examples: 'mleko' (milk), 'kruh' (bread), 'jogurt' (yoghurt), 'kava' (coffee).

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

Maximum number of products to return. The site serves 50 products per page.

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

Proxy settings. The search page is open, server-rendered HTML and works well through Apify datacenter proxies.

## Actor input object example

```json
{
  "searchQuery": "mleko",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "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 = {
    "searchQuery": "mleko",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

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

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

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/ZN2dfE6fitKHVeq8X/builds/3voTPF7DWTas2gbys/openapi.json
