# Tesco Czech Republic Scraper — Grocery Products & Prices (`studio-amba/tesco-cz-scraper`) Actor

Scrape the full Tesco Czech Republic groceries catalogue: product names, CZK prices, Clubcard offers, price per unit, EAN codes, images, ratings and categories. Search by keyword, walk the department tree or scrape one category. No login, no cookies.

- **URL**: https://apify.com/studio-amba/tesco-cz-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 $2.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/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 Czech Republic Groceries Scraper

Scrape Tesco Czech Republic's grocery range: product names, CZK prices, Clubcard offers, price per unit, EAN codes, images, ratings, stock and full category paths. Search by keyword, scrape one category, or walk the entire catalogue. No login, no cookies.

### Why use this actor?

Tesco is one of the Czech Republic's largest grocers, and its online range (nakup.itesco.cz) is one of the biggest price datasets in Czech retail. This actor gives you a clean, structured feed of the Tesco Czech grocery catalogue for price monitoring, competitor benchmarking, product matching, market research, or building a grocery price comparison. You get the same data the Tesco website shows shoppers, including Clubcard prices, without needing an account or a delivery slot.

**Two data paths, both first-class.** Keyword searches go straight to Tesco's own search API, the same one the site uses, so search runs are fast and return clean structured data including the real brand name. Category and full-catalogue runs read the authoritative listing data embedded in Tesco's rendered pages, including the exact product total for every category.

**Complete past the 10,000 cap.** Every Tesco listing is capped at 10,000 results, so a single broad crawl can silently truncate large departments. This actor walks the category tree (superdepartment → department → aisle → shelf) and, whenever a node's total hits the cap, descends into its child categories until every listing stays under 10,000. Products are deduped by Tesco product id (TPNC), and the run ends with a self-checking completeness assertion that compares per-category distinct coverage against the authoritative totals.

Tesco Czech Republic sits behind a bot-protection wall, so ordinary scrapers get rejected before any product loads. For category scraping this actor routes every request through the Bright Data Web Unlocker, which solves the protection challenge and returns the fully rendered page, so you get reliable results run after run. Keyword search does not need Bright Data at all.

### How to scrape Tesco Czech Republic data

1. Add this actor to your Apify account.
2. Choose what to scrape:
   - Set `searchQuery` to scrape a keyword, e.g. `mléko` (milk) or `chléb` (bread). This path needs no Bright Data key.
   - Set `categoryUrl` to scrape one category, e.g. `bakery` or `bakery/sweet-pastry`, or a full `https://nakup.itesco.cz/shop/en-CZ/browse/...` URL.
   - Or paste a list of listing URLs into `startUrls`.
   - Leave everything empty to walk the whole grocery catalogue (all grocery superdepartments).
3. For category or full-catalogue runs, provide a Bright Data API key (field `brightDataApiKey`, stored as a secret) or set the `BRIGHT_DATA_API_KEY` environment variable.
4. Set `maxProducts` to cap the run (default 100, prefilled 20 for a quick test). Set it high, e.g. `25000`, for a full-catalogue pull.
5. Run the actor. Results stream to the dataset and can be exported as JSON, CSV, Excel or fed to an API.

For category runs the actor reads the authoritative product total of every listing and paginates 200 products per page. Whenever a listing's total hits Tesco's 10,000 cap, the actor drills into that category's children so no shelf is ever truncated. Set `enumerateOnly: true` to walk the tree and report the exact catalogue size without scraping products, a cheap way to verify completeness before a full run.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `searchQuery` | String | No | Search Tesco Czech Republic groceries by keyword (no Bright Data key needed) |
| `categoryUrl` | String | No | A Tesco Czech Republic category URL or slug to scrape |
| `startUrls` | Array | No | One or more Tesco Czech Republic listing URLs |
| `maxProducts` | Integer | No | Maximum products to return (default 100) |
| `brightDataApiKey` | String (secret) | For categories | Bright Data Web Unlocker API key. Falls back to `BRIGHT_DATA_API_KEY` env var. |
| `enumerateOnly` | Boolean | No | Walk the tree and report the authoritative catalogue size without scraping products |
| `requestDelaySecs` | Integer | No | Minimum pause between category page fetches (for very large paced runs) |
| `proxyConfiguration` | Object | No | Proxy settings for the search API path |

#### Example input

```json
{
    "searchQuery": "mléko",
    "maxProducts": 100
}
```

Or a category run:

```json
{
    "categoryUrl": "bakery/sweet-pastry",
    "maxProducts": 500
}
```

### Output

| Field | Type | Example | Description |
|-------|------|---------|-------------|
| `name` | String | `Tesco Roll 43g` | Product name |
| `brand` | String | `Tesco` | Brand name (search API) or own-brand detection |
| `price` | Number | `2.9` | Current shelf price in CZK |
| `currency` | String | `CZK` | Always CZK |
| `pricePerUnit` | String | `67.44 Kč/kg` | Unit price |
| `discount` | String | `Clubcard Price` | Clubcard / promotion text if present |
| `ean` | String | `02167700000000` | Barcode (GTIN) where available |
| `sku` | String | `200151875` | Tesco base product number (TPNB) |
| `productId` | String | `200151875` | Tesco consumer product number (TPNC) |
| `inStock` | Boolean | `true` | Availability flag |
| `rating` | Number | `3.8` | Average review rating (0-5) |
| `reviewCount` | Integer | `4` | Number of reviews |
| `category` | String | `Bakery > Loose pastry > Savory Pastry > Rolls` | Full category path |
| `imageUrl` | String | `https://digitalcontent.api.tesco.com/...` | Primary product image |
| `url` | String | `https://nakup.itesco.cz/shop/en-CZ/products/200151875` | Product page URL |
| `scrapedAt` | String | `2026-07-06T12:00:00.000Z` | Timestamp |

#### Example output

```json
{
    "name": "Tesco Roll 43g",
    "brand": "Tesco",
    "price": 2.9,
    "currency": "CZK",
    "pricePerUnit": "67.44 Kč/kg",
    "ean": "02167700000000",
    "sku": "200151875",
    "productId": "200151875",
    "inStock": true,
    "rating": 3.8,
    "reviewCount": 4,
    "imageUrl": "https://digitalcontent.api.tesco.com/v2/media/ghs/eee4737d-db37-4180-8572-605292d79de9/c82dfc06-82d9-4153-8c71-22bfc05a2485.jpeg",
    "category": "Bakery > Loose pastry > Savory Pastry > Rolls",
    "categories": ["Bakery", "Loose pastry", "Savory Pastry", "Rolls"],
    "url": "https://nakup.itesco.cz/shop/en-CZ/products/200151875",
    "scrapedAt": "2026-07-06T12:00:00.000Z"
}
```

### Cost estimate

Keyword searches fetch up to 200 products per request, so even large keyword pulls cost only a few cents of platform usage. Category runs go through the Bright Data Web Unlocker (about $0.0015 per page fetch on Bright Data's side) and also return up to 200 products per page, so a full-catalogue pull of the Czech grocery range needs only a few hundred unlocker requests.

### Related Scrapers

- [Tesco Groceries Scraper (UK)](https://apify.com/studio-amba/tesco-scraper) — the full Tesco UK grocery catalogue, same completeness engine.
- [Tesco Ireland Groceries Scraper](https://apify.com/studio-amba/tesco-ie-scraper) — the Irish Tesco grocery range in EUR.
- Building a wider grocery price dataset? Pair these with the rest of the Studio AMBA grocery and supermarket scrapers for cross-market price comparison.

### Limitations / known issues

- Tesco Czech Republic's website does not expose historical prices; each run captures a snapshot (use scheduled runs to build a price history).
- `rating` and `reviewCount` are only present for products that have reviews.
- The `discount` field carries the promotion text exactly as Tesco publishes it.
- Category scraping requires a Bright Data Web Unlocker key; keyword search does not.
- A full-catalogue walk is a long run. The actor persists its progress and survives Apify server migrations: already-pushed products are never duplicated and completed categories are skipped on resume.
- Tesco Czech Republic currently has no third-party marketplace; if Tesco ever adds one, this actor's own-range guard will keep marketplace items out of the output.

# Actor input Schema

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

Search Tesco Czech Republic groceries by keyword (e.g., 'mléko', 'chléb', 'sýr'). Search runs through Tesco's own search API — fast and no Bright Data key needed.

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

A Tesco Czech Republic category to scrape. Full URL (https://nakup.itesco.cz/shop/en-CZ/browse/bakery/all) or a slug (bakery or bakery/sweet-pastry).

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

One or more Tesco Czech Republic category or search listing URLs to scrape.

## `maxProducts` (type: `integer`):

Maximum number of products to return across all seeds. Set high (e.g., 30000) for a full-catalogue pull.

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

Minimum pause between category page fetches. Bright Data rate-limits rapid-fire requests to Tesco; a delay of 15-30s keeps a full-catalogue run under the limit (slower but reliable). 0 = full speed. Does not apply to keyword search.

## `enumerateOnly` (type: `boolean`):

Walk the category tree and report the authoritative catalogue size (summed leaf totals) without paginating or pushing products. Cheap completeness check.

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

Bright Data API key for the Web Unlocker zone. Required for category and full-catalogue scraping — Tesco Czech Republic is behind a bot-protection wall. Keyword search works without it. Falls back to the BRIGHT\_DATA\_API\_KEY environment variable.

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

Proxy settings for the Tesco search API. Category page access goes through the Bright Data Web Unlocker instead.

## Actor input object example

```json
{
  "searchQuery": "mléko",
  "maxProducts": 20,
  "requestDelaySecs": 0,
  "enumerateOnly": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "CZ"
  }
}
```

# 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": "mléko",
    "maxProducts": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "CZ"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/tesco-cz-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": "mléko",
    "maxProducts": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "CZ",
    },
}

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

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/0TzZ4JwJ6L2wiw7Jv/builds/kpgOwlctyw3anFtL4/openapi.json
