# Superdrug Scraper - UK Health, Beauty & Pharmacy (`studio-amba/superdrug-scraper`) Actor

Scrape products from Superdrug.com, a major UK health and beauty retailer. Extract names, prices, brands, EAN codes, ratings, reviews and stock. No login, no cookies.

- **URL**: https://apify.com/studio-amba/superdrug-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Features:** Limited permissions
- **Stats:** 5 total users, 2 monthly users, 95.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.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/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

## Superdrug Scraper

Scrape products from [Superdrug.com](https://www.superdrug.com), one of the UK's largest health and beauty retailers with over 700 stores. Search by keyword and pull clean, structured product data: names, prices, brands, EAN barcodes, ratings, review counts, stock levels, categories, and images.

No login. No cookies. No account required.

### What this scraper does

Give it a keyword ("vitamin c", "no7 serum", "paracetamol", "shampoo") and it returns matching Superdrug products as flat JSON rows. Each row is a real product with its current online price, brand, barcode, rating, stock status, and image, ready to load into a spreadsheet, database, or price-monitoring pipeline.

### Why use this scraper?

- **Price monitoring** — Track Superdrug prices for beauty, skincare, vitamins and pharmacy lines over time and catch promotions as they land.
- **Competitive analysis** — Compare Superdrug pricing against Boots, Amazon, and supermarket health aisles on matching EAN codes.
- **Market research** — Analyse assortment, brand coverage, and pricing across makeup, skincare, haircare, fragrance, and wellbeing categories.
- **Retail intelligence** — Monitor stock levels and offer badges (3 for 2, points events) across large product ranges.
- **Catalogue enrichment** — Match products by EAN to enrich your own catalogue with images, ratings, and category data.
- **Brand monitoring** — Track how your brand's products are priced, rated, and merchandised on Superdrug, including marketplace listings.
- **Data journalism & academia** — Build datasets on UK health and beauty retail pricing and consumer ratings.
- **Reselling & arbitrage** — Find discounted lines and price gaps against other UK and EU health and beauty retailers.

### How to scrape Superdrug data

1. **Create an Apify account** — Sign up at [apify.com](https://apify.com) (free tier available).
2. **Open the Superdrug Scraper** — Navigate to this actor's page in the Apify Store.
3. **Enter a search term** — Type a product keyword (e.g., "vitamin c", "mascara", "paracetamol"). The scraper matches it against Superdrug's full product catalogue.
4. **Refine (optional)** — Narrow to a category path (e.g., "make-up/face"), restrict to in-stock items, or paste exact product URLs to scrape specific pages.
5. **Set a result limit** — Choose how many products you want (default: 100).
6. **Run the actor** — Click "Start".
7. **Download your data** — Export as JSON, CSV, or Excel from the Dataset tab, or pull it via the Apify API for automated workflows.

### How it works

Superdrug runs on SAP Commerce Cloud (a Spartacus storefront) behind Akamai bot protection. This scraper enumerates the catalogue from Superdrug's own published XML product sitemaps, filters the product URLs by your search keyword and optional category, then fetches full product detail for each match from Superdrug's product API. Superdrug's sitemaps still list many discontinued products, so the scraper fetches the most recently updated matches first; discontinued products only appear when a search has too few live matches, and they carry `discontinued: true`. Every request is routed through a managed unlocking layer that handles the anti-bot challenge, so you don't need to configure your own browser or residential proxies. The result is clean, structured product data pulled straight from the source that powers the Superdrug website.

Because the data comes from Superdrug's structured product API rather than scraped HTML, fields like price, EAN, rating, review count, and stock level arrive fully typed and consistent.

### Input parameters

| Parameter | Type | Description | Default |
|-----------|------|-------------|---------|
| `searchQuery` | string | Keyword to match against product names and category paths (e.g., "vitamin c", "no7 serum") | `vitamin c` |
| `category` | string | Optional. Limit to a Superdrug category path or slug (e.g., "make-up/face", "health/pain-relief") | — |
| `productUrls` | array | Optional. Scrape these exact product pages (full URLs or bare product codes) instead of searching | — |
| `maxResults` | integer | Maximum products to return (1–5000) | 100 |
| `inStockOnly` | boolean | Only return products currently in stock | `false` |
| `concurrency` | integer | How many product pages to fetch in parallel (1–8) | 5 |
| `requestDelaySecs` | integer | Minimum pause between requests; raise for very large runs | 0 |
| `catalogueCacheHours` | integer | How long a catalogue section read in an earlier run may be reused (0 re-reads it every run) | 24 |
| `proxyConfiguration` | object | Proxy settings (not required; handled automatically) | Apify Residential GB |

### Output fields

| Field | Type | Description | Example |
|-------|------|-------------|---------|
| `name` | string | Full product name | `Seven Seas Cod Liver Oil & Multivitamins 30 Caps` |
| `brand` | string | Brand, from Superdrug's own brand record for the product. Sub-lines are folded into their brand. Empty when Superdrug has no brand on file | `Seven Seas` |
| `subBrand` | string | Product line within the brand (`Elvive` for L'Oreal Paris Elvive). Empty when there is none | `""` |
| `price` | number | Current selling price | `6.75` |
| `discontinued` | boolean | True when Superdrug lists the product as discontinued (no longer for sale). `price` is then its last selling price, or null when the site shows a 0.10 GBP placeholder instead | `false` |
| `originalPrice` | number | Price before discount (if on offer) | `null` |
| `currency` | string | ISO currency code | `GBP` |
| `ean` | string | EAN barcode | `5012335792005` |
| `sku` | string | Superdrug product code | `286651` |
| `inStock` | boolean | Stock status | `true` |
| `stockLevel` | number | Exact stock count when available | `40` |
| `rating` | number | Average review score (out of 5) | `4.8` |
| `reviewCount` | number | Number of reviews | `46` |
| `category` | string | Most specific catalogue category | `Cod Liver Oil` |
| `promotion` | string | Promotional / offer text, if any | `VITAMINS 3 FOR 2` |
| `imageUrl` | string | Product image URL | `https://www.superdrug.com/medias/...jpg` |
| `url` | string | Product page URL | `https://www.superdrug.com/health/.../p/286651` |
| `description` | string | Product description / summary | \`\` |
| `scrapedAt` | string | ISO timestamp of the scrape | `2026-07-06T18:49:40.507Z` |

### Example output

```json
{
    "name": "Seven Seas Cod Liver Oil & Multivitamins 30 Caps",
    "brand": "Seven Seas",
    "subBrand": "",
    "price": 6.75,
    "discontinued": false,
    "originalPrice": null,
    "currency": "GBP",
    "ean": "5012335792005",
    "sku": "286651",
    "inStock": true,
    "stockLevel": 40,
    "rating": 4.8,
    "reviewCount": 46,
    "category": "Cod Liver Oil",
    "promotion": "VITAMINS 3 FOR 2 | FREE STANDARD DELIVERY",
    "imageUrl": "https://www.superdrug.com/medias/sys_master/prd-images/h9a/h41/12219068710942/prd-front-286651_600x600/prd-front-286651-600x600.jpg",
    "url": "https://www.superdrug.com/health/vitamins-supplements/cod-liver-oil/seven-seas-cod-liver-oil-multivitamins-30-caps/p/286651",
    "description": "",
    "scrapedAt": "2026-07-06T18:49:40.507Z"
}
```

### Tips for best results

- **Broad keywords pull more products.** "vitamin" returns far more than "vitamin c gummies 60". Start broad, then filter your dataset downstream.
- **Combine `searchQuery` with `category`.** For example, keyword "spf" plus category "skin/suncare" scopes results tightly.
- **Scrape specific products with `productUrls`.** Paste a list of product URLs (or codes) to refresh prices for a known set of SKUs on a schedule.
- **Large runs?** Raise `requestDelaySecs` to 10–20 to stay well under rate limits. The scraper already backs off automatically when throttled, but a steady pace is faster overall for big pulls.
- **Marketplace items are included.** Third-party marketplace listings (codes starting `mp-`) are returned alongside Superdrug's own range.

### Cost estimate

Pricing is pay-per-result. Each product is fetched individually through an unlocking layer, so cost scales with the number of results you request. A 100-product run is inexpensive; budget larger pulls against the per-result rate shown on this actor's pricing tab. Set `maxResults` to control spend precisely.

### Limitations / known issues

- **Search is slug-based.** The keyword is matched against product names and category paths in Superdrug's catalogue index, not a full-text engine. Very specific multi-word phrases may miss products whose names are worded differently. Broader terms return the widest slice.
- **Per-product fetch pace.** Because Superdrug exposes product detail one item at a time, large runs take longer than a listing-page scraper. Use `concurrency` and `requestDelaySecs` to tune speed vs. reliability. Each product costs one Bright Data fetch measured at 8-27s, so a `maxResults` of 5000 at the default `concurrency` of 5 takes roughly 2.2-7.5 hours end to end — raise the run timeout for pulls that size. If Apify migrates a long run to a new host, the actor resumes where it left off instead of restarting the fetch queue, so already-pushed products are never duplicated.
- **The first run of the day is the slow one.** Superdrug's catalogue index arrives corrupted from the unlocking layer on roughly half of all fetches, so reading it can take several minutes. Each section that is read cleanly is kept for `catalogueCacheHours`, and later runs search it without re-reading it — so a run that follows a recent one starts on the products straight away. If a run ends with fewer products than you asked for, re-run it: the second attempt is usually much faster.
- **Description often empty.** Superdrug's product API leaves the long description blank for many lines. Price, EAN, rating and stock are consistently populated.
- **Brand comes from Superdrug's brand record.** `brand` is the product's `masterBrand` from Superdrug's product API. Some brands have sub-line records ("L'Oreal Paris Elvive", "Nivea Men", "Garnier Ambre Solaire"); those are split, so `brand` is "L'Oreal Paris" and `subBrand` is "Elvive", and one brand always has one value. Products with no brand record fall back to Superdrug's range name when the product name starts with it, and to "Superdrug" for own-label lines. Some smaller brands have no brand record at all at Superdrug and come out with an empty `brand`: measured 2026-10-02, 75-85% populated on a broad keyword search and 95-100% on a brand search.
- **Online pricing only.** Reflects Superdrug.com pricing; in-store-only offers may differ.
- **Not affiliated with Superdrug.** This is an independent tool for publicly available product data. Respect Superdrug's terms and applicable laws when using scraped data.

### Related Scrapers

Building a UK health and beauty price dataset? Pair Superdrug with our other UK retail and pharmacy scrapers to compare pricing across chains on matching EAN codes:

- **Boots Scraper** (`boots-scraper`) — Boots.com UK health, pharmacy and beauty products.
- **Boots IE Scraper** (`boots-ie-scraper`) — Boots Ireland catalogue in EUR.
- **Tesco Scraper** (`tesco-scraper`) — Tesco UK groceries, Clubcard prices and stock.

Match products across all of them on the shared `ean` field to build a like-for-like UK retail price comparison.

# Actor input Schema

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

Keyword to search the Superdrug catalogue (e.g. 'vitamin c', 'no7 serum', 'paracetamol', 'shampoo'). Matched against product names and category paths.

## `category` (type: `string`):

Optional. Limit results to a Superdrug category path or slug, e.g. 'make-up/face' or 'health/pain-relief'. Combine with a search query or leave the query empty to pull a whole category.

## `productUrls` (type: `array`):

Optional. Scrape these exact product pages instead of searching. Accepts full Superdrug product URLs (…/p/860282) or bare product codes.

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

Maximum number of products to scrape.

## `inStockOnly` (type: `boolean`):

Only return products currently in stock.

## `concurrency` (type: `integer`):

How many product pages to fetch in parallel. Higher is faster but Superdrug's anti-bot proxy throttles hard — 3 to 5 is a good balance.

## `requestDelaySecs` (type: `integer`):

Minimum pause between requests. Raise this (10-20s) for large runs if you hit throttling. 0 = full speed with automatic adaptive backoff.

## `catalogueCacheHours` (type: `integer`):

Superdrug publishes its catalogue as gzipped sitemaps that the unlocker corrupts on roughly half of all fetches. Each section that is read cleanly is cached, so later runs search it without re-fetching and spend their whole budget on product data. Lower this if you need brand-new products the same day; 0 re-reads the catalogue on every run (slower, and more likely to hit a corrupted fetch).

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

Optional. Your own Bright Data Web Unlocker API key. Normally not needed — the actor ships with access. Only set this to route traffic through your own Bright Data account.

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

Proxy settings. Superdrug is fetched through the Bright Data Web Unlocker, so this can be left at its default.

## Actor input object example

```json
{
  "searchQuery": "vitamin c",
  "maxResults": 20,
  "inStockOnly": false,
  "concurrency": 5,
  "requestDelaySecs": 0,
  "catalogueCacheHours": 24,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GB"
  }
}
```

# 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": "vitamin c",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "GB"
    }
};

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

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

```

## MCP server setup

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