# JD.com Products Scraper 京东 — Prices, Variants, Barcodes & Stock (`memo23/jd-com-price-scraper`) Actor

JD.com (京东 / Jingdong) products scraper with no login: search by keyword or paste SKU ids and product links. Get every variant with its real CNY price (not ¥1??9), stock, delivery, barcode, brand, shop, reviews and rating, or a fast, cheaper search-results-only sweep.

- **URL**: https://apify.com/memo23/jd-com-price-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** E-commerce
- **Features:** Limited permissions
- **Stats:** 11 total users, 5 monthly users, 94.6% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 skus

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

## JD.com Products Scraper 京东 — Prices, Variants, Barcodes & Stock

Get the real price of every variant of a JD.com (京东 / Jingdong) product: each color, storage size, bundle and pack, with its own CNY price, stock state, delivery promise and subsidy flags. Paste SKU ids, product links, a search, or a whole shop's catalog — or just drop any JD address into **Start URLs** and it sorts itself out. No JD account, no cookies, no proxy setup.

Signed-out, JD shows prices on product pages masked as `¥1??9`. This actor returns the full number for every SKU.

Need a fast price sweep across many keywords? Turn on **Search results only**: each keyword result is saved as one row straight from JD's listing card (real price, review count, positive rate, review tags, shop, image) without the variant lookup, at a lower price per row: $0.0015 a result. This mode starts on 22 November 2026; until then a run with it on looks up each result's variants as usual and says so in the log.

<p align="center">
  <img src="https://api.apify.com/v2/key-value-stores/eSeWSb9bMn2O7vwd8/records/how-it-works-jd-price.png" alt="How the JD.com price scraper works" width="900" />
</p>

### 中文说明

**京东商品价格采集，无需登录、无需 Cookie、无需设置代理。** 京东未登录时商品页价格显示为 `¥1??9`，本工具返回每个 SKU 的真实人民币价格：

- 输入：SKU ID、商品链接（item.jd.com、item.m.jd.com、wqitem.jd.com、npcitem.jd.hk）、分享文本、关键词（如 `华为手机`、`茅台`）、搜索链接，或店铺（`shopIds` 填店铺 ID 或 `mall.jd.com` 链接，整店采集，每店最多 168 个商品）。也可把任意京东网址都放进 `startUrls`，自动归类为商品、关键词或店铺
- 每个商品的全部规格（颜色、内存、套装），每个 SKU 单独的价格、库存状态、库存数量、配送时效、国补/预售/限购标记
- 关键词搜索：`maxProductsPerKeyword` 设为 5 以内取京东前 5 个商品；设为 6-500 则从京东热卖列表页翻页采集，并附带评价数（如「10万+」）、好评率、买家评价标签、上架时间
- 价格区间：`minPrice`、`maxPrice`，区间外的商品在查询规格前就被过滤，不收费
- 排序（`sortBy`）：京东默认顺序、价格从低到高、价格从高到低、评价最多、好评率最高、最新上架
- 店铺：店铺 ID、名称、链接、是否京东自营；品牌；EAN/UPC 条码
- 可选商品详情：图集、型号、类目、重量、保修、产地（`includeProductDetails`）
- 免费的京东相关搜索词（`includeSuggestions`）
- 仅搜索结果模式（`searchResultsOnly`）：每个关键词结果直接保存为一行（真实价格、评价数、好评率、评价标签、店铺、图片），不查询规格，速度更快，每行价格更低（2026 年 11 月 22 日起可用）

输入示例：

```json
{
    "keywords": ["蓝牙耳机"],
    "maxProductsPerKeyword": 50,
    "maxPrice": 300,
    "allVariants": false,
    "maxItems": 50
}
```

主要输出字段：`skuId`、`productId`、`title`、`price`、`inStock`、`stockState`、`stock`、`deliveryPromise`、`properties`、`isGovernmentSubsidy`、`barcodes`、`shopName`、`isJdSelf`、`reviewCountText`、`goodRate`、`reviewTags`、`searchKeyword`、`searchRank`。

价格：每个 SKU 行 $0.004，仅搜索结果模式每行 $0.0015，每个关键词 $0.005，商品详情每个商品 $0.004，每次运行启动费 $0.005。

### Why use this JD.com scraper?

- **Real prices, not `¥1??9`.** Every row has the numeric CNY price for that exact SKU.
- **Every variant in one run.** One product link returns all its SKUs (up to 100), each with its own price, stock and properties (`外观: 曜金黑【512GB】`).
- **Stock and delivery.** `inStock`, `stockState`, stock count when JD shows it, and the delivery promise text (`预计明天发货，后天送达`).
- **Subsidy and presale flags.** Government subsidy (国补), presale, purchase limits.
- **Shop and brand.** Shop id, name and link, the JD self-run (自营) flag, and the brand.
- **Barcodes.** EAN/UPC codes per SKU, cleaned of JD's placeholder zeros.
- **Whole shop catalogs.** Give a shop id or a `mall.jd.com` link and get its products, each looked up with full variants, price, stock and reviews — up to 168 products a shop.
- **Paste any JD address.** Product, search or shop links all go in one **Start URLs** box and are sorted into products, keywords and shops for you.
- **Optional product details.** Main image gallery, the long-description image gallery, model, category, weight, warranty and place of origin.
- **Deep keyword search.** Up to 500 products per keyword from JD's keyword listing pages, each with its review count (`10万+`), positive-review rate and the review tags buyers use most, before its variants are looked up. A price band drops products before they cost anything.
- **Fast, cheaper price sweeps.** With **Search results only** on, keyword results are saved straight from JD's listing cards at $0.0015 a row: price, review count, positive rate, review tags and shop for hundreds of products per keyword, without paying for variant lookups.
- **Free search suggestions.** The related searches JD shows for each keyword (`手机` → `苹果17pro max`, `红米k90`), to find the terms buyers type.

### Overview

The actor takes JD SKU ids, product links, keywords or shop ids. For each product it fetches the full variant list, then writes one dataset row per SKU. Keywords return JD's top 5 products by default. Set **Products per keyword** above 5 and the products come from JD's keyword listing pages (JD 热卖), up to 500 a keyword; those are the listings JD promotes for the keyword, in JD's order, and when the pages return nothing the run falls back to the top 5. A shop id brings that shop's catalog (up to 168 products). Each product, however it was found, is then expanded into its variants the same way.

### Supported inputs

| Input | Example |
|---|---|
| SKU id | `100012043978` |
| PC product link | `https://item.jd.com/100012043978.html` |
| Mobile product link | `https://item.m.jd.com/product/100012043978.html?from=share` |
| WeChat product link | `https://wqitem.jd.com/item/view?sku=100012043978` |
| JD Global (京东国际) link | `https://npcitem.jd.hk/100009475513.html` |
| Share text with a link inside | `【京东】茅台飞天 https://item.jd.com/100012043978.html` |
| Keyword | `华为手机`, `蓝牙耳机`, `茅台` |
| Search link | `https://search.jd.com/Search?keyword=茅台`, `https://re.jd.com/search?keyword=lego` |
| Shop id or shop link | `1000475228`, `https://mall.jd.com/index-1000475228.html` |

Everything above can go in one **Start URLs** box: product links and ids are scraped as products, search links as their keyword, shop links as that shop's catalog. Short links (`3.cn/…`, `u.jd.com/…`) only resolve in a browser — open them and paste the `item.jd.com` link.

### Use cases

- **Price monitoring.** Schedule a run over your SKU list and track price changes per variant.
- **Cross-border and dropshipping research.** Compare JD prices for the exact variant you sell.
- **Brand protection.** See which shops sell your products on JD and at what price.
- **Catalog matching.** Match JD SKUs to your catalog by barcode.
- **Stock tracking.** Watch when a variant goes out of stock or into presale.
- **Subsidy tracking.** See which SKUs carry the 国补 government-subsidy flag.

### How it works

1. You enter SKU ids, product links or keywords.
2. Keywords are searched first: JD's top 5, or up to 500 products from JD's keyword listing pages. Products outside your price band are dropped here.
3. For each product, the actor fetches every variant with its live price and stock. The SKU you entered always comes first.
4. With product details on, it adds the product page fields once per product.
5. Each SKU becomes one row. SKUs that appear under several inputs are returned once.

### Input configuration

| Field | Type | Default | What it does |
|---|---|---|---|
| `products` | list | — | SKU ids or product links, one per line |
| `startUrls` | list | — | Any JD address — product, search or shop — sorted into products, keywords and shops for you |
| `shopIds` | list | — | Shop ids or `mall.jd.com` links; each shop's whole catalog is scraped |
| `maxProductsPerShop` | integer | `50` | Products to pull from each shop, 1-168, before their variants are looked up |
| `keywords` | list | — | Search terms |
| `maxProductsPerKeyword` | integer | `5` | Products per keyword, 1-500. Above 5 they come from JD's listing pages, with review count, positive rate and review tags |
| `searchResultsOnly` | boolean | `false` | ON: keyword results are saved straight from their listing cards (price, reviews, shop), with no variant lookup, at the lower search-result price. SKU ids and links still return full variant rows |
| `sortBy` | string | `relevance` | Order of each keyword's products before lookup: `relevance` (JD's order), `priceAsc`, `priceDesc`, `mostReviews`, `bestRated`, `newest`. `searchRank` keeps JD's position |
| `minPrice` / `maxPrice` | number | — | Price band in CNY for keyword results and SKU rows. Products outside it are not looked up or billed |
| `searchKeywords` | boolean | `true` | OFF: keywords only feed suggestions, nothing is searched or charged |
| `includeSuggestions` | boolean | `false` | Save JD's related searches per keyword to the `SUGGESTIONS` record (free) |
| `allVariants` | boolean | `true` | ON: every variant. OFF: only the SKU you entered |
| `maxVariantsPerProduct` | integer | `100` | Cap on variants per product (max 100) |
| `includeProductDetails` | boolean | `false` | Add the main gallery, the long-description image gallery, model, category id and name, weight, warranty, origin |
| `onlyInStock` | boolean | `false` | Drop SKUs that cannot be ordered now |
| `maxItems` | integer | `1000` | Cap on rows for the run (free plan: 100) |

Example input:

```json
{
    "products": ["100012043978", "https://item.jd.com/10233787625364.html"],
    "keywords": ["蓝牙耳机"],
    "allVariants": true,
    "maxVariantsPerProduct": 20,
    "includeProductDetails": false
}
```

To refresh prices on a known SKU list cheaply, set `allVariants` to `false`: one row per SKU you entered.

### Output overview

One row per SKU (`detailLevel` `sku`, or `full` with product details). With **Search results only**, each keyword result is one row with `detailLevel` `listing`: price, review count, positive rate, review tags, shop and image, but no stock, barcode or variant fields. Rows from the same product share `productId`. `sourceInput` says which id, link or keyword produced the row, and keyword rows also carry `searchKeyword`, `searchRank`, and from the listing pages `reviewCountText`, `goodRate`, `reviewTags` and `listedAt`.

### Output sample

A real row from keyword `蓝牙耳机` with product details on:

```json
{
    "skuId": "100207440191",
    "productId": "100104950402",
    "isRequestedSku": true,
    "title": "Viken【2026最新款丨柏林之声第1名】骨传导蓝牙耳机耳夹式概念无线开放式运动跑步超长续航不入耳挂耳",
    "url": "https://item.jd.com/100207440191.html",
    "mobileUrl": "https://item.m.jd.com/product/100207440191.html",
    "price": 198,
    "currency": "CNY",
    "onSale": true,
    "inStock": true,
    "stockState": "in_stock",
    "stock": null,
    "purchaseLimit": null,
    "deliveryPromise": "23:10前付款，预计明天(10月19日)送达",
    "isPresale": false,
    "isGovernmentSubsidy": true,
    "isBillionSubsidy": null,
    "isFlashSale": null,
    "promoTags": [],
    "properties": {
        "版本": "【12重空间音效丨ENC通话降噪】",
        "颜色": "【京东独家】星际黑丨APP升级版"
    },
    "color": "【京东独家】星际黑丨APP升级版",
    "size": "【12重空间音效丨ENC通话降噪】",
    "brand": "维肯（Viken）",
    "barcodes": ["6941463424375", "6979854450061", "6979854453161"],
    "imageUrl": "https://img14.360buyimg.com/n0/jfs/t1/528727/28/4600/117062/6aaf4700F357ff9f3/0083320320641c06.jpg",
    "shopId": "1000462847",
    "shopName": "维肯（Viken）京东自营旗舰店",
    "shopUrl": "https://mall.jd.com/index-1000462847.html",
    "isJdSelf": true,
    "variantCount": 1,
    "detailLevel": "full",
    "sourceInput": "蓝牙耳机",
    "searchKeyword": "蓝牙耳机",
    "searchRank": 1,
    "model": "i113",
    "categoryId": "842",
    "weight": null,
    "warranty": "1年质保",
    "productArea": null,
    "isJdExpress": false,
    "imageUrls": [
        "https://img14.360buyimg.com/n1/jfs/t1/528727/28/4600/117062/6aaf4700F357ff9f3/0083320320641c06.jpg"
    ],
    "scrapedAt": "2026-10-18T11:23:06.396Z"
}
```

Without product details, rows stop at `searchRank` and `detailLevel` is `sku`.

#### Search suggestions

With `includeSuggestions` on, the run's key-value store gets a `SUGGESTIONS` record, one entry per keyword (real output for `茅台`):

```json
[
    {
        "keyword": "茅台",
        "suggestions": [
            { "keyword": "茅台53度飞天", "searchKey": "茅台53度飞天", "keywordType": 1, "iconUrl": null },
            { "keyword": "茅台飞天礼盒", "searchKey": "茅台飞天礼盒", "keywordType": 1, "iconUrl": null },
            { "keyword": "茅台迎宾", "searchKey": "茅台迎宾", "keywordType": 1, "iconUrl": null }
        ],
        "error": null
    }
]
```

Suggestions are not dataset rows and are not charged. They cover the first 100 keywords of a run. To get only suggestions, turn `searchKeywords` off.

### Key output fields

| Field | Meaning |
|---|---|
| `skuId` | JD SKU id (one color/size/bundle) |
| `productId` | Product group id shared by all variants. Not a SKU; it cannot be used as input |
| `isRequestedSku` | `true` on the SKU you entered or the one search returned |
| `price` | Live CNY price of this SKU, as shown signed-out in JD's default delivery region |
| `inStock` | Can be ordered now. Presale and reservation SKUs are `false` |
| `stockState` | JD's stock state code (`in_stock`, `out_of_stock`, …) |
| `stock` | Stock count when JD shows one; `null` means not shown, not zero |
| `deliveryPromise` | JD's delivery text for the default region |
| `properties` | Sale properties of this SKU, name → value, as JD writes them |
| `isGovernmentSubsidy` | JD flags the SKU for the 国补 subsidy. The flag alone does not say whether `price` already includes it |
| `barcodes` | EAN/UPC codes for the SKU |
| `variantCount` | How many SKUs the product has. Larger than the rows returned means `maxVariantsPerProduct` cut it |
| `reviewCountText` | Review count as JD prints it, e.g. `10万+` (keyword rows) |
| `goodRate` | Share of positive reviews, 0-100 (keyword rows) |
| `reviewTags` | What buyers mention most, e.g. `音质清晰` (keyword rows from the listing pages) |
| `listedAt` | When the product went on sale on JD (keyword rows from the listing pages) |
| `detailLevel` | `sku` (variant row), `full` (with product details) or `listing` (a keyword result from **Search results only**) |
| `salesText` | Sales as JD's listing card prints them, e.g. `已售5万+`, when shown (`listing` rows) |
| `imageUrls` | Main product gallery (with product details on) |
| `detailImages` | The long-description image gallery, in page order (with product details on) |
| `categoryName` | JD category name, when the product page gives one (with product details on) |
| `sourceShopId` | The shop id a row was scraped from, when the input was a shop catalog |

### Coming from another JD.com scraper?

| What you need | This actor |
|---|---|
| The real price, not `¥1??9` | Every SKU row has the numeric CNY price for that exact variant |
| Every variant of a product | One link returns all its SKUs (up to 100), each with price, stock and properties |
| Many products per keyword | Up to 500 per keyword, with review count, positive rate and review tags |
| A price band | `minPrice` / `maxPrice` drop products before they are looked up, so they cost nothing |
| Sort by price, reviews or newest | `sortBy` orders each keyword's products before lookup, so your row cap keeps the cheapest, most-reviewed or newest |
| Paste links you already have | SKU ids, PC, mobile, WeChat and JD Global links, search links, shop links or share text, all in one **Start URLs** list |
| A whole shop's catalog | A shop id or `mall.jd.com` link returns its products (up to 168), each with full variants, price, stock and reviews |
| Stock and delivery | `inStock`, `stockState`, the stock count JD shows, and the delivery promise |
| Barcodes for catalog matching | EAN/UPC per SKU, placeholder zeros removed |
| Every product image | Main gallery plus the long-description image gallery (`detailImages`) with product details on |
| A fast, cheap price sweep | **Search results only**: one row per keyword result from JD's listing card, $0.0015 a row, no variant lookups |

Field names differ from other JD actors: the SKU id is `skuId`, the numeric price is `price`, variants are separate rows grouped by `productId`.

### FAQ

**Why are the prices different from what I see in the JD app?**
Prices are JD's signed-out prices for its default delivery region. Member prices (PLUS), coupons applied at checkout and region-specific prices can differ.

**Why did a product return fewer variants than `variantCount`?**
JD's variant list does not always load in full. The actor asks a second time when a product comes back empty or short, and keeps the longer answer. If a run still shows fewer rows than `variantCount`, run that product again or pass the missing SKU ids directly.

**Why did I get one row with `inStock: null` instead of every variant?**
When JD's variant list is briefly unavailable, the actor still returns the SKU you asked for, read from its product page: title, price, shop, brand and `variantCount`, without stock fields. You pay for that one row only. Run the product again a few minutes later to get every variant.

**Why is `stock` often `null`?**
JD only shows a count for some SKUs. `inStock` and `stockState` are always filled.

**Can I get more than 5 products per keyword?**
Yes: set **Products per keyword** up to 500. Above 5 the products come from JD's keyword listing pages (about 30 new products per page). These are the listings JD promotes for the keyword, in JD's order, so they are not the same list as JD's signed-in organic ranking. When those pages return nothing, the run falls back to JD's top 5 and says so in the log.

**How does sorting work?**
`sortBy` sorts the products a keyword brought (up to **Products per keyword**) by the price, review count, positive rate or listing date on JD's search card, then looks them up in that order. It does not re-rank all of JD: raise **Products per keyword** to sort a larger pool. Products missing the value go last.

**What does "Search results only" return?**
Available from 22 November 2026. One row per keyword result, taken from JD's listing card: title, real price, review count, positive rate, review tags, shop, JD self-run flag, category, image and listing date. It skips the variant lookup, so rows have no stock, barcode, delivery or per-variant prices, and they cost $0.0015 each instead of the SKU-row price. The results are the listings JD promotes for the keyword, in JD's order. SKU ids and product links in the same run still return full variant rows.

**Can I scrape a whole shop's catalog?**
Yes. Put a shop id (`1000475228`) or a shop link (`https://mall.jd.com/index-1000475228.html`) in **Shop ids**, or drop the shop link into **Start URLs**. Each product the shop lists is looked up with its variants, price, stock and reviews, up to **Products per shop** (max 168). Set `allVariants` off for one row per product.

**Do you return review text?**
Keyword and shop rows carry the review count, positive rate and review tags. For full review text, photos and ratings use the [JD.com Reviews Scraper](https://apify.com/memo23/jd-com-reviews-scraper).

**Why do `isBillionSubsidy` and `promoTags` come back empty?**
They are filled only when JD tags the SKU. Most SKUs carry no tag.

**Where are the search suggestions?**
In the run's key-value store, record `SUGGESTIONS` (Storage tab → Key-value store), not in the dataset. JD usually returns 10 per keyword.

**English keywords?**
They work, but JD titles are in Chinese, so Chinese keywords match better.

### Support

Found a problem or need a field? Open an issue on the actor's Issues tab and include the run id.

### Additional services

Need a custom JD dataset, a scheduled price feed, or another Chinese marketplace? Reach out through the Issues tab.

### Explore more scrapers

- [JD.com Reviews Scraper 京东评价](https://apify.com/memo23/jd-com-reviews-scraper) — buyer reviews with rating, text, photos and the variant bought
- [JD.com Search Scraper](https://apify.com/memo23/jd-search-playwright) — JD search results and keyword suggestions
- [Taobao Scraper 淘宝](https://apify.com/memo23/taobao-scraper) — Taobao and Tmall products, variants and reviews
- [1688 Wholesale Scraper](https://apify.com/memo23/1688-wholesale-scraper)
- [1688 Image Search](https://apify.com/memo23/1688-image-search-scraper)
- [1688 Product Details Scraper](https://apify.com/memo23/1688-product-details-scraper)
- [Alibaba Scraper](https://apify.com/memo23/alibaba-scraper)
- [AliExpress Scraper](https://apify.com/memo23/aliexpress-scraper)
- [Temu Product Scraper](https://apify.com/memo23/temu-scraper)
- [Goofish (闲鱼) Scraper](https://apify.com/memo23/goofish-xianyu-scraper)

### 🤖 For AI agents & LLM apps

Call this actor through the Apify API or the Apify MCP server. Minimal input: `{"products": ["<sku id or item.jd.com link>"]}`, or `{"keywords": ["蓝牙耳机"], "maxProductsPerKeyword": 30, "allVariants": false}` for a priced product list, or `{"shopIds": ["1000475228"], "maxProductsPerShop": 50, "allVariants": false}` for a shop's catalog, or add `"searchResultsOnly": true` for the cheapest per-row price sweep. Each output row is one SKU with a numeric `price` in CNY, so variants compare without text parsing. Use `allVariants: false` when you only need the price of the SKUs you passed. `productId` groups variants of the same product.

### ⚠️ Disclaimer

This actor is not affiliated with, endorsed by, or connected to JD.com, Inc. or any of its subsidiaries. It collects publicly visible product information. You are responsible for using the data in line with JD.com's terms, applicable laws, and data-protection rules in your jurisdiction.

### SEO Keywords

JD.com scraper, JD products scraper, JD.com products, JD product search scraper, JD scraper, JD price scraper, JD shop scraper, JD shop catalog scraper, Jingdong scraper, 京东商品搜索, 京东爬虫, 京东价格, 京东商品数据, 京东店铺采集, JD SKU scraper, JD.com product prices, JD stock tracker, China e-commerce prices, JD price monitoring, JD variants, JD barcode lookup, Chinese marketplace scraper, JD.com API alternative, JD keyword search scraper, JD search results, 京东搜索, 京东商品采集, 京东数据采集, 京东评价数, 京东好评率, 京东SKU

# Actor input Schema

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

One per line: a numeric SKU id (`100012043978`), a product link (`https://item.jd.com/100012043978.html`, `https://item.m.jd.com/product/100012043978.html`, `wqitem.jd.com` links) or share text that contains one. Short links (`3.cn`, `u.jd.com`) only open in a browser: open them and paste the item.jd.com link.

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

Paste any JD.com address and it is sorted for you: a product link or SKU id is scraped as a product, a search link (`https://search.jd.com/Search?keyword=茅台`, `https://re.jd.com/search?keyword=lego`) is run as its keyword, and a shop link (`https://mall.jd.com/index-1000475228.html`) is scraped as that shop's catalog. Mix them freely; anything not recognised is skipped with a note.

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

One per line, to scrape each shop's whole catalog: a shop id (`1000475228`) or a shop link (`https://mall.jd.com/index-1000475228.html`). Each product the shop lists is looked up with its variants, price, stock and reviews like the ids above. **Products per shop** below caps each shop; **Maximum SKU rows in total** caps the run.

## `keywords` (type: `array`):

Chinese works best (`华为手机`, `茅台`). Each keyword brings up to **Products per keyword** products, and each of those is fetched with its variants like the ids above. Up to 5, they are JD's own top 5; above 5 they come from JD's keyword listing pages (JD 热卖, promoted listings in JD's order), with the top 5 as a fallback when those pages return nothing.

## `searchKeywords` (type: `boolean`):

ON (default): each keyword returns JD's top 5 products with all their variants. OFF: keywords are only used for suggestions (below), and nothing is searched or charged for them.

## `maxProductsPerKeyword` (type: `integer`):

How many products each keyword brings into the run, 1-500. Default 5 (JD's top 5). Above 5, products come from JD's keyword listing pages, about 30 new products per page, each with its review count, positive-review rate and review tags; every product is then looked up with its variants and billed per SKU row. Maximum SKU rows in total still caps the run.

## `maxProductsPerShop` (type: `integer`):

How many products to pull from each shop catalog (see Shop ids), 1-168. Each is then looked up with its variants and billed per SKU row. Default 50. Maximum SKU rows in total still caps the run.

## `searchResultsOnly` (type: `boolean`):

ON: each keyword result is saved as one row straight from JD's listing card: title, real price, sales, review count, positive rate, review tags, shop and image. No variant lookup, so runs are faster and each row is billed at the lower search-result price. Good for price sweeps and market sizing across many keywords. Rows have no stock, barcode or per-variant data, and they follow JD's listing order. SKU ids and product links still return full variant rows. OFF (default): every result is looked up with all its variants. Available from 22 November 2026; until then the run looks up each result's variants as usual.

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

Order of each keyword's products before their variants are looked up, so Maximum SKU rows in total keeps the ones you want. Sorts the products the keyword brought (see Products per keyword), by the price, review count, positive-review rate or listing date on JD's search card. Products without that value go last. searchRank keeps JD's own position. Default: JD's order.

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

Keep only products and SKU rows priced at or above this, in yuan. Keyword results outside the band are dropped before their variants are fetched, so they cost nothing. Leave empty for no floor.

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

Keep only products and SKU rows priced at or below this, in yuan. Leave empty for no ceiling.

## `includeSuggestions` (type: `boolean`):

For each keyword, also save the related searches JD suggests (相关搜索, e.g. `手机` → `苹果17pro max`, `红米k90`). Saved to the `SUGGESTIONS` record of the run's key-value store, not as dataset rows. Free: no charge per suggestion. Up to 100 keywords per run.

## `allVariants` (type: `boolean`):

ON (default): one row per variant (color, storage, size, bundle) with its own price and stock. OFF: only the SKU you entered, one row per product.

## `maxVariantsPerProduct` (type: `integer`):

Cap on variant rows per product when every variant is on. The SKU you entered always comes first. Default and maximum 100.

## `includeProductDetails` (type: `boolean`):

Adds the product page fields to each row: full image gallery, the long-description image gallery, model, category id and name, weight, warranty, place of origin, JD Logistics flag, and the barcode when the variant data has none. Billed once per product. Prices and stock always come from the variant data, which is unmasked.

## `onlyInStock` (type: `boolean`):

Drop variants that cannot be ordered right now (out of stock, presale, reservation). Default: false.

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

Cap on rows for the whole run. Default 1000. Free-plan runs are capped at 100.

## Actor input object example

```json
{
  "products": [
    "100012043978",
    "https://item.jd.com/10233787625364.html"
  ],
  "searchKeywords": true,
  "maxProductsPerKeyword": 20,
  "maxProductsPerShop": 50,
  "searchResultsOnly": false,
  "sortBy": "relevance",
  "includeSuggestions": false,
  "allVariants": true,
  "maxVariantsPerProduct": 100,
  "includeProductDetails": false,
  "onlyInStock": false,
  "maxItems": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

One row per SKU: price in CNY, stock, delivery promise, variant properties, promo tags, subsidy and presale flags, brand, shop, and the input or keyword that found it. With product details on: image gallery, model, warranty and origin (`detailLevel` is `full`).

## `suggestions` (type: `string`):

Only when 'Add JD search suggestions' is on: for each keyword, the related searches JD suggests (keyword, searchKey, keywordType, iconUrl).

# 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 = {
    "products": [
        "100012043978",
        "https://item.jd.com/10233787625364.html"
    ],
    "maxProductsPerKeyword": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/jd-com-price-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 = {
    "products": [
        "100012043978",
        "https://item.jd.com/10233787625364.html",
    ],
    "maxProductsPerKeyword": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/jd-com-price-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 '{
  "products": [
    "100012043978",
    "https://item.jd.com/10233787625364.html"
  ],
  "maxProductsPerKeyword": 20
}' |
apify call memo23/jd-com-price-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/jd-com-price-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/ZXCIE1AsSUYI02qSh/builds/fwRjFTcbFpFmMOHer/openapi.json
