# Sainsbury's UK Grocery Scraper (`parsebird/sainsburys-scraper`) Actor

Scrape Sainsbury's UK grocery products by search term. Get prices, Nectar prices, offers, unit prices, pack size, brand, EAN barcode, ratings, categories and images. Export as JSON, CSV, or Excel.

- **URL**: https://apify.com/parsebird/sainsburys-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.39 / 1,000 products

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?

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

### Sainsbury's UK Grocery Scraper

Sainsbury's UK Grocery Scraper extracts grocery products from [Sainsbury's Groceries](https://www.sainsburys.co.uk/gol-ui/groceries) by search term, with prices, Nectar prices, offers, unit prices, pack size, brand, EAN barcode, ratings, categories, descriptions, and images for every product.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Search Sainsbury's for any list of products, sort by price or rating, keep only offers if you want, and get the regular price and the Nectar price as separate numbers, ready for price comparison and basket tracking.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```text
Apify Actor parsebird/sainsburys-scraper scrapes grocery products from Sainsbury's (sainsburys.co.uk, UK). Call it with the apify-client package: client.actor("parsebird/sainsburys-scraper").call(run_input={"queries": ["baked beans", "whole milk"], "maxResultsPerQuery": 20}). Inputs: queries (array of search terms, as typed in the Sainsbury's search box), maxResultsPerQuery (int 1-5000, default 20), sortBy ("relevance","price_asc","price_desc","rating"; default "relevance"), offersOnly (bool, default false; only offers and Nectar prices), includeDetails (bool, default true; adds exact brand, zone, department, main category, breadcrumbs, description, all images), productUrls (array of {url}: Sainsbury's product URLs or search result URLs), proxyConfiguration (object, optional). Output: one dataset item per product per search term with store, query, position, productId, sainId, ean, eans, name, brand, price, regularPrice, nectarPrice, unitPrice, unitPriceMeasure, unitSize, onOffer, offerDescription, offers (description, isNectar, type, originalPrice, startDate, endDate, url, promotionId), labels, isAvailable, isAlcoholic, rating, reviewCount, zone, department, mainCategory, categories, breadcrumbs, description, imageUrl, images, productUrl, scrapedAt. Prices are in GBP. API docs: https://apify.com/parsebird/sainsburys-scraper/api. Get a token: https://console.apify.com/settings/integrations
```

### What is Sainsbury's UK Grocery Scraper?

**Sainsbury's UK Grocery Scraper** is a data extraction tool for **Sainsbury's grocery prices and products**. [Sainsbury's](https://www.sainsburys.co.uk/) is one of the UK's biggest supermarket chains, and its online grocery shop lists everything from baked beans to wine with prices, Nectar prices, and offers. The Actor works as a **Sainsbury's API alternative**: you enter search terms and get clean JSON product records instead of copying prices by hand.

The easiest way to try it: open the **Input** tab, keep the prefilled search terms `baked beans`, `whole milk`, and `sourdough`, and click **Start**. You get 30 products with full details in about 10 seconds.

### What can Sainsbury's UK Grocery Scraper do?

- 🔍 **Search Sainsbury's by keyword**: run many search terms in one go, each scraped separately and tagged with its `query`.
- 💷 **Get every price you need**: the shelf price, the regular price, the Nectar price, and the unit price (per kg, per litre, or each).
- 🏷️ **Track offers**: Nectar prices, multibuys, and meal deals with the offer text, type, original price, and start and end dates.
- ↕️ **Sort like the website**: by relevance, price low to high, price high to low, or rating, and keep only products on offer if you want.
- 📦 **Get product data**: brand, EAN barcode, pack size, rating and review count, availability, alcohol flag, categories, zone, department, breadcrumbs, description, and full-size images.
- 🔗 **Scrape URLs directly**: paste Sainsbury's product URLs or search result URLs.

On the Apify platform you also get [scheduled runs](https://docs.apify.com/platform/schedules), a full [REST API](https://docs.apify.com/api/v2), [integrations](https://apify.com/integrations) with Make, Zapier, n8n, Google Sheets, Slack, and webhooks, and export to JSON, CSV, Excel, XML, or HTML.

### What data can you extract from Sainsbury's?

| Field | Description |
|-------|-------------|
| `name` / `brand` | Product name and brand (for example "Heinz", "Sainsbury's") |
| `price` | Price shown on Sainsbury's in GBP. When a Nectar price applies, this is the Nectar price |
| `regularPrice` / `nectarPrice` | Regular shelf price and the Nectar price (empty when there is no Nectar price) |
| `unitPrice` / `unitPriceMeasure` | Price per unit for the shown price, for example `9.06` `per kg` |
| `unitSize` | Pack size from the product name, for example `4 x 415g`, `2L`, `70cl` |
| `onOffer` / `offerDescription` / `offers` | Whether there is an offer, the offer text, and each offer's type, original price, and dates |
| `labels` | Price labels such as "LOW EVERYDAY PRICE" or "ALDI PRICE MATCH\*" |
| `ean` / `productId` | EAN barcode and Sainsbury's product ID |
| `rating` / `reviewCount` | Average customer rating and number of reviews |
| `isAvailable` / `isAlcoholic` | Availability and alcohol flag |
| `zone` / `department` / `mainCategory` / `breadcrumbs` / `categories` | Where the product sits in the Sainsbury's shop |
| `description` | Short product description |
| `imageUrl` / `images` | Main image and all product images in full size |
| `productUrl` | Direct link to the product on sainsburys.co.uk |
| `query` / `position` | Search term and the product's position in the results |

### How to scrape Sainsbury's

1. Open [Sainsbury's UK Grocery Scraper](https://apify.com/parsebird/sainsburys-scraper) and click **Try for free**.
2. Enter your **Search terms**, one per line, such as `baked beans`, `whole milk`, or `sourdough`.
3. Set **Max products per search term**.
4. Optionally pick **Sort by**, turn on **Only products on offer**, or turn off **Include product details** for a faster run.
5. Click **Start**, then download the results from the **Output** tab as JSON, CSV, Excel, XML, or HTML, or fetch them through the API.

To track prices over time, add the run to a [schedule](https://docs.apify.com/platform/schedules), for example every morning, and compare the datasets.

### Input example

```json
{
    "queries": ["baked beans", "whole milk", "sourdough"],
    "maxResultsPerQuery": 10
}
```

Cheapest wine offers first, search results only:

```json
{
    "queries": ["wine"],
    "maxResultsPerQuery": 200,
    "sortBy": "price_asc",
    "offersOnly": true,
    "includeDetails": false
}
```

All input parameters:

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| queries | array | Yes\* | — | Search terms, as you would type them on sainsburys.co.uk |
| maxResultsPerQuery | integer | No | `20` | Maximum products per search term (1–5,000) |
| sortBy | string | No | `relevance` | `relevance`, `price_asc`, `price_desc`, or `rating` |
| offersOnly | boolean | No | `false` | Only products with an offer or Nectar price |
| includeDetails | boolean | No | `true` | Add exact brand, zone, department, main category, breadcrumbs, description, and all images |
| productUrls | array | No | — | Sainsbury's product URLs or search result URLs |
| proxyConfiguration | object | No | no proxy | Optional. The Actor switches to Apify Proxy by itself if Sainsbury's blocks requests |

\* Add at least one search term or one URL.

### Output example

```json
{
    "store": "sainsburys",
    "query": "chocolate",
    "position": 3,
    "productId": "8230856",
    "sainId": "na4b48jk",
    "ean": "8445291524545",
    "name": "KitKat 2 Finger Milk Chocolate Biscuit Bar Multipack 8 x 20.7g",
    "brand": "KitKat",
    "price": 1.5,
    "regularPrice": 2.2,
    "nectarPrice": 1.5,
    "unitPrice": 9.06,
    "unitPriceMeasure": "per kg",
    "unitSize": "8 x 20.7g",
    "onOffer": true,
    "offerDescription": "Buy 1 for 1.5",
    "offers": [
        {
            "description": "Buy 1 for 1.5",
            "isNectar": true,
            "type": "SIMPLE_FIXED_PRICE",
            "originalPrice": 2.2,
            "startDate": "2026-11-04T00:00:00Z",
            "endDate": "2026-11-24T00:00:00Z",
            "url": "https://www.sainsburys.co.uk/gol-ui/promo-lister/10771467",
            "promotionId": "10771467"
        }
    ],
    "isAvailable": true,
    "isAlcoholic": false,
    "rating": 4.84,
    "reviewCount": 345,
    "zone": "Snacks, sweets and treats",
    "department": "Chocolate",
    "mainCategory": "Single bar chocolate",
    "categories": ["Chocolate bars", "Chocolate biscuit bars", "Vegetarian & plant based"],
    "breadcrumbs": ["Snacks, sweets and treats", "Chocolate", "Chocolate bars"],
    "description": "Two crispy wafer fingers covered with milk chocolate (66%)",
    "imageUrl": "https://assets.sainsburys-groceries.co.uk/gol/8230856/image.jpg",
    "images": [
        "https://assets.sainsburys-groceries.co.uk/gol/8230856/1/2365x2365.jpg",
        "https://assets.sainsburys-groceries.co.uk/gol/8230856/2/2365x2365.jpg",
        "https://assets.sainsburys-groceries.co.uk/gol/8230856/3/2365x2365.jpg"
    ],
    "productUrl": "https://www.sainsburys.co.uk/gol-ui/product/kitkat-2-finger-milk-chocolate-biscuit-bar-multipack-8-x-20-7g",
    "scrapedAt": "2026-11-03T11:41:08.246Z"
}
```

### Use cases

- 💷 **Price monitoring**: track Sainsbury's prices and Nectar prices for your products every day.
- 🛒 **Supermarket price comparison**: compare Sainsbury's with Tesco, Lidl, and other retailers by EAN barcode or unit price.
- 🏷️ **Promotion tracking**: see which brands run Nectar prices, multibuys, and meal deals, and for how long.
- 📈 **Brand and category analysis**: measure assortment, ratings, and price ranges by brand or department.
- 🍽️ **Shopping and recipe apps**: price a basket of ingredients with up-to-date Sainsbury's prices.
- 🤖 **AI agents**: give an LLM structured, current grocery prices through the API or MCP.

### How it works

1. For each search term, the Actor reads the Sainsbury's product search, 60 products per page, in the sort order you chose.
2. It turns each result into a flat record: prices, unit price, offers, labels, rating, EAN, and categories. The pack size is read from the product name.
3. With **Include product details** on, it opens each product's data, 5 at a time, for the exact brand, zone, department, breadcrumbs, description, and images.
4. It stops at **Max products per search term** or the end of the results, and skips duplicates within a search term.
5. Each product is saved to the dataset and charged as it is collected, so the run stops as soon as your spending limit is reached.

### How much does it cost to scrape Sainsbury's?

Sainsbury's UK Grocery Scraper uses pay-per-event pricing. You pay per product saved to the dataset. Compute and traffic are included in the event price, so they are not billed separately.

| Event | Price per event | Price per 1,000 |
|-------|----------------|-----------------|
| product-scraped (Free plan) | $0.00299 | **$2.99** |
| product-scraped (Bronze plan) | $0.00279 | **$2.79** |
| product-scraped (Silver plan) | $0.00259 | **$2.59** |
| product-scraped (Gold plan) | $0.00239 | **$2.39** |

One event is one product in the dataset, with or without details. A small platform **Actor start** fee also applies per run. For example, 10 search terms with 20 products each (200 products) cost about $0.60 on the Free plan. Apify's free plan includes monthly platform credit you can use for this Actor.

### Python and JavaScript API examples

Python ([apify-client](https://docs.apify.com/api/client/python)):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("parsebird/sainsburys-scraper").call(run_input={
    "queries": ["baked beans", "whole milk", "sourdough"],
    "maxResultsPerQuery": 20,
})
for p in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(p["query"], "|", p["name"], "|", p["price"], "|", p.get("nectarPrice"), "|", p["unitPrice"], p["unitPriceMeasure"])
```

JavaScript ([apify-client](https://docs.apify.com/api/client/js)):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('parsebird/sainsburys-scraper').call({
    queries: ['baked beans', 'whole milk', 'sourdough'],
    maxResultsPerQuery: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((p) => console.log(p.query, p.name, p.price, p.nectarPrice, p.unitPrice, p.unitPriceMeasure));
```

Find all endpoints on the [API tab](https://apify.com/parsebird/sainsburys-scraper/api).

### FAQ

**Do I need a Sainsbury's account or Nectar card?**
No. The Actor reads the product data Sainsbury's shows to every visitor of its online grocery shop. You don't need to log in.

**What is the difference between price, regularPrice, and nectarPrice?**
`price` is the price Sainsbury's shows for the product. When a Nectar price applies, Sainsbury's shows the Nectar price as the main price, so `price` and `nectarPrice` are the same and `regularPrice` is the price without Nectar. When there is no Nectar price, `price` and `regularPrice` are the same and `nectarPrice` is empty.

**Why does an offer have a start date in the future?**
`startDate` and `endDate` are the dates Sainsbury's gives for the offer. Sainsbury's sometimes shows an offer price on the website before its listed start date, and the Actor returns the dates as provided.

**How many products can I scrape?**
Up to 5,000 per search term, limited by how many products Sainsbury's returns for that search. For example, "chocolate" returned 1,603 products and "cheese" 401 in our tests.

**Why is the brand sometimes empty?**
With **Include product details** on (the default), the brand comes from the product data and is almost always filled. With details off, the Actor matches the product name against the brand filter Sainsbury's shows for the search, which covers the main brands only.

**How is unitSize found?**
Sainsbury's doesn't publish the pack size as a separate field, so the Actor reads it from the end of the product name (for example `4 x 415g` or `70cl`). Loose items like bananas have no size.

**Are prices the same in every store?**
The Actor returns the online grocery prices from sainsburys.co.uk. Prices in physical stores can differ.

**Can I schedule the scraper and connect it to other tools?**
Yes. Use [Apify schedules](https://docs.apify.com/platform/schedules) to run it daily or weekly, and connect the results to Google Sheets, Slack, Make, Zapier, n8n, or your own system through [integrations](https://apify.com/integrations), webhooks, or the API.

**Something does not work or a field is missing.**
Open an issue on the **Issues** tab with your input and run ID, and we will look into it.

### Is it legal to scrape Sainsbury's?

The Actor collects only public product and price information that Sainsbury's shows to every visitor of its online shop. It does not collect personal data. Check that your use of the data complies with Sainsbury's terms and the laws that apply to you. For more background, read Apify's article [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/) and consult a lawyer if you are unsure about your use case.

### Other grocery and retail scrapers from ParseBird

| Actor | What it scrapes |
|-------|-----------------|
| [Tesco UK & Ireland Scraper](https://apify.com/parsebird/tesco-scraper) | Tesco.com and Tesco.ie products, Clubcard prices, nutrition, and reviews |
| [Lidl Scraper](https://apify.com/parsebird/lidl-scraper) | Lidl online shop products across European countries |
| [ALDI Australia Scraper](https://apify.com/parsebird/aldi-australia-scraper) | ALDI Australia products and prices |
| [Carrefour MAF Scraper](https://apify.com/parsebird/carrefour-maf-scraper) | Carrefour products in the Middle East |
| [Walmart Product Scraper](https://apify.com/parsebird/walmart-product-scraper) | Walmart product data |
| [Amazon Search Scraper](https://apify.com/parsebird/amazon-search-scraper) | Amazon search results |

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/sainsburys-scraper/changelog.md

# Actor input Schema

## `queries` (type: `array`):

Enter what you would type into the Sainsbury's search box, one per line (for example baked beans, whole milk, sourdough). Each search term is scraped separately.

## `maxResultsPerQuery` (type: `integer`):

Maximum number of products to save for each search term. Sainsbury's returns the products in the order you pick under Sort by.

## `sortBy` (type: `string`):

Order of the search results, the same options as on sainsburys.co.uk.

## `offersOnly` (type: `boolean`):

Return only products with an offer or Nectar price (the 'Offers & Nectar Prices' filter on sainsburys.co.uk).

## `includeDetails` (type: `boolean`):

Add the brand from the product page, zone, department, main category, breadcrumbs, product description, and all product images. Turn off for a faster run with search result data only.

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

Paste Sainsbury's product URLs (https://www.sainsburys.co.uk/gol-ui/product/...) to scrape single products, or search result URLs (https://www.sainsburys.co.uk/gol-ui/SearchResults/...) to add them as search terms.

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

Not needed in most cases. The Actor switches to Apify Proxy automatically if Sainsbury's blocks direct requests.

## Actor input object example

```json
{
  "queries": [
    "baked beans",
    "whole milk",
    "sourdough"
  ],
  "maxResultsPerQuery": 10,
  "sortBy": "relevance",
  "offersOnly": false,
  "includeDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "queries": [
        "baked beans",
        "whole milk",
        "sourdough"
    ],
    "maxResultsPerQuery": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/sainsburys-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 = {
    "queries": [
        "baked beans",
        "whole milk",
        "sourdough",
    ],
    "maxResultsPerQuery": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/sainsburys-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 '{
  "queries": [
    "baked beans",
    "whole milk",
    "sourdough"
  ],
  "maxResultsPerQuery": 10
}' |
apify call parsebird/sainsburys-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/sainsburys-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/SH7fXeUkDebg0pCor/builds/f1McamZPSN84s5iB6/openapi.json
