# Tesco Groceries Scraper (`piotrv1001/tesco-groceries-scraper`) Actor

The Tesco Groceries Scraper extracts products from tesco.com by keyword, category or product URL, capturing prices, unit prices, Clubcard offers, GTIN codes, stock status, ratings, reviews, ingredients, nutrition and allergens — ideal for FMCG price monitoring and nutrition datasets.

- **URL**: https://apify.com/piotrv1001/tesco-groceries-scraper.md
- **Developed by:** [FalconScrape](https://apify.com/piotrv1001) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

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

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

### 🛒 Tesco Groceries Scraper

Extract the **Tesco UK groceries catalogue** — prices, **Clubcard offers**, unit prices, stock status, ratings and the full **nutrition, ingredients and allergen** data — as clean, structured JSON. Search by keyword, sweep a whole [tesco.com](https://www.tesco.com/groceries/) category, or pass individual product URLs.

Built for FMCG price monitoring, grocery price comparison, nutrition datasets and retail market research. Runs on the Apify platform, so you get a REST API, scheduling, webhooks, proxy rotation and integrations with Make, Zapier, Google Sheets and n8n out of the box.

### ✨ Features

- 💷 **Real Clubcard pricing** — the member price, offer text and promotion window, not just the shelf price. Multibuy offers ("Any 2 for £4") are captured too.
- 🥗 **Nutrition & allergen data** — full nutrition table, reference intakes, ingredients, allergens, origin, storage and preparation instructions.
- ⭐ **Customer reviews** — star rating, ratings distribution and up to 20 review texts per product with verified-buyer flags.
- 🔖 **Retail identifiers** — GTIN/EAN barcode, TPNB and TPNC codes, brand and the full 4-level category path, so rows join straight onto your own product master.
- 📉 **Price-position flags** — Low Everyday Pricing, Low Price Promise and competitor price-match signals.
- 📚 **Whole-catalogue sweeps** — pagination is not capped at Tesco's 10,000-result display limit, so a large category comes back complete.
- ⚡ **Fast and cheap in listing mode** — thousands of products per minute; pay for the expensive detail data only when you ask for it.

### 🛠️ How to use the Tesco Groceries Scraper

1. **Choose what to scrape** — type keywords into **Search terms** (for example `olive oil`), and/or paste Tesco category, search or product page URLs into **Tesco URLs**.
2. **Set a limit** — **Max items** caps how many products the run collects. The default is 50.
3. **Decide on detail** — leave **Scrape full product details** off for fast price and availability data. Turn it on to also get nutrition, ingredients, allergens and reviews.
4. **Run it** — click **Start**, then download the results as JSON, CSV, Excel or XML, or pull them from the API.

### 📥 Input

| Field                | Type    | Description                                                                           |
| -------------------- | ------- | ------------------------------------------------------------------------------------- |
| `searchTerms`        | array   | Keywords to search the groceries catalogue for, e.g. `olive oil`.                     |
| `startUrls`          | array   | Tesco category, search or product page URLs. Scraped in addition to the search terms. |
| `maxItems`           | integer | Maximum number of products to collect. Default `50`.                                  |
| `scrapeDetails`      | boolean | Also collect nutrition, ingredients, allergens, origin and reviews. Default `false`.  |
| `sortBy`             | string  | `relevance`, `price-ascending` or `price-descending`.                                 |
| `proxyConfiguration` | object  | Proxy settings. UK residential proxies are strongly recommended.                      |

```json
{
    "searchTerms": ["olive oil"],
    "startUrls": [{ "url": "https://www.tesco.com/shop/en-GB/category/bakery/bread" }],
    "maxItems": 500,
    "scrapeDetails": false,
    "sortBy": "relevance",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GB"
    }
}
```

### 📊 Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
[
    {
        "url": "https://www.tesco.com/shop/en-GB/products/254918424",
        "id": "254918424",
        "tpnb": "50352624",
        "gtin": "05000119511027",
        "title": "Tesco Olive Oil 1L",
        "brand": "TESCO",
        "price": 7,
        "currency": "GBP",
        "unitPrice": 7,
        "unitOfMeasure": "litre",
        "clubcardPrice": null,
        "isOnPromotion": false,
        "promotions": [],
        "superDepartment": "Food Cupboard",
        "department": "Cooking Ingredients",
        "aisle": "Oils & Cooking Fats",
        "shelf": "Olive Oil",
        "imageUrl": "https://digitalcontent.api.tesco.com/v2/media/ghs/ff58fc20.../988401f6..._1687087292.jpeg",
        "rating": 4.5,
        "reviewsCount": 51,
        "inStock": true,
        "isSponsored": false,
        "foodIcons": ["Suitable for Vegetarians"],
        "source": "olive oil",
        "scrapedAt": "2026-08-03T14:03:43.797Z"
    },
    {
        "url": "https://www.tesco.com/shop/en-GB/products/264417662",
        "id": "264417662",
        "title": "Captain Morgan Original Spiced Gold Rum Based Spirit Bottle 35% 1L",
        "price": 25,
        "clubcardPrice": 18.5,
        "isOnPromotion": true,
        "promotions": [
            {
                "id": "101637056",
                "description": "£18.50 Save 25% Clubcard Price",
                "unitSellingInfo": "£18.50/litre",
                "startDate": "2026-07-13T23:00:00Z",
                "endDate": "2026-08-31T23:00:00Z",
                "isClubcard": true
            }
        ]
    }
]
```

With **Scrape full product details** enabled, every item additionally carries:

```json
{
    "packSize": [{ "value": "1000", "units": "ML" }],
    "netContents": "1l ℮",
    "ingredients": ["Olive Oil"],
    "nutrition": [
        { "name": "Typical Values", "value1": "Per 100ml", "value2": "One tablespoon (15ml)" },
        { "name": "Energy", "value1": "3378kJ / 822kcal", "value2": "507kJ / 123kcal" },
        { "name": "Fat", "value1": "91.3g", "value2": "13.7g" }
    ],
    "allergens": [{ "name": "Contains", "values": ["Milk", "Soya"] }],
    "guidelineDailyAmount": {
        "title": "One tablespoon",
        "dailyAmounts": [{ "name": "Fat", "value": "13.7g", "percent": "20", "rating": "HIGH" }]
    },
    "origin": [{ "title": "Produce of", "value": "the U.K." }],
    "storage": ["Store away from light and heat."],
    "recyclingInfo": "Bottle. Recycle- Rinse/Cap on",
    "isLowEverydayPricing": false,
    "isLowPricePromise": false,
    "isPriceMatched": null,
    "ratingsDistribution": [{ "name": "5.0", "value": "38" }],
    "reviews": [
        {
            "rating": 5,
            "summary": "Very good",
            "text": "Repeat purchase",
            "submittedAt": "2026-07-12T17:42:00.092Z",
            "verifiedBuyer": true
        }
    ]
}
```

### 🗂️ Data fields

| Field                                                           | Description                                                                  |
| --------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `url`, `id`, `tpnb`, `gtin`                                     | Product page URL and Tesco / barcode identifiers.                            |
| `title`, `brand`, `description`                                 | Product name, brand and marketing copy.                                      |
| `price`, `unitPrice`, `unitOfMeasure`                           | Shelf price in GBP and the comparable per-litre / per-kg price.              |
| `clubcardPrice`, `isOnPromotion`, `promotions`                  | Clubcard member price plus every active offer with its text and date window. |
| `superDepartment`, `department`, `aisle`, `shelf`               | Full Tesco category path.                                                    |
| `imageUrl`, `images`                                            | Main product image and, in detail mode, all high-resolution images.          |
| `rating`, `reviewsCount`, `ratingsDistribution`, `reviews`      | Star rating, review count and individual review texts.                       |
| `inStock`, `status`, `bulkBuyLimit`                             | Availability and per-order quantity limit.                                   |
| `isSponsored`                                                   | Whether the item came from a sponsored ad slot.                              |
| `nutrition`, `guidelineDailyAmount`, `allergens`, `ingredients` | Nutrition table, reference intakes, allergens and ingredient list.           |
| `origin`, `storage`, `preparationAndUsage`, `warnings`          | Country of origin, storage advice, cooking instructions and warnings.        |
| `isLowEverydayPricing`, `isLowPricePromise`, `isPriceMatched`   | Tesco price-position and competitor price-match flags.                       |
| `seller`                                                        | Marketplace seller name for third-party listings.                            |
| `source`, `scrapedAt`                                           | The search term or URL the item came from, and the capture timestamp.        |

### 💰 How much does it cost to scrape Tesco?

The Actor uses **pay per event** pricing — you pay for the results you get, not for how long the run takes.

| Event                     | Price  | Charged when                                        |
| ------------------------- | ------ | --------------------------------------------------- |
| Actor start               | $0.005 | Once per run.                                       |
| Product                   | $0.002 | Each product returned in listing mode.              |
| Product with full details | $0.006 | Each product returned with `scrapeDetails` enabled. |

So 1,000 products with prices and Clubcard offers costs about **$2.01**, and 1,000 products with the full nutrition, allergen and review payload costs about **$6.01**. Apify's free tier includes $5 of monthly usage, which is enough for roughly 2,400 listing results per month at no cost.

### 💡 Tips

- **Keep `scrapeDetails` off** unless you actually need nutrition or reviews — listing mode is three times cheaper and much faster, and it already includes price, Clubcard offers, ratings and stock status.
- **Target the narrowest category you can.** `.../category/bakery/bread` is far cheaper than sweeping all of `.../category/bakery` and filtering afterwards.
- **Use UK residential proxies.** Tesco throttles bursts of traffic from a single IP, and residential proxies keep the success rate near 100%.
- **Schedule a daily run** and point a webhook at your warehouse to build a Clubcard price history — this is the highest-value use case for the data.
- **Sort by price** with `price-ascending` when you only care about the cheapest options in a category and want to stop early.

### ❓ FAQ

**Is scraping Tesco legal?**
The Actor collects only publicly available product information — no login, no personal data, no customer accounts. Scraping public data is generally legal, but how you use the data is your responsibility. Review Tesco's Terms of Service and consult a lawyer if you plan to redistribute it commercially.

**Does it cover Tesco Ireland or other countries?**
No. This Actor covers Tesco UK (tesco.com). Prices are national online prices, not per-store prices.

**Why did I get fewer items than `maxItems`?**
Your search term or category may simply have fewer products than the limit you set. The Actor stops as soon as a category is exhausted.

**Do I get Clubcard prices for every offer?**
`clubcardPrice` is filled in for single-unit Clubcard offers. Multibuy deals ("Any 2 for £4") have no single-unit price, so they appear in the `promotions` array with the full offer text instead.

**Something is broken or missing.**
Open an issue on the Actor's **Issues** tab. Feature requests and custom scraping solutions are welcome.

# Actor input Schema

## `searchTerms` (type: `array`):

Keywords to search the Tesco groceries catalogue for, e.g. `olive oil`.

## `startUrls` (type: `array`):

Tesco category, search or product page URLs, for example `https://www.tesco.com/shop/en-GB/category/bakery`. Scraped in addition to the search terms above.

## `maxItems` (type: `integer`):

Maximum number of products to scrape across all search terms and URLs.

## `scrapeDetails` (type: `boolean`):

Also collect ingredients, the nutrition table, allergens, origin, storage, customer reviews and price-match flags for every product. Slower and priced separately.

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

Result ordering for search terms and categories.

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

Tesco blocks bursts of traffic from a single IP, so UK residential proxies are strongly recommended.

## Actor input object example

```json
{
  "searchTerms": [
    "olive oil"
  ],
  "startUrls": [],
  "maxItems": 50,
  "scrapeDetails": false,
  "sortBy": "relevance",
  "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 = {
    "searchTerms": [
        "olive oil"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("piotrv1001/tesco-groceries-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 = { "searchTerms": ["olive oil"] }

# Run the Actor and wait for it to finish
run = client.actor("piotrv1001/tesco-groceries-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "olive oil"
  ]
}' |
apify call piotrv1001/tesco-groceries-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=piotrv1001/tesco-groceries-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/iuMe3vYj6KHbt3nEl/builds/dUW9998b2omsFaA7S/openapi.json
