# Fenwick Scraper — UK Department Store Products & Prices (`studio-amba/fenwick-scraper`) Actor

Scrape Fenwick (fenwick.co.uk), the UK department store chain, for fashion, beauty, homeware and gift products: prices, per-size stock, brand, images and category. Search by keyword, filter by collection, or pull the full catalogue. No login required.

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

## Fenwick Scraper

Scrape [Fenwick](https://www.fenwick.co.uk) — the UK department store chain
— and get back clean JSON: prices, per-size stock, brand, images, category,
and Fenwick's own SKU/item reference for every product.

No login. No cookies to supply.

### Why use this actor?

Fenwick carries fashion, beauty, homeware and gift products across
hundreds of brands (Longchamp, Coach, Prada, Lacoste, Karl Lagerfeld and
more) under one storefront. If you are tracking department-store pricing,
building a resale/price-comparison dataset, or monitoring stock for a
specific brand or category, this actor pulls the whole catalogue — or just
the slice you ask for — without you having to reverse-engineer Shopify's
JSON feed yourself.

### How to scrape Fenwick data

1. Open the actor and leave every field empty to pull the full catalogue, or
2. Set `searchQuery` to a keyword, brand name, or category (e.g. `"dress"`,
   `"longchamp"`, `"perfume"`) to search by term, or
3. Set `collection` to a Shopify collection handle (e.g. `"klevering"`,
   `"honey"`) to scrape one category or brand line, and
4. Set `maxResults` and run. Results land in the dataset as JSON, CSV, Excel,
   or via the API.

You do not need an account, an API key, cookies, or a proxy to try it — the
actor talks directly to Fenwick's own Shopify storefront feed
(`products.json`, `collections/*/products.json`, `search/suggest.json`).
A residential proxy is enabled by default for reliability on larger runs (see
"Proxies" below).

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `searchQuery` | string | — | Search by keyword, brand, or category. Leave empty to browse all products. |
| `collection` | string | — | Shopify collection handle to scrape (see fenwick.co.uk/collections for handles). Leave empty for all products. |
| `maxResults` | integer | `100` | Maximum number of products to return. |
| `proxyConfiguration` | object | RESIDENTIAL (GB) | Proxy settings. See "Proxies" below for why this is on by default. |

### Output

One record per product.

```json
{
  "name": "Le Pliage Original Large Travel Bag Navy",
  "brand": "Longchamp",
  "price": 145,
  "currency": "GBP",
  "originalPrice": null,
  "discountPercent": null,
  "sku": "F-01623917",
  "itemNumber": "A804569",
  "productId": "10818972614990",
  "inStock": true,
  "sizes": [
    { "size": "Navy", "sku": "F-01623917", "price": 145, "inStock": true }
  ],
  "category": "Bags",
  "categories": ["Division:Women", "gift_box_ineligible", "ITEMNUMBER:A804569"],
  "description": "The Le Pliage Original Large Travel Bag by Longchamp delivers generous capacity...",
  "imageUrl": "https://cdn.shopify.com/s/files/.../A804569_000_001.jpg",
  "imageUrls": ["https://cdn.shopify.com/..."],
  "url": "https://www.fenwick.co.uk/products/longchamp-le-pliage-original-travel-bag-l-navy-l1624",
  "source": "fenwick.co.uk",
  "scrapedAt": "2026-09-09T09:07:09.640Z"
}
```

Field-by-field descriptions are in the output schema, visible in the Console
before you run.

### Search vs collection vs full catalogue — the trade-off

Fenwick's Shopify feed answers these three modes with two different
endpoints, and they do not expose the same fields:

| | `collection` / full catalogue | `searchQuery` |
|---|---|---|
| Endpoint | `products.json`, `collections/*/products.json` | `search/suggest.json` + per-product detail fetch |
| Per-size stock (`inStock`) | Real (`true`/`false`) | **Not exposed** — always `null` |
| Coverage | Full catalogue | Site's own suggest index (~10 hits) plus a filtered catalogue scan for the remainder |

Neither endpoint is a superset of the other. If you need real stock signal,
scrape by `collection` or the full catalogue. This actor never coerces a
missing signal to `false` — a `null` `inStock` means "this endpoint doesn't
say", not "out of stock".

### SKU and item numbers

Fenwick's feed uses two different SKU shapes. House-brand items carry a
`sku` like `FEN-943853` with no further reference. Third-party branded
items (Longchamp, Coach, Prada, and so on) carry a `sku` like
`F-01623917` plus a separate `itemNumber` (e.g. `A804569`), extracted from
the product's `ITEMNUMBER` tag.

Neither `sku` nor `itemNumber` is a confirmed designer manufacturer style
code — Fenwick's feed has no `mpn` field and no structured cross-retailer
join key. Treat both as Fenwick's own internal references, not a code you
can join against the brand's own site or another retailer.

### Speed and cost

Full-catalogue and collection scans page through `products.json` at 250
products per request (roughly 25,000 products across ~100 pages for a full
run). Search mode makes one lightweight suggest call plus one detail fetch
per matched product — typically ready in a few seconds for the default
10-hit suggest index; scanning the full catalogue for more matches takes
proportionally longer, the same as a full-catalogue run.

This actor scrapes against Fenwick's native JSON API — no HTML parsing, no
browser — so the cost per result is low (STANDARD tier, roughly $0.002 per
result plus a small per-run start fee). A run's usage cost only settles
after it reports SUCCEEDED; reading the dataset mid-run will undercount
what you'll actually be charged.

### Limitations

- **No confirmed manufacturer style code.** See "SKU and item numbers" above.
- **`inStock` is `null` in search mode.** See the trade-off table above.
- **No barcode/EAN field.** Fenwick's variant objects never expose a
  barcode key, on any endpoint.
- Shopify can rate-limit `products.json` by IP independent of any WAF — a
  burst of unpaced requests can return HTTP 429. This actor backs off and
  retries automatically, and a residential proxy is on by default.
- Prices and stock change constantly. Re-scrape rather than caching.

### Proxies

RESIDENTIAL (GB) is on by default. Fenwick has no WAF or anti-bot
challenge — Cloudflare fronts the domain but doesn't gate the JSON feed —
but Shopify can rate-limit `products.json` by IP independent of that, the
same behaviour documented on this fleet's other open-Shopify-feed actors
(Browns Fashion, Antonioli, Flying Tiger).

### Related scrapers

- **Browns Fashion Scraper** — UK multi-brand luxury boutique on the same
  open-Shopify-feed pattern as this actor.
- **Antonioli Scraper** / **Biffi Scraper** — Italian multi-brand boutiques,
  same pattern.
- **Farfetch Scraper** — the largest luxury marketplace; publishes a real
  manufacturer style code (`brandStyleId`).

### Maintained by Studio Amba

We run 700+ scrapers for European websites, and the priority is keeping
every one of them working. Automated runs test this actor against the live
site and verify the output is complete. When the website changes, the
scraper usually gets repaired the same day, without you having to report
anything. Questions and issues go straight to the people who built it, and
most get an answer the same day.

### Need this data on a schedule, or a custom version?

We run this scraper as a managed service for businesses: scheduled runs,
deduplication, delta detection, and delivery to your inbox, Google Sheets,
or API, maintenance included. We can also build a custom version with your
exact fields and filters, or combine multiple sources into one feed.

See [studioamba.dev/services](https://studioamba.dev/services/) or email
<hello@studioamba.dev> for a free data sample.

### Legal

This actor reads publicly available product listings. It does not log in,
does not touch personal data, and does not access anything behind an
account. You are responsible for how you use the output, including
compliance with Fenwick's terms and with applicable law.

# Actor input Schema

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

Search for products by keyword, brand, or category (e.g. 'dress', 'longchamp', 'perfume'). Leave empty to browse all products.

## `collection` (type: `string`):

Shopify collection handle to scrape (e.g. 'klevering', 'honey'). See fenwick.co.uk/collections for handles. Leave empty for all products.

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

Maximum number of products to return. Leave at the default for a representative slice; raise it (up to ~25,000) for a full-catalogue run.

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

Fenwick has no WAF/anti-bot, but Shopify rate-limits by IP regardless — a burst of unpaced requests can return HTTP 429 (verified on sibling Shopify-feed actors in this fleet). RESIDENTIAL proxy is on by default for reliable runs.

## Actor input object example

```json
{
  "searchQuery": "dress",
  "maxResults": 20,
  "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": "dress",
    "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/fenwick-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": "dress",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB",
    },
}

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

```

## MCP server setup

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