# Takealot Scraper (`cocoa_kit/takealot-scraper`) Actor

Extract Takealot product prices, stock, ratings, seller offers, barcodes, and details from searches, categories, and product URLs.

- **URL**: https://apify.com/cocoa_kit/takealot-scraper.md
- **Developed by:** [Cocoa Kit](https://apify.com/cocoa_kit) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 product listings

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

## Takealot Scraper

Collect **Takealot product prices, stock, ratings, and seller offers** in a structured dataset. Start with search terms, category pages, brand filters, or direct product URLs. Export the results to JSON, CSV, or Excel, or connect them to your reporting tools through the Apify API.

Use fast listing mode to compare a large range of products. Enable full product details to add descriptions, barcodes, specifications, seller information, and other published offers.

### What can you do with this scraper?

- **Monitor prices and stock:** Run scheduled collections and compare prices, discounts, and availability.
- **Research product ranges:** Search by keyword or browse departments, categories, and brands.
- **Match products:** Use Takealot product IDs, TSIN values, barcodes, and model numbers when available.
- **Compare seller offers:** Collect the selected offer and other offers shown on the product page.
- **Build reports:** Send results to spreadsheets, dashboards, or other tools with Apify integrations.

The scraper removes duplicate products across sources in the same run. It follows listing pagination and stops at your product or page limit. Prices are in South African rand (`ZAR`). No Takealot account is needed.

### Quick start

1. Enter one or more **Search terms**, such as `laptop`.
2. Set **Maximum products**. Start with 50.
3. Choose whether to **Scrape full product details**.
4. Click **Start** and wait for the run to finish.
5. Open the **Products** dataset to view or export your results.

#### Search for products

```json
{
    "searchTerms": ["laptop", "wireless mouse"],
    "maxItems": 100,
    "maxPages": 5,
    "scrapeProductDetails": true
}
```

#### Collect a category in listing mode

```json
{
    "startUrls": [{ "url": "https://www.takealot.com/automotive/interior-accessories-25850" }],
    "maxItems": 100,
    "scrapeProductDetails": false
}
```

#### Get one product with full details

```json
{
    "startUrls": [
        { "url": "https://www.takealot.com/playstation-5-slim-console-with-disc-drive-ps5-slim/PLID95228805" }
    ],
    "maxItems": 1
}
```

#### Browse by department or brand

```json
{
    "categoryFilters": ["Type:13", "Brand:HP"],
    "maxItems": 100,
    "scrapeProductDetails": false
}
```

Each filter entry starts a separate source. To use a combination of filters, supply a Takealot `/all?filter=...` listing URL. Department URLs such as `https://www.takealot.com/computers` also work. Listing URLs can include an `after` cursor to start from a later page.

### Input options

Supply at least one source: `searchTerms`, `categoryFilters`, `startUrls`, `keyword`, or `url`.

| Input                  | Default     | Description                                                                                                              |
| ---------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
| `searchTerms`          | None        | List of search terms.                                                                                                    |
| `startUrls`            | None        | Takealot product, search, department, category, or filtered listing URLs. Use objects with a `url` field, as shown in the examples. |
| `categoryFilters`      | None        | One source per filter, such as `Type:13`, `Category:25850`, or `Brand:HP`.                                               |
| `scrapeProductDetails` | `true`      | Add full product details. Direct product URLs always return full details.                                                |
| `maxItems`             | `50`        | Maximum unique products across all sources. Set `0` for no product limit.                                                |
| `maxPages`             | `10`        | Maximum listing pages per source. Applies even when `maxItems` is `0`.                                                   |
| `imageSize`            | `pdpxl`     | Image URL size: `pdpxl`, `zoom`, `full`, `large`, or `small`.                                                            |
| `sort`                 | `Relevance` | Takealot sort name. A sort value in a listing URL takes priority.                                                        |
| `proxyConfiguration`   | Disabled    | Optional Apify Proxy or custom proxy settings.                                                                           |
| `maxConcurrency`       | `5`         | Maximum requests in progress, from 1 to 20.                                                                              |
| `maxRequestsPerMinute` | `120`       | Maximum request rate, from 1 to 600 per minute.                                                                          |
| `maxRequestRetries`    | `3`         | Retries after a request or response error, from 0 to 10.                                                                 |
| `requestDelayMillis`   | `200`       | Delay before each request, in milliseconds.                                                                              |
| `requestTimeoutSecs`   | `45`        | Network request timeout, from 10 to 180 seconds.                                                                         |
| `keyword`              | None        | Alternate input for one search term. A supplied `url` takes priority.                                                    |
| `url`                  | None        | Alternate input for one source URL.                                                                                      |
| `results_wanted`       | None        | Alternate name for `maxItems`; takes priority when greater than 0. Set 0 to use `maxItems`.                              |
| `max_pages`            | None        | Alternate name for `maxPages`; takes priority when supplied.                                                             |

Direct product URLs are processed first. When you use multiple listing sources, request completion order determines which products fill the shared limit. Each unique product has one source record in the output.

### Output data

Each row represents one product. Fields are omitted when Takealot does not supply a valid value. Empty arrays mean that no entries were supplied. Listing prices can describe a range of options; full-detail `price` is the selected offer price.

| Group                | Fields                                                                                                                                |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Product identity     | `plid`, `productId`, `tsin`, `offerProductId`, `title`, `subtitle`, `slug`, `brand`, `url`                                            |
| Prices               | `price`, `priceMin`, `priceMax`, `prices`, `prettyPrice`, `listingPrice`, `saving`, `currency`                                        |
| Availability         | `stockStatus`, `inStock`, `isLeadtime`, `isImported`, `isPreorder`, `addToCartAvailable`, `shopAllOptionsAvailable`, `hasMoreColours` |
| Delivery             | `distributionCentres`, `estimatedDelivery`, `estimatedDeliveryType`                                                                   |
| Ratings              | `starRating`, `reviewCount`, `reviewDistribution`                                                                                     |
| Images and badges    | `imageUrl`, `images`, `imageCount`, `badges`                                                                                          |
| Full product details | `sku`, `ean`, `mpn`, `model`, `warranty`, `descriptionHtml`, `attributes`, `department`, `categories`, `categoryPath`                 |
| Sellers and options  | `sellerId`, `sellerName`, `sellerRating`, `offers`, `variants`                                                                        |
| Source and position  | `sourceUrl`, `searchTerm`, `departmentSlug`, `categorySlug`, `sort`, `page`, `pagePosition`, `overallPosition`, `pageCursor`          |
| Collection status    | `scrapedAt`, `detailsScraped`, `detailError`                                                                                          |

`reviewDistribution` contains rating counts by star value. The Actor does not collect reviewer names or review text. `attributes` maps specification names to their published text. `offers` contains other seller offers; `variants` contains the purchase options supplied in the product response. It does not crawl every linked variant. `mpn` is included only when published; a barcode is not assumed to be an MPN.

`overallPosition` is the position within a source, starting from the requested page. It is not a global rank across sources. `imageCount` in listing mode can exceed the number of image URLs supplied. Delivery estimates depend on Takealot's default location and can differ from checkout.

#### Example product

This example shows a selection of fields. Prices and availability can change.

```json
{
    "plid": "PLID95228805",
    "productId": 95228805,
    "title": "PlayStation 5 Slim Console with disc drive (PS5 Slim)",
    "brand": "Sony Playstation",
    "price": 15904,
    "listingPrice": 17999,
    "currency": "ZAR",
    "inStock": true,
    "stockStatus": "In stock",
    "ean": "711719577188",
    "starRating": 4.9,
    "reviewCount": 212,
    "department": "Gaming",
    "categories": ["Consoles"],
    "distributionCentres": ["JHB"],
    "detailsScraped": true,
    "url": "https://www.takealot.com/playstation-5-slim-console-with-disc-drive-ps5-slim/PLID95228805"
}
```

### Pricing

| Result                    | Price per 1,000 results |
| ------------------------- | ----------------------: |
| Product listing           |               **$0.80** |
| Product with full details |               **$2.00** |

Each saved product incurs one result charge. A full-detail result replaces the listing charge; the two are not added together. A run start costs **$0.00005** at up to 1 GB of memory, with one additional start event per extra GB. Standard platform usage is included in the event price.

For example, 100 listing results cost $0.08 plus the run start. 100 full-detail results cost $0.20 plus the run start. Set a maximum run cost in Apify to control spending. The Actor stops when it cannot save another result within that budget. The Pricing tab shows the current rates.

### Scheduling and integrations

Create an Apify schedule to collect fresh data each day or week. Each run produces a separate dataset. Compare `plid`, `price`, `inStock`, and `scrapedAt` across runs to track changes. Use the Apify API, webhooks, Make, Zapier, or dataset exports to send results to your workflow.

### FAQ

#### Why did I get fewer products than requested?

The source can contain fewer products, reach the page limit, or repeat products already collected from another source. Your maximum run cost can also stop collection. `maxItems` is an upper limit, not a guaranteed count.

#### What happens if a product detail request fails?

After retries, the Actor keeps the available listing with `detailsScraped: false` and a `detailError`. It charges the listing rate for that record. The run is marked as failed if any request remains unsuccessful, so missing data is visible. The **Run summary** output lists failed requests and the number of saved products. Successful records remain available.

#### Which URLs are supported?

Use public Takealot product URLs with a `PLID`, search URLs, department pages, category pages, or `/all?filter=...` listings. Promotion landing pages, account pages, and other non-listing pages are not supported. Unsupported inputs fail with an error instead of returning unrelated products.

#### Why are some fields missing?

Some products have no published barcode, MPN, brand, seller, or price. Enable full product details for richer data. An absent stock flag means unknown availability, not necessarily out of stock. HTML descriptions are source content; sanitize them before displaying them in your application.

#### Where can I get help?

Open an issue from this Actor's **Issues** tab. Include the run ID, input source, and expected result. Do not include API tokens or private account information.

Use the data in line with Takealot's terms and applicable requirements. This Actor is not affiliated with Takealot.

# Actor input Schema

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

Search for each term. Results are unique across all sources.

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

Product, search, department, category, or filtered listing URLs.

## `categoryFilters` (type: `array`):

One listing source per filter. Use Type:13, Category:25850, or Brand:HP.

## `scrapeProductDetails` (type: `boolean`):

Add descriptions, barcodes, specifications, sellers, and offers. Direct product URLs always return details.

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

Global limit of unique products. Set 0 for no item limit. The page limit still applies.

## `maxPages` (type: `integer`):

Maximum listing pages for each search, filter, or listing URL.

## `imageSize` (type: `string`):

Size used for product image URLs.

## `sort` (type: `string`):

Takealot sort name. Relevance preserves the default order.

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

Optional proxy settings. Disabled by default.

## `maxConcurrency` (type: `integer`):

Maximum number of requests in progress.

## `maxRequestsPerMinute` (type: `integer`):

Request rate limit for the complete run.

## `maxRequestRetries` (type: `integer`):

Retries after a request or response error.

## `requestTimeoutSecs` (type: `integer`):

Maximum time in seconds for one network request.

## `keyword` (type: `string`):

Single search term. A supplied url takes priority.

## `url` (type: `string`):

Single Takealot source URL.

## `results_wanted` (type: `integer`):

Alternate name for maxItems. Overrides maxItems when supplied. Set 0 to use the main limit.

## `max_pages` (type: `integer`):

Alternate name for maxPages. Overrides maxPages when supplied. Set 0 to use the main limit.

## `requestDelayMillis` (type: `integer`):

Delay before each request, in milliseconds.

## Actor input object example

```json
{
  "searchTerms": [
    "laptop"
  ],
  "startUrls": [],
  "categoryFilters": [],
  "scrapeProductDetails": true,
  "maxItems": 50,
  "maxPages": 10,
  "imageSize": "pdpxl",
  "sort": "Relevance",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxConcurrency": 5,
  "maxRequestsPerMinute": 120,
  "maxRequestRetries": 3,
  "requestTimeoutSecs": 45,
  "requestDelayMillis": 200
}
```

# Actor output Schema

## `products` (type: `string`):

No description

## `summary` (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": [
        "laptop"
    ],
    "startUrls": [],
    "categoryFilters": [],
    "keyword": "",
    "url": "",
    "results_wanted": 0,
    "max_pages": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("cocoa_kit/takealot-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": ["laptop"],
    "startUrls": [],
    "categoryFilters": [],
    "keyword": "",
    "url": "",
    "results_wanted": 0,
    "max_pages": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("cocoa_kit/takealot-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 '{
  "searchTerms": [
    "laptop"
  ],
  "startUrls": [],
  "categoryFilters": [],
  "keyword": "",
  "url": "",
  "results_wanted": 0,
  "max_pages": 0
}' |
apify call cocoa_kit/takealot-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cocoa_kit/takealot-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/9BTCRb33fn3n40aYb/builds/yruXDaTsS59hpuHfd/openapi.json
