# HobbyLink Japan 日本手办·高达模型 Price & Stock Stats (`jpmarketdata/hlj-hobby-market-cn`) Actor

日本手办、高达模型与塑料模型的跨境转卖必备：输入一个关键词，一次调用拿到 HobbyLink Japan（HLJ，静冈的模型出口商）的日元挂牌价四分位，以及和价格同等重要的库存状态构成——现货 / 预订 / 缺货补订 / 停产，外加打折比例、折扣中位数与发售年份分布。预订与补订状态正是中文转卖方在国内查不到的那条信息。From $0.02 per keyword, no subscription.

- **URL**: https://apify.com/jpmarketdata/hlj-hobby-market-cn.md
- **Developed by:** [h ichi](https://apify.com/jpmarketdata) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 keyword market summaries

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/platform/actors/running/actors-in-store#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

## Japan Gunpla & Figure Price + Availability Stats — for Chinese-Speaking Buyers

**中文 · English · 日本語** —— 输入一个关键词，一次调用拿到 HobbyLink Japan（HLJ）的日元挂牌价四分位，**以及和价格同等重要的库存状态构成**：现货 / 预订 / 缺货补订 / 停产。

***

### 中文说明

#### 这是给谁用的（Who this is for）

**做手办与高达模型跨境转卖的人，缺的从来不是价格，而是「拿不拿得到」。** 一个 4,500 日元、状态是**停产**的 MG，和一个 4,500 日元、状态是**现货**的 MG，对任何一个要出货的人来说根本不是同一件商品。而**预订（预约中）与缺货补订这两个状态，恰恰是中文转卖方在国内查不到的信息**——国内平台上你只看得到「有货/无货」，看不到日本这一侧到底是「明年 3 月发售的预约」还是「厂家补订中」。

这个 Actor 读取 **[HobbyLink Japan](https://www.hlj.com/)（HLJ——静冈的模型出口商，自 1988 年起向全球发货高达模型、塑料模型、手办、涂料与工具）**，为每个关键词返回一条紧凑的行情记录：

- **`priceJpy` —— 取样商品的最低 / Q1 / 中位 / Q3 / 最高**（日元），并附当前汇率下的美元。
- **`stockBreakdown`** —— 按 HLJ 自己的状态码计数：`instock`（现货）/ `preorder`（预约）/ `futurerelease`（未发售）/ `backorder`（补订中）/ `orderstop`（停止接单）/ `discontinued`（停产）。**就是这个字段决定一个关键词是进货机会还是一条死目录。**
- **`inStockRatioSampled`** 与 **`orderableRatioSampled`** —— 故意分成两个数字，见下文。
- **`onSaleRatioSampled`** 与 **`saleRatePct`** —— 这个关键词里有多少在打折，打折的那些平均折多少。
- **`releaseYearTop`** —— 发售年份分布，看清一个关键词是当期现货、2026 年的预约潮，还是老目录的尾货。
- 可选：每一件取样商品（标题、售价、原价、省多少、折扣率、库存状态、发售日、商品链接）。

无需登录、无需 API key、不开浏览器、运行之间不存储任何数据。

本 Actor 是英文版 **HobbyLink Japan (HLJ) Gunpla & Figures — Price + Availability Stats in One Call**（同一账号下的英文入口）的**中文语言包**：抓取逻辑与统计口径完全相同，只有标题、商店说明、文档和输入项标签改写成中文。

#### 概览 Overview

每个关键词返回**一条 `market_summary` 汇总记录**：价格四分位（附口径标注）、库存状态构成、现货比例与可下单比例、打折比例与折扣中位数、发售年份分布、汇率。开启单件输出后，另外为每一件取样商品返回一条记录。

#### 输入 Input

| 字段 | 示例 | 说明 |
|---|---|---|
| `keywords` | `["RG Nu Gundam"]` | HLJ 的目录以**英文**建索引——产品名与产品线名命中率最高。每个关键词 $0.02 |
| `pagesPerKeyword` | `2` | 1–8。一页 = 24 件 = 1 次页面请求 + 1 次批量价格请求。默认 2（48 件） |
| `includeIndividualItems` | `false` | 开启后输出每一件取样商品的记录（+$0.002/件） |
| `convertToUsd` | `true` | 按当前汇率附上美元统计。汇率取不到时绝不会让整次运行失败 |

```json
{
    "keywords": ["Gundam"],
    "pagesPerKeyword": 2,
    "includeIndividualItems": false,
    "convertToUsd": true
}
```

#### `inStockRatioSampled` 与 `orderableRatioSampled` —— 这一段请一定读

**HLJ 价格接口里的 `is_in_stock` 标记，对「补订中（backorder）」的商品同样是 `true`——它的意思是「你可以下单」，不是「货在架上」。** 照单全收的话，一个 38% 是补订状态的关键词会被报成 100% 有货。所以本 Actor 把它拆成两个：

- **`inStockRatioSampled`** —— 取样商品里 HLJ 状态码**字面就是 `instock`** 的占比。**你要的是这个。**
- **`orderableRatioSampled`** —— HLJ 愿意接单的占比（现货**加上**补订/预约）。单独列出，并用一个说清楚它是什么的名字。

#### 输出 Output

字段名保持英文，这是 API 接口：

```json
{
  "type": "market_summary",
  "keyword": "RG Nu Gundam",
  "totalListingsFound": 273,
  "sampledListings": 24,
  "priceJpy": { "min": 500, "q1": 500, "median": 500, "q3": 4125, "max": 60000, "count": 24 },
  "priceJpyBasis": "sample",
  "pricedListings": 24,
  "stockBreakdown": { "instock": 15, "backorder": 9 },
  "inStockRatioSampled": 0.625,
  "orderableRatioSampled": 1.0,
  "onSaleRatioSampled": 0.0,
  "saleRatePct": null,
  "releaseYearTop": [[2025, 12], [2021, 7], [2026, 4], [2023, 1]],
  "checkedAt": "2026-08-01T05:33:51.318685+00:00",
  "sourceUrl": "https://www.hlj.com/search/?Word=RG+Nu+Gundam&page=1",
  "priceUsd": { "min": 3.15, "q1": 3.15, "median": 3.15, "q3": 26.02, "max": 378.48 },
  "exchangeRateJpyUsd": 0.006308
}
```

注意上例：`inStockRatioSampled` 是 0.625，而 `orderableRatioSampled` 是 1.0——同一批商品，前者说「六成在架上」，后者说「全部能下单」。**这两个数字之间的差，就是那 9 件补订品。**

那个 500 日元的中位价是真实的，而且很有教育意义：`RG Nu Gundam` 这个搜索既会命中 4,500 日元的模型本体，也会命中给它用的 500 日元水贴与细节件，而相关度排序会把它们排在前面。**想拿到模型本身的价格，就搜完整产品名**（`RG 1/144 Nu Gundam`）；在配件多的关键词上，请把 `q3` / `max` 和中位数一起读。本 Actor 如实返回搜索给出的结果，而不是悄悄过滤让数字更好看。

#### 每项统计的口径（basis）

每条记录都带 **`priceJpyBasis`**，你永远不用猜：

| `priceJpyBasis` | 含义 | 什么时候出现 |
|---|---|---|
| **`exact`** | 读到的页面覆盖了**整个结果集**——这是对每一条命中商品的真实统计 | 窄关键词（命中数 ≤ `pagesPerKeyword` × 24） |
| **`sample`** | 对实际读到的商品做的普通样本统计，`count` 是其中有价格的件数 | 其余全部情况 |

**这里刻意没有第三档。** HLJ 的搜索返回的是**相关度**排序，且不提供任何价格排序，所以不存在「某个名次的值就是全量分位数」这回事。我们自己的姊妹 Actor（`bookoff-market-checker`、`digimart-instrument-market-checker`）确实读全量四分位——它们能这么做，是因为那些平台提供单调的价格升序排列。**HLJ 没有，所以本 Actor 不会编造一个它支撑不了的全量声明。** 你拿到的是前 N 个相关度命中的诚实样本，明确标注，并把 `totalListingsFound` 放在旁边，让你自己看得见抽样比例。

记录里的其余部分（`stockBreakdown`、各比例、`saleRatePct`、`releaseYearTop`）**同样是样本口径**，母数为 `sampledListings`。

#### 本 Actor 不做什么

- **不给全量分位数。** HLJ 不提供价格排序，任何名次都不能被声称为全量百分位——见上面的口径表。
- **不给成交价。** HLJ 是一家商店：这些是**要价**，是今天买家会付的日元价格，不是完成交易的成交记录。
- **默认不倾倒商品明细。** 产品本身是「那条统计」，单件输出是可选项且单独计费。
- **不访问需要登录的数据。** 全部来自公开搜索页与 HLJ 自己的公开价格接口。
- **不存数据集。** 每次运行都实时抓取，运行之间不保留任何内容。
- **不涉及客户或卖家个人数据。** HLJ 是单一零售商，没有第三方卖家可供画像。

#### 价格 Pricing —— 每个关键词 $0.02 起，无订阅

| 计费事件 | 价格 | 何时发生 |
|---|---|---|
| 关键词行情汇总（`keyword-analyzed`） | **$0.02** | 每分析一个关键词 |
| 单件商品记录（`item-scraped`） | **$0.002** | 仅当开启「输出单件商品」时 |

默认运行（1 个关键词、只要汇总）花费 **$0.02**。**零结果的关键词绝不收费。** Apify 每月赠送 $5 免费额度。

#### 注意事项 Notes & limits

- **价格不在搜索页 HTML 里。** HLJ 的结果卡片是服务端渲染的，但价格那个 span 是**空的**，靠 JavaScript 填。所以本 Actor 把卡片列表与 HLJ 自己的批量价格接口（`/search/livePrice/?item_codes=…`，每次最多 40 个编码）配对，而不是去开浏览器——这也是它能塞进 256 MB、几秒钟跑完的原因。**一个通用 HTML 爬虫指到这些页面上，拿到的是一堆标题配空价格。**
- **确实有些商品根本没有价格**（未公布或已下架的产品）。它们仍会计入 `sampledListings` 与 `stockBreakdown`；`pricedListings` 告诉你有多少件进了价格统计。它们绝不会被当成 0 日元。
- **`priceJpy` 是售价** —— 今天买家实际支付的价格。打折时，折前价在单件记录里以 `listPriceJpy` 给出，配合 `savingsJpy` 与 `saleRatePct`。
- **`saleRatePct` 只对打折商品取中位数。** 把占绝大多数的不打折商品算进去只会把它拉到 0，反而藏掉捡漏者唯一想看的数字。`null` 表示样本里没有任何商品在打折。
- **`releaseYear`** 解析自 HLJ 的 `release_date`（例如 `"July 2026"` → `2026`）。**未来年份在这里是正常且有意义的**：尚未发售的预约品本来就是这个目录的一大部分。
- **库存状态码是 HLJ 自己的**（`instock`、`preorder`、`futurerelease`、`backorder`、`orderstop`、`discontinued`…）。我们不认识的状态码会原样透传进 `stockBreakdown` 而不是丢掉，所以 HLJ 新增状态时不会从构成比里悄悄消失。HLJ 价格接口没有应答的商品会出现在 `unpriced_or_unknown`。
- 请求限速 ≥1.2 秒，运行带有总时长预算；触及预算时，后面的关键词会以更少页数取样，其记录带 `truncatedForTimeLimit: true`。
- 与 HobbyLink Japan 无任何关联。数据用于市场调研，大额交易前请自行核实。

#### 用途 Use cases

- **进货筛选** —— 先用 `stockBreakdown` 排除掉停产与长期补订的关键词，再谈价格。
- **预约排期** —— `releaseYearTop` 与 `preorder` 计数告诉你这个题材的货什么时候到。
- **捡漏** —— `onSaleRatioSampled` 与 `saleRatePct` 定位正在打折的关键词。

***

### English

#### Overview

Japanese asking-price statistics for any hobby keyword on HobbyLink Japan (HLJ). One call per keyword returns price quartiles (min/Q1/median/Q3/max) over the pages read, plus the availability split every reseller needs next to the price — in-stock / preorder / backordered / discontinued — the on-sale share, the median discount and the release-year spread. Gunpla, plastic model kits, figures, hobby tools.

This listing is the **Chinese-language package** of our English Actor **HobbyLink Japan (HLJ) Gunpla & Figures — Price + Availability Stats in One Call**. The scraping and the statistics are identical; the documentation, store copy and input labels are written for Chinese-speaking hobby resellers and proxy buyers (日本手办 / 高达模型 / 日本模型代购).

#### Input

| Field | Example | Notes |
|---|---|---|
| `keywords` | `["RG Nu Gundam"]` | HLJ's catalogue is indexed in **English**. $0.02 per keyword |
| `pagesPerKeyword` | `2` | 1–8. One page = 24 items = 1 page request + 1 batch price request |
| `includeIndividualItems` | `false` | Enable to also get each sampled item as a record (+$0.002 each) |
| `convertToUsd` | `true` | Adds USD stats at the current exchange rate. A failed lookup never fails the run |

#### Output

One `type: "market_summary"` record per keyword (`priceJpy` + `priceJpyBasis`, `pricedListings`, `stockBreakdown`, `inStockRatioSampled`, `orderableRatioSampled`, `onSaleRatioSampled`, `saleRatePct`, `releaseYearTop`, USD conversion) — see the JSON example in the Chinese section — plus optionally one item record per sampled listing.

#### Pricing

| Event | Price |
|---|---|
| Keyword market summary (`keyword-analyzed`) | **$0.02** |
| Individual item record (`item-scraped`) | **$0.002** each |

Individual items are OFF by default, so a default run is a flat **$0.02** per keyword. A keyword that returns zero listings is never charged. No subscription.

#### Notes & limits

- **HLJ's `is_in_stock` means "orderable", not "on the shelf".** It is `true` for backordered items too, so taken at face value it reports 100% availability on a keyword that is 38% backorder. This Actor splits it: `inStockRatioSampled` (state code literally `instock` — the one you want) and `orderableRatioSampled` (in-stock plus backorder/preorder).
- **No population quantiles.** HLJ's search is a relevance order and offers no price sort, so no rank can be claimed as a percentile of the whole result set. `priceJpyBasis` is `exact` or `sample`, never anything stronger.
- Prices are not in the search HTML — the card's price span is empty and filled by JS, so the Actor pairs the card list with HLJ's own batch price endpoint instead of running a browser.
- Some items genuinely have no price; they count in `sampledListings` and `stockBreakdown` but never as ¥0. `pricedListings` says how many made it into the price statistics.
- `saleRatePct` is the median over discounted items only; `null` means nothing in the sample was on sale.
- These are **asking** prices, not sold comps. Read-only, throttled ≥1.2 s, no login, nothing stored between runs. Not affiliated with HobbyLink Japan.

***

### 日本語

#### 概要 Overview

ホビーリンクジャパン（HLJ）の模型・フィギュア相場をキーワード単位で1コールで返します。取得ページ内の価格四分位（最小/Q1/中央値/Q3/最大）に加え、**価格と同じくらい重要な在庫状態の内訳**（在庫あり / 予約 / 未発売 / バックオーダー / 受注停止 / 廃番）、セール比率と割引率の中央値、発売年の分布。中国語圏の利用者（日本手办 / 高达模型 / 日本模型代购）向けに中国語で書き直したパッケージで、英語版は **HobbyLink Japan (HLJ) Gunpla & Figures — Price + Availability Stats in One Call**（取得・統計処理は同一）。

#### 入力 Input

`keywords`（HLJ の索引は**英語**）／`pagesPerKeyword`（既定 2、1〜8。1ページ24件）／`includeIndividualItems`（既定 OFF）／`convertToUsd`（既定 ON）。

#### 出力 Output

キーワードごとに `market_summary` を1件（`priceJpy`＋`priceJpyBasis` / `pricedListings` / `stockBreakdown` / `inStockRatioSampled` / `orderableRatioSampled` / `onSaleRatioSampled` / `saleRatePct` / `releaseYearTop` / USD換算）。`includeIndividualItems` が ON のときは、取得した各商品の明細（タイトル・売価・定価・割引・在庫状態・発売日・商品URL）も出力します。

#### 料金 Pricing

キーワードサマリー（`keyword-analyzed`）**$0.02**／個別商品レコード（`item-scraped`）**$0.002 / 件**。個別明細は**既定 OFF** なので既定実行はキーワードあたり $0.02 固定です。**0件のキーワードには課金されません。** サブスクリプション不要。

#### 注意 Notes

**HLJ の `is_in_stock` は「注文できる」であって「棚にある」ではありません**——バックオーダー品でも `true` になるため、額面どおり読むと 38% がバックオーダーのキーワードを在庫100%と報告してしまいます。そこで本 Actor は `inStockRatioSampled`（状態コードが文字どおり `instock` のもの＝欲しいのはこちら）と `orderableRatioSampled`（在庫＋バックオーダー/予約）に分けています。**母集団分位は提供しません**：HLJ の検索は関連度順で価格ソートが無く、どの順位も母集団のパーセンタイルとは主張できないためです（`priceJpyBasis` は `exact` か `sample` のみ）。価格は検索HTMLに無く（空の span を JS が埋める）、カード一覧と HLJ 自身の一括価格エンドポイントを突き合わせています。価格の無い商品は `sampledListings` と `stockBreakdown` には入りますが ¥0 として扱いません（`pricedListings` を参照）。`saleRatePct` はセール品のみの中央値で、`null` はサンプル内にセール品が無かったことを意味します。これらは**売り希望価格**であり成約価格ではありません。リクエストは1.2秒以上の間隔、ログイン不要・実行間の保存なし。HobbyLink Japan とは無関係です。

# Actor input Schema

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

一个或多个搜索关键词——HLJ 的目录以英文建索引，所以产品名与产品线名命中率最高（RG Nu Gundam、MG Sazabi、Nendoroid、Tamiya 1/35、HGUC）。每个关键词 $0.02。

## `pagesPerKeyword` (type: `integer`):

每个关键词读多少页搜索结果。一页 24 件，花费一次页面请求加一次批量价格请求。HLJ 不提供价格排序，所以这是按相关度排序的诚实样本，绝不是全量分位数——每条记录都用 'priceJpyBasis' 写明这一点。页数越多样本越大、运行越久；8 页（192 件）是运行时间预算内的上限。

## `includeIndividualItems` (type: `boolean`):

默认关闭：一次运行每个关键词汇总固定 $0.02。开启后还会输出每一件取样商品（标题、售价、原价、折扣、可下单标记、库存状态、发售日、商品链接），+$0.002/件。

## `convertToUsd` (type: `boolean`):

按当前汇率（open.er-api.com）在日元统计旁边附上美元统计。汇率取不到时绝不会让整次运行失败——只是单独返回日元数字。

## Actor input object example

```json
{
  "keywords": [
    "Gundam"
  ],
  "pagesPerKeyword": 2,
  "includeIndividualItems": false,
  "convertToUsd": true
}
```

# 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 = {
    "keywords": [
        "Gundam"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jpmarketdata/hlj-hobby-market-cn").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 = { "keywords": ["Gundam"] }

# Run the Actor and wait for it to finish
run = client.actor("jpmarketdata/hlj-hobby-market-cn").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 '{
  "keywords": [
    "Gundam"
  ]
}' |
apify call jpmarketdata/hlj-hobby-market-cn --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jpmarketdata/hlj-hobby-market-cn"
        }
    }
}

```

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/kR91ue5pQeCaAKKcW/builds/SPVCdaWS4mXfWlkvm/openapi.json
