# Shopee Scraper - Product Catalogue Across 8 Markets (`s-r/shopee-scraper`) Actor

Search Shopee by keyword or category and get one row per product: name, canonical link, shop and item ids, and with details on, the brand, category, seller location, images and attributes. Indonesia, Singapore, Malaysia, Thailand, Vietnam, Philippines, Taiwan and Brazil. Catalogue data, not prices.

- **URL**: https://apify.com/s-r/shopee-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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?

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

## Shopee Scraper

Search Shopee by keyword or category and get one row per product: the name, the
canonical link, the shop and item ids, and with details switched on, the brand,
category, seller location, images and the seller's declared attributes.

Eight markets, chosen with one input:

| | | | |
|---|---|---|---|
| Indonesia `shopee.co.id` | Singapore `shopee.sg` | Malaysia `shopee.com.my` | Thailand `shopee.co.th` |
| Vietnam `shopee.vn` | Philippines `shopee.ph` | Taiwan `shopee.tw` | Brazil `shopee.com.br` |

Search in the market's own language: `sepatu` for Indonesia, `giày` for
Vietnam, `tenis` for Brazil. Around forty products come back per term per page.

### Prices, included

Every product comes back priced, in the market's own currency, with the price
before discount and the discount percentage when the seller is running one:

| title | price | price\_original | discount\_percent | rating | currency |
|---|---|---|---|---|---|
| Sepatu Slip On Pria HF07 Kulit Asli | 51250 | 125000 | 59 | 4.7 | IDR |
| 【GERALD】Canvas Sneakers Size 35-44 | 18.90 | 50.00 | 62 | 5.0 | MYR |
| Giày thể thao nữ đế mỏng siêu nhẹ | 152880 | 190000 | 20 | 4.8 | VND |

Measured across all eight markets on 2026-09-12: **315 of 319 products priced**,
308 with a rating, 302 with a seller location. The handful without a price are
promoted placements that Shopee renders without one.

**Read the currency column, do not assume it.** `18.90` is Malaysian ringgit on
one market and Brazilian reais on another, and the markets do not agree on
whether a dot is a thousands separator or a decimal point. Each row states its
own currency for exactly that reason, and the amounts are already normalised to
ordinary units, so `51250` is fifty-one thousand two hundred and fifty rupiah.

**Sold count and stock are not included.** Shopee does not put either on a
listing page in any market, so they are absent here rather than present as a
column of nulls.

### Optional: your own session, for the extra detail fields

Prices do not need a login. A session adds the fields Shopee only shows to a
signed-in shopper, such as stock and the rating count.

Paste your own Shopee cookies into **Your Shopee session cookies**. Log in to
your Shopee account in a browser, open the developer tools, and copy the
cookies for the Shopee domain: `SPC_EC`, `SPC_F`, `SPC_U` and `SPC_ST` are the
ones that carry the session.

They expire the way any login does. If the cookies are spent or wrong the run
does not fail: it records `session_refused` and carries on with the standard
path, so you still get every row, priced. That fallback is tested.

### What you get per product

- `title` — the product name, as the seller wrote it
- `price`, `price_original`, `discount_percent`, `currency` — what it costs
- `rating` — the average buyer rating out of 5
- `location` — where the seller ships from
- `product_url`, `shop_id`, `item_id` — the canonical link and its parts
- `market`, `list_position`, `source`, `source_input` — where the row came from

With **Fetch product details** on, each product page adds:

- `brand` and `brand_id`
- `cat_id` — Shopee's own category id, which is how you group a result set
- `shop_location` — the seller's full location, where the listing gives a short form
- `images`, `attributes`, `ctime`

### Details are optional, and usually unnecessary

A keyword search returns forty named, priced products in **one request**. That
is why **Fetch product details** is off by default: it costs a request per
product, and the name, the price, the rating and the link are already there
without it.

Turn it on when you need the brand, the category id or the attributes.
Leave it off when you are enumerating a market.

### Run sizes

**Pages per search term** walks deeper into a search. **Maximum products** caps
the whole run and is also the cost ceiling, since every product is a billed
row.

### Errors

| Code | Meaning |
|---|---|
| `blocked` | A listing page could not be read after every attempt |
| `detail_failed` | A product page could not be read; the product still appears, without its details |
| `bad_input` | No search term, category or product URL was given |

A `detail_failed` never costs you the row. The product keeps its name and link
and simply has no brand or attributes.

### A note on reliability

Access here is narrow. If a run suddenly returns `blocked` across the board
where it worked last week, that is what has happened; it is not your search
term. Check `products` against `errorCount` in the run summary, which is
exactly the ratio that tells the two apart.

### Related actors

For marketplaces where prices are available, see the Amazon, eBay, Walmart,
Bol, Idealo and AliExpress actors.

# Actor input Schema

## `market` (type: `string`):

Which Shopee country site to read. The market is set by this, not by where the request comes from.

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

One per line, in the market's own language. Around forty products come back per term per page.

## `categoryUrls` (type: `array`):

Shopee category pages, such as /Elektronik-cat.11044258. A full link or a path both work.

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

Individual products you already have. Combine with the above or use on their own.

## `pagesPerSearch` (type: `integer`):

How deep to walk each search.

## `fetchDetails` (type: `boolean`):

Open each product page for the brand, category id, seller location, images and attributes. Off by default: the listing already carries the name, and this is one request per product.

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

Stop after this many. Also the cost ceiling for the run.

## `concurrency` (type: `integer`):

How many product pages to open at once when details are on.

## `attempts` (type: `integer`):

How often to retry through a fresh exit before giving up on a page.

## `sessionCookies` (type: `object`):

Shopee withholds price, stock, rating and sold count from anyone who is not logged in. Paste your own cookies here as name/value pairs and the run uses Shopee's API instead, which carries all four. Without them you get the catalogue only.

## Actor input object example

```json
{
  "market": "id",
  "searchTerms": [
    "tas wanita",
    "headphone"
  ],
  "categoryUrls": [
    "https://shopee.co.id/Elektronik-cat.11044258"
  ],
  "productUrls": [
    "https://shopee.co.id/product/295064732/9112256351"
  ],
  "pagesPerSearch": 1,
  "fetchDetails": false,
  "maxProducts": 100,
  "concurrency": 3,
  "attempts": 4,
  "sessionCookies": {}
}
```

# Actor output Schema

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

One row per product.

## `summary` (type: `string`):

Products found per source, and how many carried a title and a brand.

## `errors` (type: `string`):

Pages that could not be read.

# 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 = {
    "market": "id",
    "searchTerms": [
        "sepatu"
    ],
    "categoryUrls": [],
    "productUrls": [],
    "sessionCookies": {}
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/shopee-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 = {
    "market": "id",
    "searchTerms": ["sepatu"],
    "categoryUrls": [],
    "productUrls": [],
    "sessionCookies": {},
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/shopee-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 '{
  "market": "id",
  "searchTerms": [
    "sepatu"
  ],
  "categoryUrls": [],
  "productUrls": [],
  "sessionCookies": {}
}' |
apify call s-r/shopee-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/shopee-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/z2tcW5Nk61IdiObI5/builds/T5MEJV0g9TvCcgHAp/openapi.json
