# Taobao & Tmall Products Scraper (`nice_dev/taobao-products-scraper`) Actor

Scrape Taobao & Tmall products by keyword, province, category, shop or product URL: title, price, discount, shop, shop rating, images. No login. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/nice_dev/taobao-products-scraper.md
- **Developed by:** [Nice Dev](https://apify.com/nice_dev) (community)
- **Categories:** E-commerce, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.95 / 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.
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

### 🛒 What is Taobao & Tmall Products Scraper?

**Taobao & Tmall Products Scraper** extracts **products from [Taobao](https://www.taobao.com) and Tmall**: **title, price, discount, photos, shop and its rating**, for any keyword, category, shop or product link. As options it adds the product page (ship-from city, seller credit level, shop age and scores, buyer ratings), the latest buyer review with the review keywords, and one row per shop. It works as a **Taobao API alternative**: run it on a schedule, call it from your code, or plug it into Make, Zapier or n8n.

Type a **keyword** (`蓝牙耳机`) or paste a Taobao or Tmall link, click **Start**, and download the products in JSON, CSV or Excel. No login, nothing to set up. Taobao shows only 20 products per page without an account: **Go past the first 20 results** reads the same search again in several orders, price ranges and brands, to return many more. Monitoring tells you which products are new and which changed price since your last run.

### 📋 What data can you extract from Taobao & Tmall?

One item per product, 58 fields:

| Category | What you get |
| --- | --- |
| 🏷️ **Product** | title, link, Taobao product number, photos, selling points — `夹耳式蓝牙耳机柏林德国骨传导无线运动游戏续航大电量2026新款` |
| 💰 **Price and promotions** | current price in yuan, crossed-out price, price in Hong Kong and Taiwan dollars, promotion label — `25.44 CNY`, `特价秒杀` |
| 🏪 **Shop** | shop name, number, link, the shop's "item as described" score — `4.74` |
| 🗂️ **Category** | category number, top category number, category path |
| 🛍️ **Taobao or Tmall** | platform, ship-from city, seller type, seller credit level, shop opening date, number of products, the 3 shop scores against its category — `浙江金华` |
| 👍 **Buyer ratings** | share of positive, neutral and negative ratings, payment methods, coupon link |
| ⭐ **Latest review** | rating, text, date, variant bought, follow-up review, photos, and what buyers say most with how many said it — `330 buyers: long battery life` |
| 🚚 **Buying agents** | the product on HooBuy, KakoBuy and CNFans, the sites that ship Taobao orders abroad |
| 🔎 **The search** | keyword, results page, rank on it, number of results Taobao announces |
| 🔔 **Price monitoring** | new product, price drop or rise, previous price, change in % |
| 🏬 **Shop rows** | one row per shop: name, logo, seller, 3 scores, size of the catalogue |

Every field, with an example, is listed in the **Output** section below.

Fields of the **Taobao or Tmall**, **Buyer ratings** and **Latest review** rows come from the product page: they are filled only when you tick **Product page** or **Latest review and review keywords** (both are options, off by default, see the price section) or give the product by link or number. Everything else comes with the search itself.

### ✅ Why use Taobao & Tmall Products Scraper?

- 🧭 **Search, categories, shops and products in one Actor**: keywords (several in one run), category numbers, shop pages, product links, and e.tb.cn / m.tb.cn share links.
- 📦 **Past the first 20 products**: Taobao stops at 20 per keyword or category page; the Actor reads the search again in other orders, price ranges and brands (the first page, then up to 200 other pages per search) and keeps the new products each time.
- 📍 **Ships from a province**: only products shipped from Guangdong, Zhejiang, Shanghai… alone or for several provinces in one run.
- 🛒 **Buying-agent links**: the HooBuy, KakoBuy and CNFans pages of every product, built from its number.
- 🈶 **Simplified or traditional Chinese**: titles and shop names as mainland sellers write them, or in the Hong Kong and Taiwan script.
- 🔔 **Monitoring built in**: tick **Only new products**, schedule the Actor, and each run returns only what it has never delivered; add **price changes** to hear when a price moves.
- 🧩 **Nothing twice**: a product found by several searches is saved once.

### 🚀 How to scrape Taobao & Tmall

1. Create a free Apify account.
2. Open **Taobao & Tmall Products Scraper** and type a **Search keyword** (e.g. `蓝牙耳机`).
3. Or paste your own Taobao or Tmall links into **Taobao / Tmall URLs**: keyword, category, shop or product pages.
4. Set **Max products** (100 by default, 0 = no limit) — and **Max products per search** when you run several searches — then click **Start**.
5. Download the dataset in JSON, CSV, Excel or via API.

### 💰 How much does it cost to scrape Taobao & Tmall?

This Actor uses **pay per event** pricing: you pay for each product returned, plus a small fee per run start. Everything else is an option, off by default, charged apart and only for what it delivers. See the **Pricing** tab for every amount.

- **Product page** (**Product page**, and every product you give by link or number in **Product URLs or IDs** or as a product link or share link in **Taobao / Tmall URLs**): one charge for each product delivered with its product page.
- **Latest review** (**Latest review and review keywords**): one charge for each product that has a review, review keywords or a number of reviews to deliver. It reads the product page, so the product page is charged too.
- **One row per shop** (**One row per shop**): one charge for each shop row, on top of the price of a row of the dataset. A shop row does not count in **Max products**.
- **Price changes** (**Also products whose price changed**): one charge for each product returned because its price moved by at least **Min price change (%)**. A new product costs its normal product price only.
- **Filter check** and **Detail filter check**: the filters Taobao does not offer are applied by the Actor on every product it reads. A product that passes them costs its normal price; a product a filter drops costs a small filter fee instead, so filtering never costs more than taking everything. Filter check covers **Exclude keywords**, **Min shop score** and the price range (Taobao is asked for the range too: only a product it lets through and the Actor then drops pays the fee). Detail filter check covers **Tmall only**, which needs the product page: each product dropped after its page was read pays it. Sort, province and free shipping are applied by Taobao and cost nothing extra. **Go past the first 20 results** has no fee of its own: you pay per product saved, but it reads many more products, so with a filter on, each product the filter drops among them pays its filter fee.

Platform usage (compute, proxy) is included in the price.

### ⚙️ Input

```json
{
    "query": "蓝牙耳机",
    "maxItems": 200
}
```

Several keywords in several provinces, a cap per search, only the products not delivered before:

```json
{
    "searchQueries": ["蓝牙耳机", "手机壳"],
    "locations": ["广东", "浙江"],
    "maxItemsPerQuery": 50,
    "onlyNew": true,
    "stateKey": "earphones-south"
}
```

Or with your own links, and a filter:

```json
{
    "startUrls": [
        { "url": "https://www.taobao.com/list/product/蓝牙耳机.htm" },
        { "url": "https://www.taobao.com/list/category/50005050.htm" }
    ],
    "maxPrice": 100,
    "maxItems": 500
}
```

Two products by link, with the product page and the latest review:

```json
{
    "productUrls": ["https://item.taobao.com/item.htm?id=1042700373143", "1079352038299"],
    "includeReviews": true
}
```

Monitoring a search: new products, and the ones whose price moved:

```json
{
    "query": "蓝牙耳机",
    "onlyNew": true,
    "includePriceChanges": true,
    "stateKey": "earphones-cn"
}
```

| Field | Notes |
| --- | --- |
| `startUrls` | Keyword pages (`https://www.taobao.com/list/product/蓝牙耳机.htm`, or a search link such as `https://s.taobao.com/search?q=iphone`, read as its keyword), category pages (`https://www.taobao.com/list/category/50005050.htm`), shop pages (`https://world.taobao.com/dianpu/239494884.htm`) and product pages. Share links (e.tb.cn, m.tb.cn) work too. When the list is not empty, the keyword and province fields are ignored; filters, caps and monitoring still apply. Max 1 000 URLs. |
| `query`, `searchQueries` | Keyword, as typed on Taobao (`蓝牙耳机`); `searchQueries` adds more keywords, one search each. Chinese keywords work best; short English words work too. |
| `location`, `locations` | Ship-from province, in Chinese (simplified or traditional) or English: `广东` or `Guangdong`. `locations` adds more provinces; every keyword is searched in every province (max 500 searches per run). Taobao's filter takes 16 provinces and municipalities: Guangdong, Beijing, Zhejiang, Hunan, Shanghai, Jiangsu, Fujian, Hubei, Shandong, Henan, Hebei, Chongqing, Sichuan, Heilongjiang, Shanxi and Jiangxi; any other name is refused. |
| `categoryIds` | Taobao category numbers (`50005050`), alone or with a province. Use the most precise category. |
| `shopIds` | Shop numbers (`239494884`): the shop's listed products, up to 60 per shop. |
| `productUrls` | Single products, as links or numbers (`1042700373143`). Each one is read from its product page, so it is charged as a product with the product page. Max 1 000. |
| `maxItems`, `maxItemsPerQuery` | Stop after this many products for the whole run (`0` = unlimited); `maxItemsPerQuery` caps EACH search (keyword, category, shop or search link). |
| `deepScan` | Read a keyword or category search again in other orders, price ranges and brands, to go past the first 20 products. On by default; no extra charge. On a small catalogue, some of the extra products may only have your keyword in their title: Taobao widens the search. |
| `sortBy` | Order of the results: `sales` (best selling), `price-desc` (highest price first) or `default` (Taobao's own order). |
| `minPrice`, `maxPrice` | Price range in yuan (`50`, `200`). Sent to Taobao and checked again on each product. |
| `freeShippingOnly` | Only products with free shipping within mainland China. Applied to keyword and category searches. |
| `language` | Script of the titles and shop names: `zh-CN` (simplified, default) or `zh-TW` (traditional). Prices are the same. |
| `extractDetails`, `includeReviews`, `includeShopProfile` | The three paid options, off by default: the product page, the latest review with the review keywords (it reads the product page too), and one row per shop. |
| `excludeKeywords` | Drop the products whose title contains one of these words (`二手`). Simplified and traditional Chinese are both matched. |
| `minRating` | Only products whose shop scores at least this for "item as described", out of 5 (`4.8`), as shown in the search results. |
| `tmallOnly` | Only products sold by Tmall shops. Needs `extractDetails` (without it this filter is ignored). |
| `onlyNew`, `includePriceChanges`, `minPriceChangePercent`, `stateKey`, `resetState` | Monitoring: only the products never delivered under this memory key (`earphones-cn`); with `includePriceChanges` also those whose price moved by at least `minPriceChangePercent` % (3 by default). `resetState` forgets the memory before the run. |
| Advanced | `proxyConfiguration` (Apify proxy by default, included in the price; the residential proxy is not available), `maxConcurrency`, `maxRequestsPerMinute`, `minRequestIntervalMs`, `maxRequestRetries`, `debugLog`. |

### 📦 Output

One item, shortened (a Tmall product found by the keyword search `蓝牙耳机`, with the product page; the latest review fields are filled when you tick **Latest review and review keywords**):

```json
{
    "type": "product",
    "id": "1042700373143",
    "url": "https://item.taobao.com/item.htm?id=1042700373143",
    "worldUrl": "https://www.taobao.com/list/item/1042700373143.htm",
    "title": "夹耳式蓝牙耳机柏林德国骨传导无线运动游戏续航大电量2026新款",
    "titleTruncated": false,
    "price": 25.44,
    "originalPrice": null,
    "currency": "CNY",
    "discountLabel": "特价秒杀",
    "imageUrl": "https://img.alicdn.com/imgextra/i4/3937219703/O1CN01LDZSfF7lQiK1chua_!!3937219703-2-C2M.png",
    "images": [
        "https://img.alicdn.com/imgextra/i4/3937219703/O1CN01LDZSfF7lQiK1chua_!!3937219703-2-C2M.png"
    ],
    "categoryId": "50005050",
    "rootCategoryId": "50011972",
    "categoryPath": [
        "影音视听",
        "耳机耳放",
        "耳机"
    ],
    "shopId": "239494884",
    "shopName": "官方国货甄选",
    "shopUrl": "https://world.taobao.com/dianpu/239494884.htm",
    "shopRating": 4.74,
    "agentLinks": {
        "hoobuy": "https://www.hoobuy.com/product/1/1042700373143",
        "kakobuy": "https://www.kakobuy.com/item/details?url=https%3A%2F%2Fitem.taobao.com%2Fitem.htm%3Fid%3D1042700373143",
        "cnfans": "https://cnfans.com/product?id=1042700373143&platform=TAOBAO"
    },
    "platform": "tmall",
    "isTmall": true,
    "shipsFrom": "浙江金华",
    "sellerType": "B",
    "sellerCreditLevel": 20,
    "shopOpenedAt": "2019-09-19T09:48:49.000Z",
    "shopItemCount": 93199,
    "shopScores": {
        "description": {
            "score": 4.7,
            "vsCategory": "below"
        },
        "service": {
            "score": 4.7,
            "vsCategory": "below"
        },
        "delivery": {
            "score": 4.8,
            "vsCategory": "below"
        }
    },
    "searchQuery": "蓝牙耳机",
    "searchUrl": "https://www.taobao.com/list/product/%E8%93%9D%E7%89%99%E8%80%B3%E6%9C%BA.htm",
    "rank": 3,
    "queryTotalResults": 36126,
    "scrapedAt": "2026-10-17T13:35:44.038Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV or Excel.

#### All 58 fields

| Fields | What you get |
| --- | --- |
| `type`, `id`, `url`, `worldUrl`, `title`, `titleTruncated` | row type (`product`, or `shop` on a shop row), product number, Taobao link, public Taobao page, title; `titleTruncated` is true when Taobao cut the title (a product read from its link alone) |
| `price`, `originalPrice`, `currency`, `priceHkd`, `priceTwd`, `discountLabel` | price in yuan, crossed-out price (null without a promotion), `CNY`, the same price in Hong Kong and Taiwan dollars as Taobao shows it, promotion label |
| `hasPriceRange`, `priceNote` | product page: true when the variants have different prices and `price` is the lowest; Taobao's remark under the price |
| `imageUrl`, `images`, `sellingPoints`, `freeShipping` | main photo, photos, short arguments shown on the card, true for products found with the free-shipping filter on (null otherwise) |
| `categoryId`, `rootCategoryId`, `categoryPath` | category number (reusable in the category input), top category number, category names from the top |
| `shopId`, `shopName`, `shopUrl`, `shopRating` | shop number, name, public shop page, "item as described" score out of 5 |
| `agentLinks` | HooBuy, KakoBuy and CNFans links of the product |
| `platform`, `isTmall`, `shipsFrom` | product page: `taobao` or `tmall`, true for a Tmall shop, province and city the product ships from |
| `sellerId`, `sellerType`, `sellerCreditLevel`, `shopOpenedAt`, `shopItemCount`, `shopNewItemCount`, `shopScores` | product page: seller account number, `B` (Tmall business) or `C` (Taobao seller), credit level as a number, date the shop opened, products in the shop, recently added products, the 3 scores out of 5 with their place against the category (`above`, `equal`, `below`) |
| `ratingGoodPercent`, `ratingNeutralPercent`, `ratingBadPercent`, `ratingGoodCount`, `ratingBadCount` | product page, Taobao shops only (Tmall shows none): share of positive, neutral and negative ratings, rounded counts as Taobao shows them (`2万+`) |
| `paymentMethods`, `couponUrl`, `sellableLanguages` | product page: payment methods, coupon link (opening it needs a Taobao login), languages and markets Taobao lists the product for |
| `reviewCountText`, `reviewTags`, `latestReview`, `hasMoreReviews` | latest review option: rounded number of reviews (`4000+`), what buyers say most with how many said it, the review Taobao shows (rating, text, date, variant, follow-up text, photos, video), true when there are more reviews than the one shown |
| `catalogueItemCount`, `logoUrl` | shop rows: number of products in the shop's whole catalogue, shop logo |
| `searchQuery`, `searchUrl`, `rank`, `queryTotalResults` | keyword of the search that found the product, the page it was found on (with the order and price range of the pass that found it), its place on that page, number of results Taobao announces. Rows are saved in the order pages finish: sort by `searchUrl`, then `rank`, for Taobao's order |
| `changeType`, `previousPrice`, `priceChangePercent` | monitoring: `new`, `price_drop` or `price_rise`, price on the last row delivered, change in % |
| `scrapedAt` | ISO timestamp of the extraction |

### 💡 Tips

#### How to get more results

Set `maxItems` to `0`, keep **Go past the first 20 results** on and use a broad keyword or a precise category. Taobao shows 20 products per keyword or category page and 60 per shop, with no second page. With `deepScan` the Actor reads the same search again in other orders, price ranges and brands, and a search stops when its cap is reached, after 200 other pages, or when a whole round of pages brings fewer than 2 new products for every 5 pages read. On a small catalogue, Taobao widens the search: some of the extra products may only have your keyword in their title, and their relevance is lower. The province filter is approximate too: in a sample of 15 products, about 2 shipped from another province. Several keywords, provinces and categories add more searches.

Speed, measured on real runs: about 650 products a minute from search pages (500 products with **Go past the first 20 results** in under a minute), and about 6 seconds for a product page, 5 read at once.

#### How to reduce costs

The price is per product, so the levers are `maxItems`, `maxItemsPerQuery`, the filters Taobao applies itself (sort, province, free shipping: a product it does not list costs nothing) and `onlyNew` for recurring runs (a product delivered once is never charged again). The product page, the latest review, the shop rows and the price changes are options: leave them off when you do not need them. `deepScan` and the keywords add products, not fees: you pay per product saved (with a filter on, each product it drops pays its small filter fee, and `deepScan` reads more of them).

#### Several searches in one run

Fill `searchQueries` and / or `locations`: the Actor runs one search per keyword × province (3 keywords × 4 provinces = 12 searches, up to 500 per run); categories are searched in every province too. The single `query` and `location` fields still work and are added to the lists. A product found by several searches is saved — and charged — once. Set `maxItemsPerQuery` to give every search its own cap: without it the first searches can use up the whole `maxItems` budget. You can also paste several links into `startUrls`: each keyword, category or shop link is a search of its own, with the same cap.

#### Keywords, categories and shops

Taobao publishes a public page for common product terms only. Chinese keywords work best (`蓝牙耳机` for Bluetooth earphones), short English words such as `iphone` work too, and many multi-word English phrases do not: a keyword without a page returns nothing, and the run log names it (nothing is charged). A category number is read in a category link (`/category/50005050.htm` gives `50005050`) or in the `categoryId` of a previous run; a top-level category has no public page, so use the most precise one. A shop returns its listed products, up to 60.

#### Ships from a province

`location` and `locations` use Taobao's own "ships from" filter, for 16 provinces and municipalities. It is approximate: in a sample of 15 products, about 2 shipped from another province. They filter keyword and category searches; shop and product pages take no province (a run that gives provinces together with only shops or products says so in its log). Sort, price range and free shipping work the same way: Taobao applies them to keyword and category pages.

#### Product page, latest review and shop rows

With `extractDetails` each product page is read: Taobao or Tmall, ship-from city, the price on the page (it can be lower than the card's), seller type and credit level, shop opening date, number of products, the shop's 3 scores against its category, the share of positive, neutral and negative ratings (Taobao shops only), payment methods and the coupon link. With `includeReviews` the latest review Taobao shows (it shows one without a login, buyer name left out) and the review keywords are added. With `includeShopProfile` each shop of the products found, and each shop in `shopIds`, also gets a row of its own with `type` set to `shop`, charged once per shop and per run (the shop fee, on top of the price of a row). Without `includeShopProfile`, `shopIds` returns products only. A shop none of whose products is saved in the run (all dropped by a filter, or all delivered before with `onlyNew`) gets no row, and so no charge. A product given by link or number is always read from its product page.

#### Filters

Taobao applies `sortBy`, `freeShippingOnly`, the province and, loosely, `minPrice` / `maxPrice`. The Actor applies the others on every product it reads: `excludeKeywords`, `minRating`, the exact price range and, with `extractDetails`, `tmallOnly`. A product dropped by the Actor is not saved and does not count in `maxItems`, and costs the filter fee shown in the Pricing tab. A product without the value a filter reads (no price, no shop score) is dropped. Taobao has no "lowest price first" order on these pages and no "newest" order: use `maxPrice`, and `onlyNew` to get the new products at each run.

#### Monitoring: only the new products

Tick **Only new products** (`onlyNew`) and schedule the Actor. The first run returns everything; each later run skips the products already delivered: they are not saved, not charged, and their product page is not even opened. The memory lives in a named key-value store of your account (`taobao-products-scraper-seen`, up to 150,000 products per key) and is only updated with products that really reached the dataset, so a failed run never hides anything. Give each schedule its own `stateKey` (two schedules sharing a key would hide each other's products), and tick `resetState` once to start over. Taobao has no "newest" order and prints no date, so **"new" means never delivered to you under this key, not newly listed on Taobao**: a later run can bring products listed long ago that the earlier runs did not reach (the site shows 20 products per page), and none of them was delivered before. With `onlyNew`, a product your filters drop is remembered under the same `stateKey` and skipped for free by the next runs with the same filters; one dropped by the price range is checked again, because its price can move.

#### Monitoring: price changes

Tick **Also products whose price changed** (`includePriceChanges`, needs `onlyNew`) and each run also returns the products it delivered before whose price moved: `changeType` is `price_drop` or `price_rise`, with `previousPrice` and `priceChangePercent`. A new product has `changeType` `new`.

- **Which price is followed.** The `price` of the row, in yuan: the card's price, or the product page's price when the row was built with it (`extractDetails`, a product given by link).
- **How big a change must be.** A product is returned, and charged, only when its price moved by at least `minPriceChangePercent` (3 % by default) compared with the price on the last row delivered to you for that product, not with the previous run: small moves add up, and the product comes back once the total passes your threshold.
- **A product that did not move enough** stays out of the dataset and costs nothing.
- **Memory.** Prices live under the same `stateKey` as `onlyNew`, up to 50,000 products per key (the ones not met for the longest time are forgotten and learned again silently, never reported as changes). Under 512 MB of run memory, the prices of the 25,000 products met last are kept. `resetState` forgets prices and delivered products together, so the next run returns and charges everything again.

### 🔌 Integrations and API

Call the Actor via the Apify API, the JavaScript or Python clients, or connect it with integrations and webhooks (Make, Zapier, n8n, Google Sheets, Slack, Airtable…). The dataset can be fetched as JSON or CSV from any tool.

### 🤖 Use with AI agents (MCP)

AI agents (Claude, ChatGPT, Cursor…) can find and run this Actor through the [Apify MCP server](https://mcp.apify.com), billed to their Apify account like any run. It returns one item per Taobao or Tmall product. Actor id: `nice_dev/taobao-products-scraper`; MCP server with this Actor only: `https://mcp.apify.com/?tools=fetch-actor-details,nice_dev/taobao-products-scraper`.

Smallest input, for a cheap first call:

```json
{
    "query": "蓝牙耳机",
    "maxItems": 10
}
```

Key output fields: `url`, `title`, `price`, `currency`, `shopName`, `shopRating`, `categoryId`, `searchUrl`. Cap each call with `maxItems` and, through the API, with the run option `maxTotalChargeUsd`. The prices are in the Pricing tab.

### ❓ FAQ

#### Is it legal to scrape Taobao & Tmall?

The Actor only reads what Taobao shows publicly to any anonymous visitor. It logs in to nothing. Results can contain personal data (a shop name or the text of a review can name a person), which is protected by GDPR: do not store it without a legitimate reason. The latest review is delivered without the buyer's name. You are responsible for using the data in compliance with Taobao's Terms of Use and applicable law. This Actor is not affiliated with Taobao, Tmall or Alibaba.

#### Does it need a login or a proxy?

No login. The proxy is included in the price: leave the default setting (the residential proxy is not available). A request the site turns away is retried at once on a new proxy session, up to 10 times on top of the retries (without a proxy, after a pause of 5 seconds, doubled at each retry up to 150 seconds).

#### Why does my keyword return nothing?

Taobao publishes a public page for common product terms only. A keyword without a page returns no product, and the run log names it; nothing is charged. Try the Chinese word, a shorter word, a category number, or paste a Taobao link into **Taobao / Tmall URLs**.

#### Why do some products cost 99,999 or 99,999,999?

Taobao prints these placeholder prices on some listings (they come first when you sort highest price first). The Actor returns the price as Taobao shows it. Set **Max price** to leave them out.

#### Is the data safe to open in Excel or to show on a web page?

Titles, shop names and review texts are the sellers' and buyers' own words, copied as they are. A text can begin with `-`, `+`, `=` or `@`: Excel and Google Sheets may read such a cell of a CSV file as a formula or as a number. The Actor leaves the text as it is, so that the JSON and the API give the real value: when you open a CSV, import these columns as text. Every URL field holds an http(s) URL or null. On a web page, escape every field like any text written by a stranger.

#### Known limitations

- Without an account Taobao shows 20 products per keyword or category page and 60 per shop, with no second page. **Go past the first 20 results** reads more of a keyword or category search; a shop returns its 60 listed products at most.
- The number of units sold, the variants with their price and stock, the product description and the buyers' questions are not available: Taobao does not show them without a login. Only one review per product is shown, so only that one is delivered.
- Affiliate links (`s.click.taobao.com`) need a Taobao login: they are skipped with a line in the log, and not charged.
- Titles of products read from their link alone are cut by Taobao (`titleTruncated` is then true).
- The same product read through a search, a shop and its own link does not give the same row everywhere. Prices, photos and numbers agree; the differences come from what each Taobao page shows: a product page only (`extractDetails`, a link) gives the ship-from city, seller, shop and rating details and its own price (`price`, which can be lower than the card's; `priceHkd` / `priceTwd` are then empty); the card only (search, shop, category) gives `sellingPoints`, `discountLabel`, the host prices and `rank`. `title` is the card's title, or the product page's title (shortened by Taobao, often another wording) for a product read from its link; `categoryPath` is empty on a shop page; `shopRating` has two decimals on a search card (4.75) and one on a shop or product page (4.7); on a shop page Taobao itself cuts long shop names (`深圳华强北正品直销总...`, the shop number stays the same).
- `onlyNew` remembers product numbers, not their content: a product whose price changed is returned again only with `includePriceChanges`.
- Sometimes Taobao answers a page without applying the sort, the price range, the province or the free-shipping filter. The log says so, once per search: the price range is still checked on every product, the order is Taobao's default one, and a page asked for a province or for free shipping comes back empty (its products cannot be told from those of another province, or from those that do not ship free; the page is read again once on another IP first). When **Go past the first 20 results** gets such an answer on its extra pages, it brings nothing new and stops by itself on that search.
- Two runs sharing the same `stateKey` at the same time may both return the same new product.

**A run that reaches its timeout** stops itself about 45 seconds before it: no new page is asked, what it read is saved and, with `onlyNew`, remembered, and the run ends *Succeeded* with "Stopped before the run's timeout". Resurrect it to go on from there, or give the next run a longer timeout (Run options).

**A run the platform stops without warning** (out of memory)

- Resurrect it: it goes on from where it stood at most a minute before the stop. What it had read since is read again, and the products already saved are skipped: none is delivered or charged twice, and `maxItems` still counts them.
- With `onlyNew`, the memory is saved after each write (at most once every 2 seconds): resurrect the stopped run and the products it had saved meanwhile join the memory; leave it stopped for good, and the next run may return the products of its last 2 seconds once more.

#### Something doesn't work?

The last line of the log counts the products saved, filtered out and the requests that failed after every retry. Those requests are listed, with the reason, in the `FAILED_REQUESTS` record of the run's key-value store. A run that saved nothing and had failed requests fails, and its last message gives the cause.

If Taobao changes its pages, you are told instead of paying for blank rows. If the first 20 products read all lack their title, price, photo or shop number, the run saves nothing more, stops and fails, and its last message names the missing field: at most those first products are charged. A run of fewer products (a scheduled `onlyNew` run that finds a few new ones, a small **Max products**) is checked at its end, from 5 products.

### 🛟 Support

Open an issue in the **Issues** tab with a link to your run: the run log and the `FAILED_REQUESTS` record of the key-value store show exactly which URLs failed and why.

# Actor input Schema

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

Any mix of: keyword pages (`https://www.taobao.com/list/product/蓝牙耳机.htm`, or a search link such as `https://s.taobao.com/search?q=iphone`, read as its keyword), category pages (`https://www.taobao.com/list/category/50005050.htm`), shop pages (`https://world.taobao.com/dianpu/239494884.htm`) and product pages (`https://item.taobao.com/item.htm?id=1042700373143`, `https://detail.tmall.com/item.htm?id=1042700373143`, `https://world.taobao.com/item/1042700373143.htm`, or e.tb.cn / m.tb.cn share links). When this list is not empty, the keyword fields below are ignored; filters, caps and monitoring still apply. Max 1 000 URLs.

## `query` (type: `string`):

Keyword, as typed on Taobao. Chinese keywords work best (e.g. `蓝牙耳机` = Bluetooth earphones); short English words like `iphone` or `sneakers` work too. Taobao publishes a public page for common product terms only: a keyword without one returns nothing and is named in the run log (not charged).

## `searchQueries` (type: `array`):

Several keywords in one run: one search per keyword (times each province below, max 500 searches). Added to **Search keyword**; products found by several searches are saved once.

## `location` (type: `string`):

Only products shipped from this Chinese province, as Taobao lists them (e.g. `广东` / `Guangdong`, `浙江` / `Zhejiang`, `上海` / `Shanghai`): Taobao's own 'province' filter. Empty = all of China.

## `locations` (type: `array`):

Several provinces in one run: every keyword is searched in every province (3 keywords × 4 provinces = 12 searches, max 500). Added to **Ships from (province)**.

## `categoryIds` (type: `array`):

Taobao category numbers, read in a category URL (`/category/50005050.htm` → `50005050`) or in the `categoryId` field of a previous run. Use the most precise category: a top-level category (e.g. `50011972`) has no public page.

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

Taobao / Tmall shop numbers (the `shopId` field of a previous run, or the number in a `world.taobao.com/dianpu/239494884.htm` URL): the shop's listed products (up to 60 per shop).

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

Single products to read, as URLs (`https://item.taobao.com/item.htm?id=1042700373143`, `https://detail.tmall.com/item.htm?id=1042700373143`, e.tb.cn share links) or bare product IDs (`1042700373143`). Each one is read from its product page, so it is charged as a product with **Product page** (see Pricing). Affiliate links (s.click.taobao.com) need a Taobao login and are skipped with a log line.

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

Maximum number of products to save for the whole run (after deduplication and filters). 0 = no limit.

## `maxItemsPerQuery` (type: `integer`):

Cap for EACH search (keyword, category, shop or search URL), so that the first search cannot use up the whole **Max products** budget. 0 = no per-search cap.

## `deepScan` (type: `boolean`):

Without an account, Taobao shows 20 products per keyword or category page and no page 2. On: the Actor reads the same search again in several orders, price ranges and brands, and keeps the new products each time, so a search returns hundreds of products instead of 20. On a small catalogue, some of the extra products may only have your keyword in their title: Taobao widens the search. The province filter is approximate too: about 2 products in 15 ship from another province. Off = 20 per keyword or category (faster). No fee of its own: you pay per product saved (with a filter on, each product it drops pays its filter fee, and more products are read).

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

Order of the search results, as on Taobao. Taobao has no 'lowest price first' order on these pages (it returns nothing): use **Max price** instead. Taobao has no 'newest' order: use **Only new products** below to get the new ones at each run.

## `minPrice` (type: `number`):

Only products from this price, in Chinese yuan (CNY). Sent to Taobao and checked again on each product.

## `maxPrice` (type: `number`):

Only products up to this price, in Chinese yuan (CNY). Sent to Taobao and checked again on each product. Empty or 0 = no maximum.

## `freeShippingOnly` (type: `boolean`):

Taobao filter 'free shipping' (包邮, within mainland China). Applied to keyword and category searches.

## `language` (type: `string`):

Script of the titles and shop names: simplified Chinese (mainland China, as the sellers write them) or traditional Chinese (Hong Kong, Taiwan). Prices are the same.

## `extractDetails` (type: `boolean`):

Read each product's page (1 extra request per product): Taobao or Tmall, ship-from city, original and promotion price, seller type and credit level, shop opening date and number of products, the shop's 3 scores against its category, the share of positive / neutral / negative buyer ratings, payment methods and the coupon link. Charged per product read (event `item-details`).

## `includeReviews` (type: `boolean`):

Add the latest buyer review shown on the product page (rating, text, date, variant bought, follow-up review, photo URLs) and the review keywords with how many buyers used them (e.g. `long battery life: 330`). Reads the product page, so it turns **Product page** on. Charged per product that has them (event `review`). Taobao shows only this one review without a login.

## `includeShopProfile` (type: `boolean`):

Add one row per shop (`type` = `shop`): shop name and logo, seller ID, the shop's 3 scores and the size of its whole catalogue. For the shops listed above, and also for each shop of the products found (1 extra request per shop). Charged per shop row (event `shop`).

## `excludeKeywords` (type: `array`):

Drop the products whose title contains one of these words (case ignored; simplified and traditional Chinese both matched).

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

Only products whose shop scores at least this for 'item as described' (out of 5, e.g. `4.8`), as shown in the search results. Products without a score are dropped.

## `tmallOnly` (type: `boolean`):

Only products sold by Tmall shops (brand and official stores). Taobao shows it on the product page only: needs **Product page** (without it this filter is ignored). A dropped product is charged a detail filter fee (see Pricing).

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

Skip the products that a previous run (same **Memory key**) already delivered: they are not saved and not charged, and their page is not even opened. First run = everything is new. "New" means never delivered to you, not newly listed: Taobao has no listing date, so a later run can bring older products the earlier runs did not reach.

## `includePriceChanges` (type: `boolean`):

With **Only new products**: also return the products already delivered whose price went up or down since the last run, with the previous price and the change in %. Charged per changed product (event `price-change`).

## `minPriceChangePercent` (type: `number`):

With **Also products whose price changed**: a product comes back only if its price (`price`, CNY) moved by at least this many % since the last time it was delivered.

## `stateKey` (type: `string`):

Name of the memory used by **Only new products**. Give each schedule / task its own key (e.g. `earphones-tmall`) so that they do not share their memory. Letters, digits, `-` and `_`.

## `resetState` (type: `boolean`):

Forget everything remembered under this **Memory key** before the run: this run returns (and charges) every product again. Untick it afterwards.

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

Apify Proxy or your own proxies. Keep the default: it is included in the price, and the Actor switches IP by itself when Taobao turns one away. Sorting, price, province and free-shipping filters and **Go past the first 20 results** go through the Actor's own connections, also included in the price. The residential Apify proxy is not available in this Actor.

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

Maximum number of requests processed in parallel.

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

Most requests to Taobao in any 60 seconds, all of them counted: search pages, product pages and shop pages. A budget, not an even pace: up to this many can leave at once when the minute starts (spread them with the minimum delay below). Lower it if the log shows many 'turned away' lines.

## `minRequestIntervalMs` (type: `integer`):

Smallest gap between two requests, in milliseconds. Unlike the per-minute rate, this spreads the requests evenly instead of letting them go out in a burst. 0 = no gap.

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

Retries per request before it is marked as failed. Behind a proxy, a request Taobao turns away is also retried on a new proxy session up to 10 times without using up these retries.

## `debugLog` (type: `boolean`):

Include debug messages in the run log.

## Actor input object example

```json
{
  "startUrls": [],
  "query": "蓝牙耳机",
  "searchQueries": [],
  "locations": [],
  "categoryIds": [],
  "shopIds": [],
  "productUrls": [],
  "maxItems": 100,
  "maxItemsPerQuery": 0,
  "deepScan": true,
  "sortBy": "sales",
  "freeShippingOnly": false,
  "language": "zh-CN",
  "extractDetails": false,
  "includeReviews": false,
  "includeShopProfile": false,
  "excludeKeywords": [],
  "tmallOnly": false,
  "onlyNew": false,
  "includePriceChanges": false,
  "minPriceChangePercent": 3,
  "stateKey": "default",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "maxConcurrency": 5,
  "maxRequestsPerMinute": 120,
  "minRequestIntervalMs": 0,
  "maxRequestRetries": 5,
  "debugLog": false
}
```

# Actor output Schema

## `results` (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 = {
    "query": "蓝牙耳机",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("nice_dev/taobao-products-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 = {
    "query": "蓝牙耳机",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("nice_dev/taobao-products-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 '{
  "query": "蓝牙耳机",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call nice_dev/taobao-products-scraper --silent --output-dataset

```

## MCP server setup

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