# Shopee Scraper - Products, Prices & Shops in 8 Countries (`scrapewise/shopee-scraper`) Actor

Scrape Shopee search results, categories and shops in Brazil, Singapore, Indonesia, Malaysia, Thailand, Philippines, Vietnam and Taiwan: price, original price, discount, rating, seller location, promo labels, shop stats. No login. Error rows are free.

- **URL**: https://apify.com/scrapewise/shopee-scraper.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** E-commerce
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.98 / 1,000 product delivereds

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

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

## Shopee Scraper: products, prices and discounts by search, category or shop

Scrape **Shopee search results, categories and shops** in **Singapore, Brazil, Indonesia, Malaysia, Thailand, the
Philippines, Vietnam and Taiwan** into one table: title, current price, original price, discount, rating, where the
seller ships from, the campaign labels Shopee puts on the card ("10.10 PRICE", "Free Gift", "Selling Fast"), image and
link. Turn on **Include shop details** to add the seller's rating, followers, number of products, response rate and
badges to every row, and schedule it daily to get **only new products** and **price changes**.

No Shopee account, no cookies, no API key. Works with Shopee's 2026 site, where the old JSON endpoints answer
"90309999" to anyone who is not logged in.

### At a glance

- **Price per 1,000 products, Free plan:** US$ 3.50 (US$ 2.98 on Gold and above)
- **Fee per run:** US$ 0.01
- **8 countries:** SG, BR, ID, MY, TH, PH, VN, TW, each in its own currency
- **Inputs:** search terms, search links, category links, shop ids, shop usernames or shop links
- **Deep results:** combines five sort orders (relevance, top sales, newest, price up, price down) to reach about
  250 to 300 unique products per search term and about 190 per shop
- **Shop details:** shop rating and rating count, followers, products, response rate, official / verified /
  preferred badges, join date, last active time; one request per shop, cached, no extra charge
- **Scheduled runs:** `onlyNew` and `trackPriceChanges` (previous price, change, price drop, first seen)
- **Error rows** (invalid input, shop not found, blocked page): free, with an `errorCode`

### One real row

From a test on 2026-10-12, search `wireless earbuds` in Singapore, with shop details on (a few shop fields left out here):

```json
{
  "itemId": "56164265587",
  "shopId": "1006220784",
  "title": "Lenovo EA175 Earphones Half In-Ear Wireless Bluetooth Headphones Water Resistant All Day Cloud Comfort Fit Headsets Sound Sports Gaming 24H Long Battery Life Earbuds",
  "price": 9.74,
  "priceMax": null,
  "originalPrice": null,
  "discountPercent": 44,
  "currency": "SGD",
  "priceText": "$ 9.74",
  "rating": 4.2,
  "location": "Mainland China",
  "promoLabels": [],
  "imageUrl": "https://down-sg.img.susercontent.com/file/sg-11134201-8257t-mqx0z6ygqry9e9",
  "url": "https://shopee.sg/product/1006220784/56164265587",
  "country": "SG",
  "sourceType": "search",
  "source": "wireless earbuds",
  "sortOrder": "relevance",
  "position": 1,
  "page": 0,
  "scrapedAt": "2026-10-12T15:25:00Z",
  "shopName": "Shopee Choice Global",
  "shopUrl": "https://shopee.sg/shopee_choice_global.sg",
  "shopRating": 4.77,
  "shopRatingCount": 3913332,
  "shopFollowers": 573479,
  "shopProductCount": 334397,
  "shopResponseRate": 96,
  "shopIsOfficial": false,
  "shopIsVerified": true,
  "shopJoinedAt": "2023-05-24T11:20:22Z",
  "shopLastActiveAt": "2026-10-12T15:11:49Z"
}
```

### What you can do with it

- **Dropshipping and product research:** pull the top-sales order of a term in several countries and compare price,
  discount and where sellers ship from (`location` tells local sellers from cross-border ones).
- **Price monitoring:** schedule a search, category or competitor shop daily with `trackPriceChanges` and get
  `previousPrice`, `priceChange` and `isPriceDrop` on every row.
- **New product alerts:** `onlyNew` with sort order `newest` delivers only listings you have not seen, so a daily run
  costs only what is new.
- **Seller research:** turn on shop details and rank shops by followers, rating count, response rate and badges.
- **Campaign tracking:** `promoLabels` and `discountPercent` show who joined a 9.9, 10.10 or 11.11 sale.

### Input

The simplest input, a search in Singapore:

```json
{
  "searchTerms": ["wireless earbuds"],
  "country": "SG",
  "maxItemsPerSearch": 40
}
```

Several kinds of input at once, with shop details:

```json
{
  "searchTerms": ["phone case", "tote bag"],
  "country": "MY",
  "startUrls": [
    "https://shopee.sg/search?keyword=mechanical%20keyboard&sortBy=sales",
    "https://shopee.sg/Mobile-Gadgets-cat.11013350"
  ],
  "shopIds": ["167068287"],
  "maxItemsPerSearch": 100,
  "includeShop": true
}
```

A daily price watch of the newest listings:

```json
{
  "searchTerms": ["air fryer"],
  "country": "PH",
  "sortBy": "newest",
  "onlyNew": true,
  "trackPriceChanges": true
}
```

| Field | What it does |
|---|---|
| `searchTerms` | Terms to search, one per line, in the language people use in that country |
| `country` | SG, BR, ID, MY, TH, PH, VN or TW. Links use the country of their own domain |
| `startUrls` | Search links, category links (`...-cat.<id>`) and shop links (`/shop/<id>` or `/<shop-username>`) |
| `shopIds` | Shop ids, shop usernames or shop links |
| `maxItemsPerSearch` | Unique products per input (default 40, up to 500) |
| `maxTotalItems` | Optional cap for the whole run |
| `sortBy` | `relevance`, `sales`, `newest`, `priceAsc` or `priceDesc` |
| `useMoreSortOrders` | Continue with the other orders when the first one stops returning new products (default on) |
| `minPrice`, `maxPrice` | Price range in the local currency |
| `includeShop` | Adds shop details to every row (no extra charge) |
| `includeDetails` | Opens each product page for its description and category path (charged per page) |
| `onlyNew` | Deliver only products the same input did not return before |
| `trackPriceChanges` | Add previous price, change and price drop flags |

Input names from other Shopee actors also work: `keyword`, `keywords`, `query`, `urls`, `maxItems`, `maxResults`,
`region`, `market`, `compareWithPreviousRun`.

### How deep results work

Shopee's pages repeat themselves: page 2 of a search often shows most of page 1 again. Each sort order, on the other
hand, shows a different slice. With `useMoreSortOrders` on (default), the Actor reads your chosen order first, and when
two pages in a row bring nothing new it moves to the next order, until `maxItemsPerSearch`. Each row tells you
`sortOrder` and `position` within it, so `sortOrder: "sales", position: 3` means third in Shopee's Top Sales tab.

Measured on 2026-10-12: about 280 unique products for one term in Brazil in 20 pages, about 190 for one shop. A
category link returns the category page itself (24 products in Shopee's order, `sortOrder: "category"`) and then
the search filtered by that category.

### Output fields

| Field | Meaning |
|---|---|
| `itemId`, `shopId`, `url` | Shopee ids and a clean product link |
| `title`, `imageUrl` | As shown on the card |
| `price`, `priceMax` | Current price; `priceMax` only when the card shows a price range |
| `originalPrice`, `discountPercent` | Crossed-out price and discount when the card shows them |
| `currency`, `priceText` | Local currency code and the price exactly as written |
| `rating` | Product rating on the card (not shown on category pages) |
| `location` | Where the seller ships from, for example `Mainland China`, `São Paulo`, `Selangor` |
| `promoLabels` | Campaign and offer labels on the card |
| `country`, `sourceType`, `source`, `sortOrder`, `position`, `page` | Where the row came from |
| `shop*` | Shop details with `includeShop` |
| `description`, `categoryPath` | With `includeDetails` |
| `isNewProduct`, `firstSeenAt`, `previousPrice`, `priceChange`, `isPriceDrop` | With `onlyNew` or `trackPriceChanges` |

#### Error codes (never charged)

| Code | When |
|---|---|
| `INVALID_INPUT` | Unknown country, a product link, a link that is not from Shopee, bad limits |
| `NO_RESULTS` | Shopee returned no product, or none matched your price range |
| `NOT_FOUND` | The shop or category does not exist |
| `BLOCKED` | Shopee refused the page after datacenter and residential retries; run again |
| `NOT_REACHED` | The run timeout came before this input |

### Pricing

Pay per event, no monthly fee:

| Event | Free plan | Gold and above |
|---|---|---|
| Product delivered | US$ 3.50 per 1,000 | US$ 2.98 per 1,000 |
| Product page added (`includeDetails`) | US$ 2.00 per 1,000 | US$ 1.70 per 1,000 |
| Run start | US$ 0.01 | US$ 0.01 |

Shop details are free. Error rows, duplicates and products held back by `onlyNew` are never charged. Set a maximum
cost per run in Apify and the Actor stops cleanly when it is reached.

### Limitations

- **No sold count, stock, variations or reviews.** Since 2026 Shopee shows these only to logged-in buyers, and this
  Actor does not log in. The list card has price, discount, rating and location; that is what you get.
- **No product links as input.** For the same reason, a product page has no price for visitors. Use a search, a
  category or a shop.
- Category pages do not show rating or location on their cards; the rows that come from the filtered search do.
- `originalPrice` is empty when Shopee shows only the discount badge without the crossed-out price (common in
  Singapore and the Philippines).
- Depth is limited by what Shopee shows across its sort orders, about 300 per term.

### FAQ

**Do I need a Shopee account or cookies?** No.

**Which language should my search terms be in?** The one shoppers use in that country: English works well in SG, MY
and PH; Indonesian, Thai, Vietnamese, Portuguese or Chinese terms give better results in ID, TH, VN, BR and TW.
Shopee's fuzzy matching still returns products for almost any term.

**Can I get the best sellers?** Use `sortBy: "sales"`. That is Shopee's Top Sales order; the exact sold count is
hidden from visitors.

**How do I watch a competitor?** Put the shop in `shopIds`, turn on `trackPriceChanges` and `includeShop`, save it as
a Task and schedule it daily.

**Is it legal?** It reads public pages that anyone can open without logging in, and no personal data of buyers.

### Changelog

- **2026-10-12:** first release. Searches, categories and shops in 8 countries; five sort orders for depth; shop
  details; product page description and category path; `onlyNew` and `trackPriceChanges`.

This Actor collects only publicly visible data from Shopee. Independent tool, not affiliated with Shopee.

# Actor input Schema

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

What to search on Shopee, one per line, in the language of the country you pick (English works in Singapore, Malaysia and the Philippines; Shopee's own fuzzy match also helps elsewhere). Each term returns up to 'Max products per search' unique products, combining several sort orders when 'Dig deeper' is on.

## `country` (type: `string`):

Shopee country used for the search terms and for shop ids or usernames. Links always use the country of their own domain. Prices come in that country's currency (SGD, BRL, IDR, MYR, THB, PHP, VND, TWD).

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

Search links (https://shopee.sg/search?keyword=phone%20case), category links (https://shopee.sg/Mobile-Gadgets-cat.11013350) or shop links (https://shopee.sg/shop/167068287 or https://shopee.sg/<shop-username>), from any of the 8 countries. Sort order and price range in a search link are kept. Product links are not supported: Shopee hides the price of a product page from visitors who are not logged in.

## `shopIds` (type: `array`):

Shop ids (167068287), shop usernames or shop links. Returns the shop's products in several sort orders (about 40 per order, up to about 190 per shop). Uses the Country above for ids and usernames.

## `maxItemsPerSearch` (type: `integer`):

Unique products per input. Shopee's pages repeat a lot, so deep results come from combining sort orders: about 250 to 300 per search term and about 190 per shop at most.

## `maxTotalItems` (type: `integer`):

Hard cap across all inputs together, for a fixed budget per run. Leave empty or 0 for no run cap. Also accepts 'maxItems'.

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

Order of the first pages read. 'Top sales' gives the best sellers of the term first (the order Shopee uses on its 'Top Sales' tab, which is as close as you can get to sales without a login).

## `useMoreSortOrders` (type: `boolean`):

When the first sort order stops returning new products, continue with the others (top sales, newest, price up and down) until the limit. Turn off to get only the order you picked. Every row says which order it came from in sortOrder and its place in it in position.

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

Only products at or above this price, in the currency of the country (for example 10 for SGD 10). Sent to Shopee and checked again on every row.

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

Only products at or below this price, in the currency of the country.

## `includeShop` (type: `boolean`):

Adds the seller to every row: shop name, username and link, shop rating and rating count, followers, number of products, chat response rate, official / verified / preferred badges, join date and last active time. One request per shop (cached), no extra charge.

## `includeDetails` (type: `boolean`):

Opens each product page to add its full description and category path (for example Mobile & Gadgets > Mobile Accessories > Cases). One extra request per product, charged as 'Product page added'. The product page has no price for visitors, so price and discount always come from the list.

## `onlyNew` (type: `boolean`):

Remembers which products each input already returned (in a key-value store on your account named 'shopee-scraper-state') and delivers only products not seen before. Seen products are not delivered and not charged. With 'Track price changes' on, products whose price moved are delivered too. Delete the store to start over.

## `trackPriceChanges` (type: `boolean`):

Compares every product with the previous run of the same input and adds isNewProduct, firstSeenAt, previousPrice, priceChange and isPriceDrop. Schedule the same Task daily to follow prices and discounts. Also accepts 'compareWithPreviousRun'.

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

Apify Proxy by default (datacenter, with a residential IP in the product's country as a fallback when a page is refused). Blocked sessions are swapped automatically.

## Actor input object example

```json
{
  "searchTerms": [
    "wireless earbuds"
  ],
  "country": "SG",
  "maxItemsPerSearch": 40,
  "sortBy": "relevance",
  "useMoreSortOrders": true,
  "includeShop": false,
  "includeDetails": false,
  "onlyNew": false,
  "trackPriceChanges": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `resultsCsv` (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": [
        "wireless earbuds"
    ],
    "country": "SG",
    "maxItemsPerSearch": 40,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/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 = {
    "searchTerms": ["wireless earbuds"],
    "country": "SG",
    "maxItemsPerSearch": 40,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/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 '{
  "searchTerms": [
    "wireless earbuds"
  ],
  "country": "SG",
  "maxItemsPerSearch": 40,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapewise/shopee-scraper --silent --output-dataset

```

## MCP server setup

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