# 1688.com Wholesale Scraper — Pay Per Product, No Subscription (`prodiger/1688-scraper`) Actor

Scrape 1688.com — Alibaba's Chinese B2B wholesale marketplace — for product titles, prices, sales volume, return rates, supplier years, and city. The only PPE 1688 scraper on Apify Store: pay per product, not per month. Pure HTTP, no API key, no captcha.

- **URL**: https://apify.com/prodiger/1688-scraper.md
- **Developed by:** [Arnas](https://apify.com/prodiger) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 86 total users, 5 monthly users, 83.9% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 product scrapeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 1688.com Scraper

The **only pay-per-event** 1688.com search scraper on Apify Store. Extract B2B wholesale product data — titles, prices, sales volume, return rates, supplier years, location, factory/verified flags — from China's largest wholesale marketplace, without an API key, login, or browser.

Every other 1688 scraper on Store is **monthly subscription** ($30+/month). This one charges only when you actually run it. No commitment, no idle-month bills.

### What does 1688.com Scraper do?

- Searches [1688.com](https://www.1688.com) for one or many keywords (Chinese or English).
- Extracts **22 fields per product card** including title, price, 30-day sales count, return rate, supplier years on platform, city, image, free-shipping/return tags, and factory/verified-supplier flags.
- Supports filters that match 1688's UI: price range, MOQ, sort by sales / price / composite score, and toggling between consumer (`pcmarket`) and industrial (`pcindustry`) marketplaces.
- Runs without a 1688 account, login, or API key. Pure HTTP via Apify's CN-region residential proxy network.
- Bills per product extracted (PPE) — pay only for what you actually scrape.

Try it on the **Try Actor** tab in Apify Console with the prefilled `wireless headphones` example.

### Why use 1688.com Scraper?

- **Source directly from Chinese manufacturers.** Bypass middlemen and find factory-direct pricing for retail or private-label work.
- **Compare suppliers at scale.** Pull thousands of cards across keyword variants in one run; sort by 30-day sales to filter for proven products.
- **Industrial procurement.** The `searchType: pcindustry` mode targets equipment, raw materials, and high-MOQ B2B listings.
- **No subscription.** Run the actor once a quarter, once a day, or once an hour — you only pay per product extracted, not a flat monthly fee. Other 1688 scrapers charge $30+/month flat. This is the only PPE option in the category.

### How to use 1688.com Scraper

1. Open the actor on Apify Console and click **Try Actor**.
2. Either fill **Search keyword** for a single search, or use the **Search array** field for multiple queries (e.g., one row per keyword variant).
3. Set filters: **Max pages per search** (1 page = 20 cards on the mobile route), price range, sort, MOQ, marketplace (`pcmarket` vs `pcindustry`).
4. Leave **Proxy** on the default `RESIDENTIAL` group with country `CN` — 1688's mobile route only serves SSR product data to CN-region residential traffic.
5. **Save & start.** When the run completes, click the **Output** tab to view the dataset, or download as JSON / CSV / Excel / XML / JSONL.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `keyword` | string | one of `keyword`/`searchArray` | A single search term. Chinese or English. UTF-8. |
| `searchArray` | array | one of `keyword`/`searchArray` | Run multiple searches in one execution. Each entry can override `maxPages`, `priceStart`, `priceEnd`, `sortType`, `descendOrder`, `quantityBegin`, `searchType`. |
| `maxPages` | integer | no (default `1`) | Pages per search. Max `50`. 1 page = 20 mobile cards; 1688's mobile pool recycles offers past ~50 pages. |
| `priceStart` / `priceEnd` | string | no | CNY price bounds. Numeric strings. |
| `sortType` | enum | no (default `normal`) | `normal` / `va_sales360` (sales-30d) / `pricedesc` / `priceasc` / `composite`. |
| `descendOrder` | boolean | no (default `true`) | Flips the sort direction. |
| `quantityBegin` | integer | no (default `0`) | MOQ filter. |
| `searchType` | enum | no (default `pcmarket`) | `pcmarket` (consumer) or `pcindustry` (industrial). |
| `maxRequestRetries` | integer | no (default `5`) | Retry budget for failed requests. |
| `proxyConfiguration` | object | no | Standard Apify proxy config. RESIDENTIAL with country=CN required. |

#### Example input

```json
{
    "searchArray": [
        {
            "keyword": "wireless headphones",
            "maxPages": 5,
            "priceStart": "50",
            "priceEnd": "200",
            "sortType": "va_sales360"
        },
        {
            "keyword": "bluetooth speakers",
            "maxPages": 3
        }
    ]
}
```

### Output

You can download the dataset in JSON, CSV, Excel, XML, HTML, or JSONL from the Storage tab.

#### Sample record

```json
{
    "searchKeyword": "LED",
    "id": 41565957172,
    "shop_id": "",
    "url": "https://detail.1688.com/offer/41565957172.html",
    "shop_url": "",
    "title": "外贸跨境爆款LED熔岩手表二进制led学生情侣表LED电子手表链条手",
    "price": 7.03,
    "original_price": 7.03,
    "currency": "CNY",
    "image": "https://cbu01.alicdn.com/img/ibank/O1CN01ulHSGA1kLzlQzDss6_!!1943604668-0-cib.jpg_270x270xzq60.jpg",
    "seller": "",
    "location": "深圳市",
    "seller_type": "",
    "seller_years": 12,
    "sales": 1000,
    "return_rate": "55",
    "position": 1,
    "tags": [],
    "price_tiers": [],
    "is_factory": false,
    "is_verified": false,
    "scrapedAt": "2026-04-29T14:17:19.376Z"
}
```

#### Data table

| Field | Type | Description |
|-------|------|-------------|
| `searchKeyword` | string | The keyword that produced this record. |
| `id` | number | 1688 `offerId`. |
| `shop_id` | string | Empty in v0.1 — supplier `memberId` requires a detail-page fetch. |
| `url` | string | Canonical product detail URL. |
| `shop_url` | string | Empty in v0.1 — storefront URL requires a detail-page fetch. |
| `title` | string | Product title (Chinese; HTML highlight tags stripped). |
| `price` | number | Single-unit displayed price (CNY). |
| `original_price` | number | Equals `price` in v0.1 (mobile search doesn't expose discount info). |
| `currency` | string | Always `CNY`. |
| `image` | string | Primary product image (CDN). |
| `seller` | string | Empty in v0.1 — supplier `loginId` requires a detail-page fetch. |
| `location` | string | City (mobile route omits the province). |
| `seller_type` | string | Empty in v0.1 — `bizType` requires a detail-page fetch. |
| `seller_years` | number/null | Years on the platform (when card displays the trust badge). |
| `sales` | number/null | Recent sales count (parsed from `已售N件`). |
| `return_rate` | string/null | Repurchase rate as a numeric string (no `%`). |
| `position` | integer | 1-based rank within search results. |
| `tags` | string\[] | Service/promo tags (`包邮`, `深度验商`, etc.). |
| `price_tiers` | array | Empty in v0.1 — quantity-tiered prices are only on detail pages. |
| `is_factory` | boolean | Factory inspection passed (when card has `深度验厂` tag). |
| `is_verified` | boolean | Business inspection passed (when card has `深度验商` tag). |
| `scrapedAt` | string | ISO 8601 run timestamp. |

**Why some fields are empty in v0.1:** the 1688 mobile search page exposes ~22 useful fields per card; the rest (`shop_id`, `shop_url`, `seller`, `seller_type`, `price_tiers`) live on the per-product detail page. Detail-page enrichment 4× the per-record runtime and cost; it is deferred to a separate "1688 Product Details Scraper" actor. Open an issue if you need this in v0.1.

### Pricing — premium pay per event

This actor is the **only PPE 1688 scraper on Store** — every alternative is a $30+/month subscription.

| Event | FREE | BRONZE | SILVER | GOLD | PLATINUM | DIAMOND |
|-------|------|--------|--------|------|----------|---------|
| `actor_start` | $0.05 | $0.05 | $0.05 | $0.05 | $0.05 | $0.05 |
| `product` | $0.025 | $0.020 | $0.015 | $0.010 | $0.0065 | $0.0045 |

#### How much does it cost to scrape 1688.com?

| Workload | Products | Approx. cost (FREE tier) |
|----------|----------|--------------------------|
| 1 search × 1 page | ~20 | ~$0.55 |
| 1 search × 5 pages | ~100 | ~$2.55 |
| 1 search × 25 pages | ~500 | ~$12.55 |
| 5 searches × 5 pages | ~500 | ~$12.55 |

**PPE vs $30/month subscription breakeven:** ~1,200 products extracted at FREE tier. If you scrape <1.2k products/month, this actor is cheaper. If you scrape >1.5k/month consistently, a competitor's monthly subscription will be cheaper — that's the trade-off PPE makes explicit.

DIAMOND tier ($4.50/1k) is roughly 5× cheaper than FREE; Apify's standard plan-tier dilution applies.

### Tips and advanced options

#### Working around the 3,000-result cap

1688 caps total search results at ~3,000 items per query (the mobile pool is even shallower at ~1k unique offers). To pull more in a single keyword:

- **Split by price range.** Run the same keyword twice with `priceStart: "10", priceEnd: "50"` and `priceStart: "50", priceEnd: "100"`.
- **Use multiple narrower keywords.** Instead of `"electronics"`, scrape `"wireless earbuds"` and `"smart watches"` separately.
- **Sort and slice.** Use `sortType: "pricedesc"` and `sortType: "priceasc"` runs to capture the high-end and low-end tails.
- **Use `searchType: pcindustry`.** The industrial market has a separate result pool from `pcmarket`.

#### Combining filters

Combine `quantityBegin`, `priceStart`, `searchType`, and `sortType` for highly targeted searches — e.g. industrial procurement of hydraulic valves with MOQ ≥ 100:

```json
{
    "searchType": "pcindustry",
    "searchArray": [{ "keyword": "hydraulic valves", "quantityBegin": 100, "maxPages": 10 }]
}
```

#### Why RESIDENTIAL + CN proxies?

1688's mobile route only SSRs offer cards for CN-region residential traffic. PC route is fully client-rendered + login-walled outside CN. Datacenter ranges are hard-blocked. CN-region residential is the only reliable choice — and the actor's default.

### FAQ

**Does this work without a 1688 account?**
Yes. The scraper hits 1688's public mobile search results — no login required.

**Why are titles and locations in Chinese?**
1688 is a domestic Chinese marketplace. Translation is intentionally out of scope — run the dataset through an LLM downstream if you need English titles. Keeping the source language preserves accuracy for procurement workflows.

**Why is `shop_id` / `seller` / `price_tiers` empty?**
v0.1 scrapes the mobile search-results page only. Those fields live on the per-product detail page and require an extra fetch per offer (4× the runtime + cost). Deferred to a separate detail-page actor. Open an issue if you need these in this actor.

**What if a search returns 0 products?**
The run completes successfully with an empty dataset and only the `actor_start` charge.

**Can I cancel a run mid-way to stop charging?**
Yes. The actor handles the abort signal cleanly and exits within ~1 second. You're charged only for products already pushed to the dataset.

### Disclaimers

This actor accesses publicly available 1688.com mobile search-result pages. Users are responsible for complying with 1688.com's Terms of Service, Chinese law, and any applicable data-protection regulations. The scraper does not bypass authentication, login walls, or paid memberships, and does not extract personally identifiable seller information beyond what 1688 publishes openly.

### Support and feedback

Open an issue on the actor's **Issues** tab in Apify Console for bugs, parsing regressions, or feature requests (e.g., per-product detail enrichment, additional fields).

# Actor input Schema

## `keyword` (type: `string`):

A single search term (Chinese or English). Either 'keyword' or 'searchArray' must be provided. UTF-8.

## `searchArray` (type: `array`):

Run multiple searches in one actor execution. Each entry can override 'maxPages', 'priceStart', 'priceEnd', 'sortType', 'descendOrder', 'quantityBegin', and 'searchType' for that query. Per-entry filters fall back to the top-level values when omitted.

## `maxPages` (type: `integer`):

Number of result pages to fetch per search (1 page = 20 product cards on 1688's mobile route). The mobile pool recycles offers past ~50 pages, so this is hard-capped at 50.

## `priceStart` (type: `string`):

Lower price bound, in CNY. Numeric string like "50.00". Leave empty for no lower bound.

## `priceEnd` (type: `string`):

Upper price bound, in CNY. Numeric string like "200.00". Leave empty for no upper bound.

## `sortType` (type: `string`):

How 1688 ranks the results. 'va\_sales360' = sort by 30-day sales volume.

## `descendOrder` (type: `boolean`):

Flips the sort direction on price/sales sorts.

## `quantityBegin` (type: `integer`):

Minimum-order-quantity (MOQ) filter. 0 = no filter.

## `searchType` (type: `string`):

Switches between 1688's consumer marketplace and its industrial market. Industrial mode favors equipment, raw materials, and B2B-volume listings.

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

Retry attempts for failed requests (429, 5xx, anti-bot challenges, network errors).

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

Apify proxy. RESIDENTIAL with country=CN is REQUIRED — 1688's mobile route only SSRs offer data for CN-region traffic and hard-blocks datacenter ranges. Override only if you understand the trade-off.

## Actor input object example

```json
{
  "keyword": "LED lights",
  "searchArray": [
    {
      "keyword": "wireless headphones",
      "maxPages": 3,
      "priceStart": "50",
      "priceEnd": "200",
      "sortType": "va_sales360"
    }
  ],
  "maxPages": 1,
  "sortType": "normal",
  "descendOrder": true,
  "quantityBegin": 0,
  "searchType": "pcmarket",
  "maxRequestRetries": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "CN"
  }
}
```

# Actor output Schema

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

Scraped product cards with pricing, seller, and sales metadata.

# 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 = {
    "searchArray": [
        {
            "keyword": "wireless headphones",
            "maxPages": 3,
            "priceStart": "50",
            "priceEnd": "200",
            "sortType": "va_sales360"
        }
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "CN"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("prodiger/1688-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 = {
    "searchArray": [{
            "keyword": "wireless headphones",
            "maxPages": 3,
            "priceStart": "50",
            "priceEnd": "200",
            "sortType": "va_sales360",
        }],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "CN",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("prodiger/1688-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 '{
  "searchArray": [
    {
      "keyword": "wireless headphones",
      "maxPages": 3,
      "priceStart": "50",
      "priceEnd": "200",
      "sortType": "va_sales360"
    }
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "CN"
  }
}' |
apify call prodiger/1688-scraper --silent --output-dataset

```

## MCP server setup

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