# Douyin Product Search Scraper - 抖音商城 by Keyword (`khadinakbar/douyin-product-search-scraper`) Actor

Search Douyin Shop (抖音商城) products by keyword. Use for China ecommerce research and affiliate selection — not video search or TikTok Shop. Returns title, price, sales, shop, image, detail URL. MCP-ready. $0.009/product.

- **URL**: https://apify.com/khadinakbar/douyin-product-search-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** E-commerce, Lead generation, MCP servers
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $9.00 / 1,000 product founds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Douyin Product Search Scraper

Search Douyin Shop (抖音商城) by product keyword and get one structured listing row per public product — title, price, sales when shown, shop, image, and `haohuo.jinritemai.com` detail URL. Built for China ecommerce research, affiliate selection, and MCP agents.

Referenced by: `.actor/actor.json` → `"readme": "../README.md"`. User instruction: build Douyin product search scraper.

### Best for

- Cross-border sellers researching Douyin Shop demand for Chinese keywords.
- Agencies comparing public price / sold labels across competing SKUs.
- Agents that need a keyword → product listing tool for China ecommerce.

Use this Actor when you have a **product keyword** and need Douyin Shop listings.

Do not use this Actor for Douyin **video** search (`douyin-search-scraper`), creator profiles (`douyin-profile-scraper`), video metadata (`douyin-video-scraper`), comments (`douyin-comments-scraper`), or **global TikTok Shop** (`tiktok-shop-scraper`). This SKU is China Douyin Shop only.

### Workflow story

A China ecommerce analyst sets `searchQueries` to `["口红"]` and `maxResults` to `5`. The run opens Douyin web search on the goods tab, intercepts public product XHR after Camoufox warmup, and returns listing rows with `productId`, `title`, `priceAmount`, `shopName`, and `detailUrl`. A captcha-walled route finishes `FAILED` with `UPSTREAM_FAILED` and zero `product-found` charges. A keyword with no public goods matches finishes `SUCCEEDED` with `VALID_EMPTY`.

### Input example

```json
{
  "searchQueries": ["口红"],
  "maxResults": 5
}
```

| Field | Type | Description |
|-------|------|-------------|
| `searchQueries` | array (required) | Product keywords. Chinese works best. Max 20 unique. |
| `maxResults` | integer | Cap on unique rows this run (1–200, default 50). |
| `proxyConfiguration` | object | Optional. Default path is owner DataImpulse → Apify Residential Asia. |

### Output fields

One dataset item is one public Douyin Shop listing.

```json
{
  "productId": "3821314999977115743",
  "promotionId": "3821317546850779275",
  "title": "兰蔻全新菁纯柔润丝缎唇膏196#朱砂橘 1.6g",
  "detailUrl": "https://haohuo.jinritemai.com/ecommerce/trade/detail/index.html?id=3821314999977115743&origin_type=2631",
  "mainImage": "https://p3-aio.ecombdimg.com/obj/ecom-shop-material/example.jpg",
  "priceAmount": 59.0,
  "priceCents": 5900,
  "monthlySold": 1162,
  "shopName": "桢植专营店",
  "shopScore": 92,
  "searchKeyword": "口红",
  "searchPosition": 1,
  "scrapedAt": "2026-09-22T00:00:00.000Z",
  "provider": "camoufox"
}
```

Field availability varies. Affiliate commission, review ratio, and sales counters are included only when Douyin exposes them on the public listing payload. Advertised commission is not a revenue guarantee.

### Pricing

Pay per event + platform usage pass-through:

- `apify-actor-start`: $0.00005
- `product-found`: $0.009 per pushed product row

Invalid input and fully blocked upstream runs do not charge `product-found`. See the Actor Pricing tab for live numbers.

### API / MCP

```bash
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~douyin-product-search-scraper/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["口红"],"maxResults":5}'
```

Agent prompt card:

```
Use khadinakbar/douyin-product-search-scraper with searchQueries set to one
Chinese Douyin Shop keyword (e.g. 口红) and maxResults at 5. Expect one row
per public product listing with title, price, shop, and detailUrl. Do not use
this for TikTok Shop or Douyin video search.
```

### Best results

- Prefer Chinese product nouns over English brand-only queries.
- Keep `maxResults` small for cost-bounded probes.
- Owner DataImpulse CN residential is the primary unlock path; Apify Residential alone often hits Douyin's captcha interstitial on search.

### Builder's note

Douyin signs web search XHR with `msToken` / `a_bogus`, so passive Camoufox intercept after homepage warmup is more reliable than forging signatures. ScrapeCreators and SociaVault have no Douyin routes; TikTok Shop provider routes are a different market and must not be wired here.

### Honest limits

- Public web listing fields only. No login, no private inventory, no guaranteed affiliate fields.
- Search pages are more aggressively captcha-walled than `/video/{id}` detail pages.
- Not affiliated with Douyin or ByteDance.

### Legal

Only scrape public Douyin Shop content you are allowed to process. Respect Douyin's terms, applicable privacy law (including PIPL where relevant), and your own compliance policy.

# Changelog

This Actor's version history is a separate document: https://apify.com/khadinakbar/douyin-product-search-scraper/changelog.md

# Actor input Schema

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

Douyin Shop product keywords to search. Chinese works best (e.g. 口红, 零食, 手机壳). One keyword per row; each keyword is searched independently. Max 20 unique values. NOT a product URL, video URL, or TikTok Shop query — use sibling Actors or tiktok-shop-scraper for those.

## `maxResults` (type: `integer`):

Hard cap on unique product rows pushed this run across all keywords. Acts as a cost cap. Bounded 1–200. Default 50. Does not raise Douyin's public search depth.

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

Optional override. By default the Actor tries the owner DataImpulse residential secret first (CN/HK/SG), then Apify Residential Asia (HK→SG→TW→JP→MO). Supply BYO residential proxyUrls only if you have a stronger CN pool. Not a Douyin login cookie field.

## `diagnosticMode` (type: `boolean`):

Budget-capped surface probe: try multiple Douyin Shop URLs, log XHR endpoints to OUTPUT.diagnostic, push at most a few rows. Default false. Not for customer production runs.

## Actor input object example

```json
{
  "searchQueries": [
    "口红",
    "蓝牙耳机"
  ],
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "HK"
  },
  "diagnosticMode": false
}
```

# Actor output Schema

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

One row per public Douyin Shop product listing with title, price, sales, shop, and detail URL when available.

## `runSummary` (type: `string`):

Detailed diagnostics, proxy tier, failure reasons, and estimated PPE cost.

## `output` (type: `string`):

Compact machine contract: outcome, message, itemsPushed, chargedEventCounts.

# 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 = {
    "searchQueries": [
        "口红"
    ],
    "maxResults": 50,
    "diagnosticMode": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/douyin-product-search-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 = {
    "searchQueries": ["口红"],
    "maxResults": 50,
    "diagnosticMode": False,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/douyin-product-search-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 '{
  "searchQueries": [
    "口红"
  ],
  "maxResults": 50,
  "diagnosticMode": false
}' |
apify call khadinakbar/douyin-product-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/douyin-product-search-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/oDXJtBRhEcelLDqDl/builds/CKn6cKlMS8bYKvecL/openapi.json
