# Shopee Product Details Scraper (Taiwan + 7 markets) (`khalid_alsaba/shopee-product-scraper`) Actor

Full Shopee product pages from Taiwan, Brazil, Thailand, Indonesia, Malaysia, Philippines, Vietnam and Singapore: prices, variants, stock, sold, rating, shop vouchers, shipping fees, installments and shop details. Paste product URLs, get clean JSON. Failed lookups are free.

- **URL**: https://apify.com/khalid_alsaba/shopee-product-scraper.md
- **Developed by:** [MD Khalid Mahmud Shawon](https://apify.com/khalid_alsaba) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$6.00 / 1,000 products

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

## Shopee Product Details Scraper (Taiwan + 7 markets)

Get the **complete Shopee product page**, the same `get_pc` page data the Shopee app shows. Supported markets: **Taiwan**, Brazil, Thailand, Indonesia, Malaysia, the Philippines, Vietnam and Singapore. Paste product URLs and get back:

- **Prices:** current price, price range, price before discount, discount breakdown
- **Variants:** models with prices and stock flags, tier variations, sold count, rating, reviews and likes
- **Shop vouchers:** min-spend, discount, cap, validity and restrictions
- **Shipping:** every delivery option with its fee, free-shipping rules and estimated delivery dates
- **Installments:** bank installment plans where Shopee offers them
- **Shop details:** rating, followers, response rate, official / verified badges, location
- **Product details:** categories, attributes, description, images and video

No setup needed. **You pay per product answered:** data delivered, or Shopee confirmed the product is delisted or does not exist. Failed and timed-out products are free.

### Why this scraper

Shopee hides more of the product page every year. Many scrapers now return empty prices, missing vouchers or no variant data, especially for **Taiwan**. This Actor returns the complete product page in Shopee's own layout (all 79 page blocks and all 103 item fields), so you can use the same parser for every market.

### How to use

1. Add one or more **Product URLs**. These URL styles work:
   - `https://shopee.tw/product/8655035/10077094496`
   - `https://shopee.tw/Product-name-i.8655035.10077094496`
   - short share links (`s.shopee.tw/...`, `shp.ee/...`, `shope.ee/...`)
   - a text file with one URL per line
2. Or pass products by ID under **Products by ID**: `[{"region": "tw", "shopId": 8655035, "itemId": 10077094496}]`
3. Pick the **Output format**: the full product page (default) or clean flat fields.
4. Click **Start**. Results appear in the dataset as each product finishes.

Speed:

- **Taiwan** products usually take 1–3 minutes each. **Other markets** take 10–50 seconds.
- Products are fetched in parallel (default 20 at a time, up to 50), so large lists finish much faster than the per-product time suggests.

#### Input

| Field | Description |
|---|---|
| `productUrls` | Shopee product URLs (any supported market) |
| `products` | Optional list of `{region, shopId, itemId}` |
| `outputFormat` | `raw_get_pc` (default): full product page in Shopee's layout. `clean`: flat ready-to-use fields |
| `maxConcurrency` | Products fetched in parallel (1–50, default 20) |
| `timeoutSecs` | Max wait per product (300–3600 s, default 900). Timed-out products are not charged |
| `retryFailed` | Retry failed products once (default on) |

### Output: full product page (`raw_get_pc`, default)

One dataset item per product. A short summary sits on top for the table view, and the full page is under `raw`. Trimmed example (Taiwan):

```json
{
  "url": "https://shopee.tw/product/6000888/25629610891",
  "region": "tw",
  "shop_id": 6000888,
  "item_id": 25629610891,
  "status": "success",
  "title": "【米菈生活館】推車掛勾 嬰兒車掛勾 D型登山扣 ...",
  "currency": "TWD",
  "price": 5,
  "priceBeforeDiscount": 11,
  "discountPercent": 55,
  "sold": 113,
  "rating": 4.92,
  "shop": { "name": "米菈生活館" },
  "raw": {
    "get_pc": {
      "bff_meta": null,
      "error": 0,
      "error_msg": null,
      "data": {
        "item": {
          "item_id": 25629610891, "shop_id": 6000888, "currency": "TWD",
          "price": 500000, "price_min": 500000, "price_max": 1000000,
          "price_before_discount": 1100000, "show_discount": 55,
          "models": [ { "model_id": 236317055462, "name": "A款-D扣黑", "price": 1000000, "has_stock": true }, … ],
          "tier_variations": [ … ],
          …
        },
        "product_price": {
          "price": { "single_value": 500000, "range_min": -1, "range_max": -1 },
          "price_before_discount": { "single_value": 1100000 },
          "discount": 55, …
        },
        "product_shipping": {
          "ungrouped_channel_infos": [ { "name": "蝦皮店到店", "price": { "single_value": 4500000 }, "channel_delivery_info": { … } }, … ],
          …
        },
        "promotion_drawer": { "shop_vouchers": [ { "voucher_code": "JOANSUMME", "min_spend": 29900000, "discount_value": 1500000, … } ], … },
        "installment_drawer": { "bank": { "channels": [ … ] } },
        "product_review": { "rating_star": 4.92, "rating_count": [25, 0, 0, 1, 0, 24], "sold_count_display": "113", … },
        "shop_detailed": { "shopid": 6000888, "name": "米菈生活館", "rating_star": 4.908443, "follower_count": 95960, … },
        "product_images": { … }, "product_attributes": { … }, "product_description": { … },
        "flash_sale": null, "live_stream": null,
        "…": "all 79 page blocks; blocks that do not apply are null"
      },
      "http_status": 200
    },
    "shop": { "shopid": 6000888, "name": "米菈生活館", "follower_count": 95960, "response_rate": 86, … }
  },
  "scrapedAt": "2026-10-12T01:50:00.275Z"
}
```

**Prices inside `raw` are Shopee integers.** Divide by 100,000: `500000` is NT$5 and `7386000` is R$73.86. The summary fields on top are already decimals.

Where to find common data points in `raw.get_pc.data`:

| Data point | Path |
|---|---|
| Title | `item.title` |
| Current price | `product_price.price.single_value`, also `item.price` (range: `item.price_min` / `item.price_max`) |
| Price before discount | `product_price.price_before_discount.single_value`, `item.price_before_discount` |
| Discount % | `product_price.discount`, `item.show_discount` |
| Discount breakdown | `price_breakdown` |
| Variants | `item.models[]`, `item.tier_variations[]` |
| Sold / rating | `product_review.sold_count_display`, `product_review.rating_star`, `product_review.rating_count` = \[total, 1★ … 5★] |
| Shop vouchers | `shop_vouchers[]` or `promotion_drawer.shop_vouchers[]` |
| Shipping | `product_shipping.ungrouped_channel_infos[]`, `product_shipping.free_shipping` |
| Installments | `installment_drawer`, `product_price.installment_info` |
| Shop | `shop_detailed`, plus `raw.shop` |
| Images / description / categories | `product_images`, `product_description.paragraph_list`, `product_attributes.categories` |

The page layout is unchanged. The `account` block carries no shopper identity: `user_id` and `is_new_user` are `null`.

### Output: clean fields (`clean`)

Flat, ready-to-use fields with prices as decimals: `price`, `priceMin`, `priceMax`, `priceBeforeDiscount`, `discountPercent`, `priceAfterVoucher`, `availability`, `inStock`, `sold`, `rating`, `ratingBreakdown`, `categories`, `attributes`, `description`, `images`, `video`, `tierVariations`, `variants[]`, `shop{…}`, `shipping{shipFrom, feeMin, feeMax, freeShippingMinSpend, channels[]}`, `vouchers[]` (shop vouchers with `labels` and `newCustomerOnly`), `installments{recommended, plans[]}`, `promotions{flashSale, bundleDeal, addOnDeal, wholesale[]}`.

### Status

| Status | Meaning | Charged |
|---|---|---|
| `success` | Live product, full data | yes |
| `out_of_stock` | Product exists, no stock; data returned | yes |
| `item_unavailable` | Listing exists but cannot be bought right now; data returned | yes |
| `product_not_available` | Delisted, banned or deleted (confirmed by Shopee) | yes |
| `not_found` | Shop/item pair does not exist (confirmed by Shopee) | yes |
| `failed`, `expired`, `no_data` | Temporary problem on our side; try again later | no |
| `invalid_input` | Not a Shopee product URL from a supported market | no |

Rows without product data explain the reason in `message`.

### Pricing

**Pay per product answered.** You are charged for every product that gets a definitive answer: `success`, `out_of_stock`, `item_unavailable`, `product_not_available` or `not_found`. Products that fail or time out on our side (`failed`, `expired`, `no_data`) and inputs that are not Shopee product URLs (`invalid_input`) are free.

Set a maximum cost per run in the run options. The Actor does not start products that would exceed it.

### FAQ

**Which markets are supported?**
Taiwan (`shopee.tw`), Brazil (`shopee.com.br`), Thailand (`shopee.co.th`), Indonesia (`shopee.co.id`), Malaysia (`shopee.com.my`), the Philippines (`shopee.ph`), Vietnam (`shopee.vn`) and Singapore (`shopee.sg`).

**Can I scrape search results or a whole shop?**
This Actor takes product URLs. Collect URLs from a listing first, then pass them here.

**Why is stock sometimes `null`?**
Some sellers hide the exact stock number. Each model's `has_stock` still tells you whether it can be bought.

**Is it legal?**
The Actor collects publicly visible product information. You are responsible for how you use the data and for following applicable laws and Shopee's terms.

**Need higher volume or a direct API?**
Contact us through the Issues tab.

# Actor input Schema

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

Shopee product page URLs from any supported market (shopee.tw, shopee.com.br, shopee.co.th, shopee.co.id, shopee.com.my, shopee.ph, shopee.vn, shopee.sg). Both URL styles work: .../product/{shopId}/{itemId} and ...-i.{shopId}.{itemId}. Short share links are resolved automatically. You can also upload a text file of URLs.

## `products` (type: `array`):

Alternative to URLs: a JSON list of products, e.g. \[{"region": "tw", "shopId": 8655035, "itemId": 10077094496}]. region is one of tw, br, th, id, my, ph, vn, sg.

## `outputFormat` (type: `string`):

raw_get_pc (default): the full Shopee product page in its own layout under raw.get_pc (bff_meta, error, error_msg, data with all 79 page blocks, http_status) plus raw.shop, with a short summary (title, price, shop ...) on top for the table. clean: flat, ready-to-use fields only (prices as decimals, variants, shop vouchers, shipping, installments, shop).

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

How many products are fetched at the same time. Higher is faster for big lists.

## `timeoutSecs` (type: `integer`):

How long to wait for one product before giving up (not charged). Taiwan products usually take 1-3 minutes, other markets 10-50 seconds.

## `retryFailed` (type: `boolean`):

Retry products that failed or timed out one more time. Failed products are never charged.

## Actor input object example

```json
{
  "productUrls": [
    {
      "url": "https://shopee.tw/product/8655035/10077094496"
    }
  ],
  "outputFormat": "raw_get_pc",
  "maxConcurrency": 20,
  "timeoutSecs": 900,
  "retryFailed": true
}
```

# Actor output Schema

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

One item per product: prices, variants, shop vouchers, shipping, installments, shop details and status.

## `overview` (type: `string`):

The main fields only (overview view of the dataset).

# 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 = {
    "productUrls": [
        {
            "url": "https://shopee.tw/product/8655035/10077094496"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("khalid_alsaba/shopee-product-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 = { "productUrls": [{ "url": "https://shopee.tw/product/8655035/10077094496" }] }

# Run the Actor and wait for it to finish
run = client.actor("khalid_alsaba/shopee-product-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 '{
  "productUrls": [
    {
      "url": "https://shopee.tw/product/8655035/10077094496"
    }
  ]
}' |
apify call khalid_alsaba/shopee-product-scraper --silent --output-dataset

```

## MCP server setup

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