# Stockmann Scraper — Finland Department Store Prices (`studio-amba/stockmann-scraper`) Actor

Scrape product data from stockmann.com, Finland's largest department store chain. Extract names, brands, prices, stock status, categories and images via the store's own search and category pages, in EUR.

- **URL**: https://apify.com/studio-amba/stockmann-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?

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

## Stockmann Scraper

Pull product data from stockmann.com, Finland's largest and only major department-store chain, founded in 1862 with its flagship on Aleksanterinkatu in Helsinki. This scraper reads the store's own search and category pages directly, so it returns clean, structured data -- brand, price, stock, category, images -- without a browser or a login.

### How to scrape Stockmann data

Give the actor a Finnish search term, or a stockmann.com category URL, and it pulls product listings the same way the store's own visitors browse it. There's nothing else to configure -- no session cookies, no login, no API key.

Under the hood, stockmann.com runs on Salesforce Commerce Cloud (the same platform family as magasin.dk, illum.dk and Ahlens in this fleet). The site is fronted by Cloudflare, but the storefront page routes themselves -- both the search results page and any category page -- are not challenged: a plain request gets a full, server-rendered page back with the next batch of products, no browser needed. The backend `Search-Show` pipeline endpoint even redirects straight back to that plain page itself.

Each product tile on the page carries a small JSON blob (used by the site's own analytics) with name, brand, current price, stock status and category already structured -- this actor reads that directly instead of guessing at CSS selectors for visible text, so names and IDs come back exact, not parsed from formatted text. The pre-discount "was" price is not in that JSON -- it only appears in the rendered price block on tiles that carry a sale label, so this actor reads that separately and only sets `originalPrice` when a genuine markdown is present.

If you don't provide any input, it defaults to searching for `"mekko"` (Finnish for "dress") as a demo.

#### Search mode vs. category mode

- **Search mode** (default): set `searchQuery` to any Finnish search term. The actor searches stockmann.com the way a shopper would, e.g. `"laukku"` (bag), `"kengät"` (shoes), `"neule"` (knitwear).
- **Category mode**: set `categoryUrl` to a stockmann.com category page path or full URL, e.g. `/muoti/naiset` (women's fashion), `/muoti/miehet` (men's fashion), `/koti` (home) or `/kosmetiikka` (beauty), to pull every product in that department instead of running a keyword search. Filter/sort query params already on the URL (e.g. `?prefn1=availableDiscounts&prefv1=sale` for sale-only) are preserved. When both `searchQuery` and `categoryUrl` are set, `categoryUrl` takes priority.

#### Locale

stockmann.com is a single Finnish-language storefront -- there is no separate Swedish or English path, even though Finland is officially bilingual. All output is in Finnish category/product names, priced in EUR.

### Input

| Field | Type | Description |
|-------|------|-------------|
| `searchQuery` | string | Search term, in Finnish (e.g. `"mekko"`, `"laukku"`, `"kengät"`). Ignored if `categoryUrl` is set. |
| `categoryUrl` | string | Optional stockmann.com category page path or URL to scrape instead of a search, e.g. `/muoti/naiset` or `https://www.stockmann.com/koti` |
| `maxResults` | integer | Cap on number of products returned (default: 100, max: 5000) |
| `proxyConfiguration` | object | Apify proxy settings. stockmann.com's storefront page routes have no anti-bot challenge tested -- automatic Apify proxy is used by default, no residential proxy needed |

### What you get back

| Field | Type | Example |
|-------|------|---------|
| `name` | string | `"Mekko"` |
| `brand` | string | `"Emporio Armani"` |
| `price` | number | null | `191.6` |
| `originalPrice` | number | null | `489` (only set on a genuine markdown -- null otherwise) |
| `currency` | string | `"EUR"` |
| `sku` | string | null | `"17467058459-1"` (variant-level: style + colour/size) |
| `productId` | string | `"17467058459"` (style-level, shared across colour/size variants) |
| `inStock` | boolean | null | `true` (null only if the source gives no stock signal) |
| `url` | string | Full product page URL |
| `imageUrl` | string | null | Primary product image |
| `imageUrls` | array | Product image URLs |
| `category` | string | null | `"arkimekot"` |
| `categories` | array | Full category breadcrumb, e.g. `["muoti", "naiset", "vaatteet", "mekot", "arkimekot"]` |
| `searchQuery` | string | null | The search term used to find this product (null in category mode) |
| `categoryUrl` | string | null | The category URL used to find this product (null in search mode) |
| `source` | string | `"stockmann.com"` |
| `scrapedAt` | string | ISO timestamp |

### Sample output

```json
{
  "name": "Mekko",
  "brand": "Emporio Armani",
  "price": 191.6,
  "currency": "EUR",
  "originalPrice": null,
  "sku": "17467058459-1",
  "productId": "17467058459",
  "inStock": true,
  "url": "https://www.stockmann.com/emporio-armani-mekko/17467058459-1.html",
  "imageUrl": "https://images.stockmann.com/products/e62757481b146091ee9dd84e42432375c09941d5/225x300/8059797920437.jpg",
  "imageUrls": ["https://images.stockmann.com/products/e62757481b146091ee9dd84e42432375c09941d5/225x300/8059797920437.jpg"],
  "category": "arkimekot",
  "categories": ["muoti", "naiset", "vaatteet", "mekot", "arkimekot"],
  "searchQuery": "mekko",
  "categoryUrl": null,
  "source": "stockmann.com",
  "scrapedAt": "2026-09-11T14:15:24.127Z"
}
```

### Use cases

- **Price monitoring** -- track Stockmann's price changes over time across fashion, home and beauty, including "was" price whenever an item is genuinely on sale.
- **Assortment research** -- see what brands and categories Finland's largest department store carries, and at what price points.
- **Stock and availability tracking** -- `inStock` gives a live read on which items are selling through.
- **Nordic market comparison** -- compare Stockmann against other Nordic department stores already covered in this fleet: magasin.dk and illum.dk in Denmark, Ahlens in Sweden.

### Coverage

v1 covers stockmann.com's single Finnish storefront (EUR pricing, `fi_FI` locale). There is no separate Swedish or English site to cover -- verified live, both `/sv` and `/en` paths 404.

### Performance and cost

The scraper hits the store's own storefront pages directly -- no browser rendering, no login, no session warm-up required. A run of 100 products typically completes in well under a minute. This actor charges $0.005 per run (start fee) plus $0.002 per result -- a 100-product run costs about $0.205. Your run's usage cost only settles after the run reports SUCCEEDED -- checking cost mid-run will undercount it.

### Limitations

- Keyword search or category-URL mode only, matching stockmann.com's own on-site search and category browsing. It does not accept direct product URLs.
- `originalPrice` reflects only a genuine on-page markdown, taken from the tile's own "Original Price" label. It is null on every non-sale item.
- v1 targets stockmann.com's single Finnish storefront (EUR) -- there is no other locale to add.

### Related scrapers

If you're covering European department-store and luxury retail more broadly, also check out:

- [Magasin.dk Scraper](https://apify.com/studio-amba/magasin-dk-scraper) -- Danish department store (Magasin du Nord)
- [Illum Scraper](https://apify.com/studio-amba/illum-scraper) -- Danish luxury department store (Copenhagen flagship)
- [Ahlens Scraper](https://apify.com/studio-amba/ahlens-scraper) -- Swedish department store
- [Manor Scraper](https://apify.com/studio-amba/manor-scraper) -- Swiss department store chain
- [Fenwick Scraper](https://apify.com/studio-amba/fenwick-scraper) -- UK luxury department store

### Support

Found an issue or need a specific category covered? Open an issue on this actor's Apify Store page and we'll take a look.

# Actor input Schema

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

Search term to find products on stockmann.com, in Finnish (e.g. "mekko" for dress, "laukku" for bag, "kengät" for shoes)

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

Optional: a stockmann.com category page URL or path to scrape instead of a search (e.g. https://www.stockmann.com/muoti/naiset or /koti). When set, this takes priority over searchQuery.

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

Maximum number of products to scrape. Results are paginated from the store's own search/category pages (36 per page for search, 32 per page for category browsing).

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

Apify proxy configuration. stockmann.com is fronted by Cloudflare but the storefront page routes (search/category) gate nothing tested — automatic proxy is used by default.

## Actor input object example

```json
{
  "searchQuery": "mekko",
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

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

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

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

```

## MCP server setup

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