# Shopee Scraper (`crawlerbros/shopee-scraper`) Actor

Scrape Shopee - Southeast Asia's leading marketplace (MY, SG, TH, PH, VN, ID). Shop profiles with ratings and followers, public shop product feeds, full item detail pages (price, discounts, ratings, sold, stock, variations, images) and category browsing.

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

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Shopee Scraper

Scrape **Shopee** — Southeast Asia's leading e-commerce marketplace — across 6 markets (Malaysia, Singapore, Thailand, Philippines, Vietnam, Indonesia). Pull shop profiles (ratings, followers, response time), public shop product feeds, full item detail pages (prices, discounts, ratings, sold counts, stock, variations, images, category paths) and category listings. Browser-based (Playwright). No login, no cookies required.

### What this actor does

- **Four modes:** `shopProducts` (shop profile + product feed), `itemByUrl` (full item detail), `browseByCategory` (curated categories), `shopProfile` (shop profile only)
- **6 markets:** `MY` / `SG` / `TH` / `PH` / `VN` / `ID` domains with correct local currencies (MYR, SGD, THB, PHP, VND, IDR)
- **Shop profiles:** name, rating, followers, item count, response time, official/verified badges, description, account age
- **Item details:** price range, original price, discount %, sold & 30-day sold, stock, ratings, likes, variations, images, category path, listing date
- **Filters:** min/max price, minimum rating, keyword in title
- **Anti-bot resilience:** when Shopee blocks an item feed (error `90309999`), the mode still emits its verified public record (shop profile or category taxonomy) instead of failing, and an optional Apify proxy is engaged automatically
- **Empty fields are omitted**

### Data Source

Shopee (shopee.com.my and the SG/TH/PH/VN/ID domains). Shop profiles, item pages and category data are public; the actor reads them through Shopee's public API surface and pages.

### Limitations

- **Keyword search is login-gated on Shopee and is deliberately NOT supported.** Shopee requires an account to serve keyword search results to automated clients, so this actor is built around what is public without login: shop profiles, shop product feeds, item detail pages and category browsing.
- Shopee's anti-bot layer (error `90309999`) intermittently blocks the *item-feed* endpoints (`shop/search_items`, `search/search_items`, `item/get`) from datacenter IPs. When this happens the actor still emits the mode's verified public record — the shop profile in `shopProducts`/`shopProfile`, the category taxonomy record in `browseByCategory` — and reports what was blocked. Enabling the optional **Apify proxy** (engaged automatically only on a detected block) significantly improves feed success.
- Shopee's API also answers `service_err` (error `1000000`) on some domain/IP combinations — an API-level block that affects *every* shop on that domain, not a not-found. The actor treats it as a block (proxy escalation) rather than a missing shop. Only `invalid_username` (error `2003013`) is reported as "shop not found".
- Shop detail and shop-page SSR data may be market-gated by the requesting IP (e.g. a datacenter IP in the MY region typically sees only the MY market; SG/TH/PH/VN/ID APIs return `service_err`). Use a proxy located in the target market for non-MY domains.
- Item detail mode (`itemByUrl`) tries the API first and the SSR item page second (both are independent paths); if both are blocked, zero records are emitted with a clear status message.
- Prices are in the market's local currency (e.g. MYR on shopee.com.my). Range prices (`priceMin`/`priceMax`) are kept separate from the single `price` shown on the card.
- Category IDs are shared across Shopee's SEA domains; sub-categories differ per market.

### Output

#### Per shop (`recordType: "shop"`)

- `shopId`, `shopName`, `username`, `country`
- `ratingStar`, `ratingGood`, `ratingBad`, `ratingNormal`
- `followerCount`, `itemCount`, `responseTimeSeconds`
- `createdTimestamp`, `lastActiveTimestamp`, `cancellationRate`
- `isOfficialShop`, `isShopeeVerified`, `isPreferredPlusSeller`, `showOfficialShopLabel`
- `hasFlashSale`, `hasInShopFlashSale`, `hasBrandSale`, `hasJoinedMembership`
- `showLiveTab`, `isSemiInactive`, `vacation`, `isFollowed`, `status`
- `description`, `sourceUrl`, `scrapedAt`, `recordType`

#### Per item (`recordType: "item"`)

- `itemId`, `shopId`, `shopName`, `shopUsername`, `title`
- `price`, `priceMin`, `priceMax`, `priceOriginal`, `discountPercent`, `currency`
- `sold` (historical sold), `soldLast30Days`, `stock`
- `ratingStar`, `ratingCount`, `likeCount`
- `categoryId`, `category`, `categoryPath`, `location`, `listedTimestamp`, `itemStatus`
- `variations[]` (e.g. `Colour: Red, Blue, Green`), `description`
- `images[]`, `imageCover` (Shopee CDN URLs)
- `sourceUrl`, `scrapedAt`, `recordType`

#### Per category (`recordType: "category"`)

- `categoryId`, `category`, `sourceUrl`, `scrapedAt`, `recordType`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `shopProducts` | `shopProducts` / `itemByUrl` / `browseByCategory` / `shopProfile` |
| `shopUrl` | string | `appleflagship.store` | Shop username or page URL (mode=shopProducts/shopProfile) |
| `itemUrl` | string | – | Item page URL (mode=itemByUrl) |
| `category` | string | – | Curated Shopee category (26 options, mode=browseByCategory) |
| `domain` | string | `MY` | `MY` / `SG` / `TH` / `PH` / `VN` / `ID` |
| `minPrice` | int | – | Drop items below this (local currency) |
| `maxPrice` | int | – | Drop items above this (local currency) |
| `minRating` | number | `0` | Keep items rated at least this (0–5) |
| `containsKeyword` | string | – | Keep items whose title contains this text |
| `maxItems` | int | `50` | Hard cap (1–500) |
| `proxyConfiguration` | object | off | Optional Apify proxy, engaged automatically on block |

#### Example: shop products (Malaysia)

```json
{
  "mode": "shopProducts",
  "shopUrl": "appleflagship.store",
  "domain": "MY",
  "maxItems": 30
}
```

#### Example: shop profile only

```json
{
  "mode": "shopProfile",
  "shopUrl": "https://shopee.sg/sony.os",
  "domain": "SG"
}
```

#### Example: item detail by URL

```json
{
  "mode": "itemByUrl",
  "itemUrl": "https://shopee.com.my/extended-waterproof-gloves--i.169104911.6601357248",
  "domain": "MY"
}
```

#### Example: category browse with filters

```json
{
  "mode": "browseByCategory",
  "category": "Mobile & Accessories",
  "domain": "MY",
  "minPrice": 50,
  "maxPrice": 2000,
  "minRating": 4.5,
  "containsKeyword": "samsung",
  "maxItems": 40
}
```

### Use cases

- **Marketplace monitoring** — track shops, products, prices and discounts across SEA markets
- **Brand intelligence** — follower growth, rating trends and item counts for official stores
- **Competitor pricing** — price ranges, original prices and discount patterns per category
- **Product research** — ratings, sold counts and stock for demand estimation
- **Localized data pipelines** — currency-aware (MYR/SGD/THB/PHP/VND/IDR) e-commerce datasets

### FAQ

**What is the data source?** Shopee (shopee.com.my / .sg / .co.th / .ph / .vn / .co.id). This actor is a third-party tool and is not affiliated with or endorsed by Shopee.

**Why can't I scrape keyword search results?** Shopee gates keyword search behind a login wall for automated access. This actor deliberately avoids search and uses the public storefront surfaces instead — shop profiles, shop product feeds, item pages and category browse.

**Why did I get only a shop profile (or category) record and no items?** Shopee's anti-bot layer intermittently blocks the item-feed endpoints from datacenter IPs. The actor always emits the verified public record first, then attempts the feed. Enable the optional Apify proxy and retry — it is engaged automatically on the retry after a block.

**Do I need an account or cookies?** No. Everything this actor reads is public.

**What currency are prices in?** The market's local currency: MYR (MY), SGD (SG), THB (TH), PHP (PH), VND (VN), IDR (ID).

**What are `priceMin`/`priceMax` vs `price`?** Shopee items can show a price range (e.g. size-based). The range is kept in `priceMin`/`priceMax`; `price` is the displayed card price (range minimum when they differ).

**Why are some fields missing?** Empty fields are omitted by design — e.g. items without a discount have no `priceOriginal`/`discountPercent`, and unrated items have no `ratingStar`.

**Is this free to run?** The actor uses the free Playwright base image. The optional proxy is only used after a block is detected, so most runs cost nothing extra.

**How fresh is the data?** Live — shop profiles, items and categories are fetched at run time.

# Actor input Schema

## `mode` (type: `string`):

What to fetch.

## `shopUrl` (type: `string`):

Shop username or full shop page URL, e.g. `appleflagship.store` or `https://shopee.com.my/appleflagship.store`.

## `itemUrl` (type: `string`):

Full Shopee item page URL, e.g. `https://shopee.com.my/{slug}-i.{shopid}.{itemid}`.

## `category` (type: `string`):

Curated Shopee top-level category. CatIDs are shared across the SEA domains.

## `domain` (type: `string`):

Shopee market to scrape.

## `minPrice` (type: `integer`):

Drop items priced below this (in local currency units).

## `maxPrice` (type: `integer`):

Drop items priced above this (in local currency units).

## `minRating` (type: `number`):

Only keep items with an average rating at or above this (0–5).

## `containsKeyword` (type: `string`):

Only keep items whose title contains this text (case-insensitive).

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

Hard cap on emitted records.

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

Optional Apify proxy. Engaged automatically only when the source blocks direct requests (403/429).

## Actor input object example

```json
{
  "mode": "shopProfile",
  "shopUrl": "appleflagship.store",
  "domain": "MY",
  "minRating": 0,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `items` (type: `string`):

Dataset containing all scraped Shopee shop, item and category records.

# 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 = {
    "mode": "shopProfile",
    "shopUrl": "appleflagship.store",
    "domain": "MY",
    "minRating": 0,
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/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 = {
    "mode": "shopProfile",
    "shopUrl": "appleflagship.store",
    "domain": "MY",
    "minRating": 0,
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/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 '{
  "mode": "shopProfile",
  "shopUrl": "appleflagship.store",
  "domain": "MY",
  "minRating": 0,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call crawlerbros/shopee-scraper --silent --output-dataset

```

## MCP server setup

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