# Magasin.dk Scraper — Magasin du Nord Product Prices (`studio-amba/magasin-dk-scraper`) Actor

Scrape product data from magasin.dk, Magasin du Nord, Denmark's largest department store chain. Extract names, brands, prices, stock status, categories and images via the store's own search and category pages.

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

## Magasin.dk Scraper

Pull product data from magasin.dk, the webshop of Magasin du Nord -- Denmark's largest department store chain, founded in 1868 with its flagship on Kongens Nytorv in Copenhagen. 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 Magasin du Nord data

Give the actor a Danish search term, or a magasin.dk 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, magasin.dk runs on Salesforce Commerce Cloud (the same platform family as Picard, Torfs and several other actors in this fleet). The site's own backend search endpoint (`Search-Show`) sits behind a Cloudflare JavaScript challenge and can't be hit directly. This actor routes around that the same way a real visitor's browser does: the plain storefront page itself -- both the search results page and any category page -- accepts a `?page=N` parameter and returns a full, server-rendered page of the next 36 products. No challenge, no browser needed.

Each product tile on the page carries a small JSON blob (used by the site's own analytics) with name, brand, price, SKU, category and stock status already structured -- this actor reads that directly instead of guessing at CSS selectors for visible text, so prices and IDs come back exact, not parsed from formatted text.

If you don't provide any input, it defaults to searching for `"sko"` (Danish for "shoes") as a demo.

#### Search mode vs. category mode

- **Search mode** (default): set `searchQuery` to any Danish search term. The actor searches magasin.dk the way a shopper would, e.g. `"kjole"` (dress), `"taske"` (bag), `"sengetøj"` (bedding).
- **Category mode**: set `categoryUrl` to a magasin.dk category page URL, e.g. `https://www.magasin.dk/dame/sko/sneakers/`, to pull every product in that specific department instead of running a keyword search. When both are set, `categoryUrl` takes priority.

#### A note on discounts

Magasin du Nord runs a loyalty program ("Goodie") that shows members a lower price on many items alongside the public price -- that member-only price is not the same as a public markdown. This actor's `originalPrice` field only reflects a genuine public "was" price (a real strike-through), never the loyalty member price, so you don't mistake a loyalty discount for an actual sale.

### Input

| Field | Type | Description |
|-------|------|-------------|
| `searchQuery` | string | Search term, in Danish (e.g. `"sko"`, `"taske"`, `"kjole"`). Ignored if `categoryUrl` is set. |
| `categoryUrl` | string | Optional magasin.dk category page URL to scrape instead of a search, e.g. `https://www.magasin.dk/dame/sko/sneakers/` |
| `maxResults` | integer | Cap on number of products returned (default: 100, max: 5000) |
| `proxyConfiguration` | object | Apify proxy settings. magasin.dk's storefront page routes have no anti-bot challenge -- automatic Apify proxy is used by default, no residential proxy needed |

### What you get back

| Field | Type | Example |
|-------|------|---------|
| `name` | string | `"Gel-nyc 2. 0"` |
| `brand` | string | `"Asics"` |
| `price` | number | null | `1300` |
| `originalPrice` | number | null | `null` (only set on a genuine public markdown, never a loyalty member price) |
| `currency` | string | `"DKK"` |
| `sku` | string | null | `"BRCE83-00PX"` (variant-level: style + colour) |
| `productId` | string | `"BRCE83"` (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 | `"sneakers"` |
| `categories` | array | Full category breadcrumb, e.g. `["womens", "shoes", "sneakers"]` |
| `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 | `"magasin.dk"` |
| `scrapedAt` | string | ISO timestamp |

### Sample output

```json
{
  "name": "Gel-nyc 2. 0",
  "brand": "Asics",
  "price": 1300,
  "currency": "DKK",
  "originalPrice": null,
  "sku": "BRCE83-00PX",
  "productId": "BRCE83",
  "inStock": true,
  "url": "https://www.magasin.dk/gel-nyc-2.-0/BRCE83-00PX.html",
  "imageUrl": "https://www.magasin.dk/dw/image/v2/BFCS_PRD/on/demandware.static/-/Sites-mdn-master-catalog/default/dwe1394835/large2/AA/4573690011688.jpg?sw=300&sfrm=jpg",
  "imageUrls": ["https://www.magasin.dk/dw/image/v2/BFCS_PRD/on/demandware.static/-/Sites-mdn-master-catalog/default/dwe1394835/large2/AA/4573690011688.jpg?sw=300&sfrm=jpg"],
  "category": "sneakers",
  "categories": ["womens", "shoes", "sneakers"],
  "searchQuery": null,
  "categoryUrl": "https://www.magasin.dk/dame/sko/sneakers/",
  "source": "magasin.dk",
  "scrapedAt": "2026-09-11T09:12:47.866Z"
}
```

### Use cases

- **Price monitoring** -- track Magasin du Nord's price changes over time across fashion, home and beauty, including "was" price whenever an item is genuinely discounted.
- **Assortment research** -- see what brands and categories Denmark'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.
- **Danish/Nordic market comparison** -- compare Magasin du Nord against other Nordic department stores and fashion retailers already covered in this fleet.

### Coverage

v1 covers magasin.dk's Danish storefront (DKK pricing). Sibling storefronts exist for Norway (`Sites-NO-Site`) and Sweden (`Sites-SE-Site`) but are not covered by this actor.

### 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 magasin.dk's own on-site search and category browsing. It does not accept direct product URLs.
- `ean` and product-level `color` are not included -- magasin.dk leaves both empty on every listing tile sampled during development, so they were left out rather than shipped as always-empty fields.
- `originalPrice` reflects only a genuine public markdown. It is never set from the store's loyalty member price ("Goodie"), even when that price is lower.
- v1 targets the Danish storefront (DKK) only.

### Related scrapers

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

- [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
- [Liberty London Scraper](https://apify.com/studio-amba/libertylondon-scraper) -- UK 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 magasin.dk, in Danish (e.g. "sko" for shoes, "taske" for bag, "kjole" for dress)

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

Optional: a magasin.dk category page URL to scrape instead of a search (e.g. https://www.magasin.dk/dame/sko/sneakers/). When set, this takes priority over searchQuery.

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

Maximum number of products to scrape. Results are paginated 36 at a time from the store's own search/category pages.

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

Apify proxy configuration. magasin.dk 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": "sko",
  "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": "sko",
    "maxResults": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

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

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

```

## MCP server setup

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