How to use 1688 Products Scraper
Step by step: in the Apify Store, over the API, from JavaScript or Python, in n8n, and from AI agents through MCP or LangChain.
$1.80 per 1,000 product (search result)s on the Free plan, down to $1.35 on higher plans (live Apify price on 2026-11-01).
1. In the Apify Store (no code)
- Open arcadium/1688-products and sign in to Apify (a free account works).
- Fill in the input form. The fields below are the ones the example uses.
- Set a maximum cost per run in the run options if you want a hard cap.
- Start the run. Rows appear in the Output tab as they arrive.
- Export the dataset as JSON, CSV or Excel, or connect an integration.
| Input field | Type | Description |
|---|---|---|
keywords | array | Words to search 1688.com for, Chinese or English, for example ["保温杯", "water bottle"]. Each keyword is searched on its own and every product keeps the keyword and its position in the results. Leave empty when you give offer ids or links. Also read from queries. |
maxItemsPerKeyword | integer | How many products to return per keyword, for example 120. Default: 60. A results page holds 60 products and 1688 shows at most 2,000 per search, so 2,000 is the ceiling. Also read from maxResults or maxProducts (other 1688 actors' names). |
sort | string | Order of the results: best match (default), most sold in the last 30 days, or price. Example: priceAsc. Also read from sortBy (bestSelling = sales) or sortType (va_rmdarkgmv30 = sales). |
includeDetails | boolean | Opens the product page of every keyword result and adds SKUs with stock, attributes, freight, ratings and the exact sold count. Costs more per product (the Product with details price) and runs slower. Offer ids and links always return details. Default: false. Also read from includeSkuDetails or enrichDetails. |
Example input:
{
"keywords": [
"保温杯"
],
"maxItemsPerKeyword": 50,
"sort": "relevance",
"includeDetails": false
}
2. Over the Apify API
The synchronous endpoint runs the actor and returns its rows in one call (for runs up to about five minutes; use the asynchronous run endpoint for longer ones).
curl -X POST "https://api.apify.com/v2/acts/arcadium~1688-products/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"keywords":["保温杯"],"maxItemsPerKeyword":50,"sort":"relevance","includeDetails":false}'
3. From JavaScript
// npm install apify-client
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('arcadium/1688-products').call({
"keywords": [
"保温杯"
],
"maxItemsPerKeyword": 50,
"sort": "relevance",
"includeDetails": false
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
4. From Python
# pip install apify-client
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("arcadium/1688-products").call(run_input={
"keywords": ["保温杯"],
"maxItemsPerKeyword": 50,
"sort": "relevance",
"includeDetails": False,
})
items = client.dataset(run.default_dataset_id).list_items().items # apify-client 3.x returns a Run object
print(items)
5. In n8n
Paste this node into a workflow (it is a plain HTTP Request node). Create a Header Auth credential with name Authorization and value Bearer <APIFY_TOKEN>; each returned row becomes one item for the next node.
{
"nodes": [
{
"name": "Run arcadium/1688-products",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
0,
0
],
"parameters": {
"method": "POST",
"url": "https://api.apify.com/v2/acts/arcadium~1688-products/run-sync-get-dataset-items",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\"keywords\":[\"保温杯\"],\"maxItemsPerKeyword\":50,\"sort\":\"relevance\",\"includeDetails\":false}",
"options": {
"timeout": 300000
}
}
}
],
"connections": {}
}
6. From an AI assistant (MCP)
Add Apify’s MCP server to Claude Desktop, Cursor, VS Code or any MCP client, limited to this actor:
{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com/?tools=arcadium/1688-products",
"headers": {
"Authorization": "Bearer <APIFY_TOKEN>"
}
}
}
}
More on the MCP page.
7. From LangChain
# pip install langchain-apify (reads APIFY_API_TOKEN from the environment)
from langchain_apify import ApifyActorsTool
tool = ApifyActorsTool("arcadium/1688-products")
rows = tool.invoke({"run_input": {
"keywords": ["保温杯"],
"maxItemsPerKeyword": 50,
"sort": "relevance",
"includeDetails": False,
}})
# or give `tool` to an agent: create_react_agent(llm, [tool])
Sample output
One row, from the example in the actor’s README. Long text is shortened and lists are cut to two items.
{
"rowType": "product",
"platform": "1688",
"offerId": "866095761513",
"url": "https://detail.1688.com/offer/866095761513.html",
"title": "数据线保护套硅胶防折断充电线保护套咬线器防断裂神器",
"keyword": "数据线",
"rank": 2,
"isAd": false,
"currency": "CNY",
"priceMin": 2.5,
"priceMax": 2.6,
"priceTiers": [
{
"minQty": 3,
"maxQty": 4999,
"price": 2.6
},
{
"minQty": 5000,
"maxQty": 99999,
"price": 2.55
}
],
"moq": 3,
"unit": "件",
"soldCount": 100000,
"soldText": "已售10万+件",
"soldScope": "offer",
"repurchaseRate": 17,
"origin": {
"province": "广东",
"city": "东莞市"
},
"supplier": {
"companyName": "东莞市元拓橡塑制品有限公司",
"memberId": "b2b-22072902285003c713",
"isFactory": true,
"yearsOnPlatform": 7,
"serviceScores": {
"composite": 4,
"consultation": 4,
"logistics": 3.57,
"dispute": 5,
"returns": 3.67,
"goods": 3.33
},
"repurchaseRate3m": 77,
"shopUrl": "https://apetop.1688.com"
},
"hasDetails": false
}
| Field | What it holds |
|---|---|
rowType | Kind of row. Filter on this first. 'product': one 1688 offer (charged); 'coverage': per-keyword completeness (free); 'error': an input failed (free). |
platform | Always '1688'. |
offerId | 1688 offer id, the number in the product link. Stable key for joins and monitoring. |
url | Product page link on detail.1688.com. |
title | Product title as the seller wrote it, usually Chinese; contact data removed. |
keyword | Search keyword that found the offer; null for offers requested by id or link. |
rank | Position in the keyword's results, paid placements included; null for id lookups. |
isAd | True when the row is a paid placement in the search results. |
images | Product image links. |
currency | Currency of all prices, always CNY (Chinese yuan). |
priceMin | Lowest unit price in CNY. |
priceMax | Highest unit price in CNY. |
priceTiers | Wholesale steps by quantity: {minQty, maxQty, price}. Empty when each variant is priced on its own. |
moq | Minimum order quantity. |
unit | Selling unit, e.g. 件 or 个. |
soldCount | Units sold; a lower bound on search rows, the exact total with details. |
soldText | Sold figure as 1688 shows it, e.g. '已售500+件'. |
soldScope | 'offer' for this listing, 'network' for the whole product across the web. |
bookedCount | Number of orders shown on the search card. |
repurchaseRate | Share of buyers who reordered this offer, 0-100. |
origin | Dispatch location: province and city. |
serviceTags | Service badges, e.g. 深度验厂 (inspected factory) or 退货包运费. |
supplier | Supplier facts: companyName, memberId, isFactory, isSuperFactory, factoryInspected, yearsOnPlatform, serviceScores, repurchaseRate3m, shopUrl. |
skus | Details only: variants as {skuId, attrs, price, stock, sold}. |
attributes | Details only: product parameters as {name, value}, e.g. material or brand. |
freight | Details only: dispatch promise text, shipsFrom, free flag and an indicative fee in CNY. |
rating | Details only: buyer review score, goodRatePct and reviewCount. |
videoUrl | Details only: main product video link. |
category | Category id; the name is added with details. |
hasDetails | True when the row carries the detail page fields (skus, attributes, freight, rating). |
scrapedAt | ISO time the row was collected. |
stated | Coverage rows: total results 1688 reports for the keyword. |
delivered | Coverage rows: how many products were delivered for the keyword. |
stopReason | Coverage rows: why the search stopped: limit, end, cap, filter, budget or error. |
shortfall | Coverage rows: true when fewer were delivered than reported with no cap or filter to explain it. |
input | Coverage and error rows: the keyword or offer the row is about. |
code | Error rows: invalid_input, not_found, no_match, blocked or unavailable. |
message | Error rows: what went wrong, in plain words. |
Tutorials
Schedule it
In Apify Console, create a Task from your input and add a Schedule (for example daily). Each run writes a new dataset; integrations can push the rows to Google Sheets, Slack, a webhook or your database.