# East Money Scraper (`crawlerbros/eastmoney-scraper`) Actor

Scrape East Money (eastmoney.com) - China's largest finance portal. Search finance news, get real-time stock quotes and historical K-line data from the public push2 JSON APIs, browse market news by column, and resolve quotes from stock page URLs. No login required.

- **URL**: https://apify.com/crawlerbros/eastmoney-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, News, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## East Money Scraper

Scrape East Money (`eastmoney.com`) — China's largest finance portal. News search, real-time stock quotes + historical K-line data from the public `push2` JSON APIs, market news flash feed (kuaixun) by column, quote resolution from stock page URLs, and market rankings. HTTP-only, no login, no proxy required by default.

### What this actor does

- **Six modes:** `search` (news search, default), `byStock` (quote + K-line history), `marketNews` (kuaixun flash feed by column), `byStockUrl` (quote from quote-page URLs), `topGainers` (market ranking by change % / turnover / amount / market cap / main net inflow / volume / PE / volume ratio), `byStockName` (resolve a Chinese stock name via the suggest API → quote + K-line)
- **Real-time quotes** from `push2delay.eastmoney.com/api/qt/stock/get` — price, change %, open/high/low/prev close, volume, amount, turnover rate, volume ratio, PE (dynamic/static/TTM), PB, market caps, limit-up / limit-down prices, net asset per share
- **K-line history** from the `push2his` API family with **multi-host fallback** (`push2his` → `push2his2` → `push2`) — the hosts are latency-flaky and rotate; a single failing host no longer kills the candle data. Daily/weekly/monthly periods and price adjustment (前复权/后复权/不复权) are selectable
- **News search** via `search-api-web.eastmoney.com` with automatic fallback to the `so.eastmoney.com` HTML search
- **Rankings** cover Shanghai / Shenzhen / all A-shares / ChiNext / US stocks, sorted by 8 fields, ascending or descending (top gainers **and** top losers)
- **Auto-escalation:** on 403/429 the actor lazily engages the free Apify AUTO datacenter proxy and retries with backoff
- **Typed error records** for invalid stock codes / URLs / unresolvable names — nothing is silently dropped
- Empty fields are omitted (`strip_nulls` before every push)

### Output fields

**Stock records** (`recordType: "stock"`):

- `stockCode`, `stockName`, `secid` (e.g. `1.600519`), `price`, `change`, `changePct`, `open`, `high`, `low`, `prevClose`, `volume`, `amount`, `turnoverRate`, `volumeRatio`, `peRatio`, `peStatic`, `peDynamic`, `pbRatio`, `totalMarketCap`, `floatMarketCap`, `totalShares`, `floatShares`, `amplitude`, `limitUp`, `limitDown`, `navPerShare`, plus `market`/`marketCap`/`mainNetInflow` on ranking records, `sourceUrl`

**K-line records** (`recordType: "kline"`):

- `klineDate`, `open`, `close`, `high`, `low`, `volume`, `amount`, `amplitude`, `changePct`, `change`, `turnover`, plus `stockCode`, `stockName`, `sourceUrl`

**News records** (`recordType: "news"`):

- `title`, `digest`, `newsUrl`, `publishTime`, `imageUrl`, `column`, `sourceUrl`
- Search mode also emits `newsCode` (article code) and `source` (publisher, e.g. 证券时报网)
- MarketNews mode also emits `newsId` (kuaixun item id) and `commentCount`

**Error records** (`recordType: "error"`):

- `input`, `message` — emitted for invalid codes/URLs instead of silent drops

All data records carry `recordType`, `scrapedAt`, `sourceUrl`; error records are diagnostics (`input`, `message`) without a `sourceUrl`.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `search` | `search` / `byStock` / `marketNews` / `byStockUrl` / `topGainers` / `byStockName` |
| `searchQuery` | text | `贵州茅台` | News keyword (mode=search) |
| `searchSort` | select | `default` | `default` (relevance — honors the keyword) or `time` (newest; note: upstream `time` currently returns the site-wide hot feed and ignores the keyword) |
| `stockCodes` | array | `["600519"]` | Any form: `600519`, `1.600519`, `SH600519`, `SZ000001` |
| `stockNames` | array | `["贵州茅台"]` | Chinese stock names (mode=byStockName) |
| `stockUrls` | array | quote.eastmoney.com URL | Quote page URLs (mode=byStockUrl) |
| `includeKline` | bool | `true` | Emit K-line candles with quotes |
| `klineDays` | int (1–500) | `60` | Candles per stock |
| `klinePeriod` | select | `day` | `day` / `week` / `month` candle granularity |
| `adjustPrice` | select | `qfq` | `qfq` 前复权 / `hfq` 后复权 / `none` 不复权 |
| `newsColumn` | select | `102` | Kuaixun column: 100 all, 102 finance, 103 stocks, 104 funds, 105 bonds, 106 gold, 107 forex, 110 global, 111 banking, 112 insurance, 113 real estate, 114 auto, 115 tech, 118 food & beverage, 120 travel, 122 sports, 125 health, 127 agriculture, 128 energy |
| `marketRank` | select | `allA` | `shA` / `szA` / `allA` / `gem` (ChiNext) / `us` (NASDAQ/NYSE/AMEX) — mode=topGainers |
| `rankSort` | select | `changePct` | `changePct` / `turnover` / `amount` / `volume` / `marketCap` / `mainNetInflow` / `volumeRatio` / `peRatio` |
| `rankDirection` | select | `desc` | `desc` (top of the field) or `asc` (bottom — e.g. top losers) |
| `minPrice` / `maxPrice` | number (0–100000) | – | Price filter |
| `minChangePct` / `maxChangePct` | number (−100–100) | – | Change % filter |
| `containsKeyword` | text | – | Substring filter on news title / stock name / digest |
| `maxItems` | int (1–1000) | `50` | Hard cap |

#### Examples

```json
{ "mode": "search", "searchQuery": "新能源", "maxItems": 20 }
{ "mode": "byStock", "stockCodes": ["600519", "SZ000001", "0.300750"], "includeKline": true, "klineDays": 30, "klinePeriod": "week" }
{ "mode": "byStockName", "stockNames": ["贵州茅台", "宁德时代"], "maxItems": 10 }
{ "mode": "marketNews", "newsColumn": "103", "maxItems": 20 }
{ "mode": "byStockUrl", "stockUrls": ["https://quote.eastmoney.com/sh600519.html"] }
{ "mode": "topGainers", "marketRank": "us", "rankSort": "marketCap", "maxItems": 30 }
{ "mode": "topGainers", "marketRank": "allA", "rankSort": "changePct", "rankDirection": "asc", "maxItems": 20 }
```

### Data source

East Money's public JSON APIs (no auth): `push2delay.eastmoney.com` / `push2his*.eastmoney.com` quotes + K-line, `newsapi.eastmoney.com` kuaixun flash feed, `search-api-web.eastmoney.com` news search, `searchapi.eastmoney.com` stock suggest. The push2 API hosts are known to be latency-flaky from some networks — the actor retries with exponential backoff, tries all three kline hosts in order, and escalates to the Apify AUTO proxy on 403/429.

### Limitations

- Hong Kong (`m:100+t:3`) boards intermittently return `rc:102` (empty payload) — they are intentionally not exposed in `marketRank`.
- `byStockName` resolves via the suggest API, which matches the top suggestion only (e.g. `茅台` → `600519`); ambiguity is resolved to the first suggestion.
- `topGainers` scans the first 5 pages (250 rows) of a ranking and `marketNews` the first 10 pages; filters that match nothing within that window emit 0 records with a status message (never an infinite pagination loop).
- `marketRank=us` covers NASDAQ + NYSE + AMEX (`m:105,m:106,m:107`); `changePct` for US stocks is a true percentage (relative to previous close).

### Use cases

- A-share quote monitoring / portfolio tracking
- Historical price series for backtesting
- Chinese-language finance news monitoring
- Market-scan daily reports (top gainers by change % / turnover)

### FAQ

**What is a `secid`?** East Money's internal stock id: `1.600519` = Shanghai 600519, `0.000001` = Shenzhen 000001. The actor accepts many input forms and normalizes to this.

**Why are some news columns missing?** The `newsColumn` enum covers the 19 most-used kuaixun columns; the flash feed also exposes a long tail of rarely-used columns that are not exposed to keep the dropdown honest — and only columns the API currently serves data for are listed (e.g. 133 医药 was dropped after East Money stopped serving it). Contact the author if you need a column added.

**Is the K-line data delayed?** The `push2delay` host serves delayed quotes for free. Real-time data requires a licensed feed.

**Why an error record instead of skipping a bad code?** The brief requires typed error records for invalid inputs — a bad stock code produces `recordType: "error"` with the offending input and a hint, so no input is ever silently dropped.

**Why might search return the HTML fallback?** `search-api-web.eastmoney.com` intermittently times out from some networks; the actor falls back to the `so.eastmoney.com` HTML results page, which returns the same article titles/URLs.

# Actor input Schema

## `mode` (type: `string`):

What to fetch.

## `searchQuery` (type: `string`):

Free-text news keyword, e.g. `贵州茅台`, `新能源`, `美联储`.

## `searchSort` (type: `string`):

Order of news results. Note: upstream `time` (newest-first) currently returns the site-wide hot feed and ignores the keyword, so `default` (relevance) is recommended.

## `stockCodes` (type: `array`):

Codes in any form: `600519`, `1.600519`, `SH600519`, `SZ000001`, `000001` (auto-detected as Shenzhen).

## `includeKline` (type: `boolean`):

Emit K-line candles alongside the quote (mode=byStock / byStockUrl / byStockName).

## `klineDays` (type: `integer`):

How many candles to emit per stock.

## `klinePeriod` (type: `string`):

Candle granularity.

## `adjustPrice` (type: `string`):

How the historical prices are adjusted.

## `stockNames` (type: `array`):

Chinese stock names to resolve, e.g. `贵州茅台`, `宁德时代`, `平安银行`.

## `stockUrls` (type: `array`):

Quote page URLs, e.g. `https://quote.eastmoney.com/sh600519.html`, `https://quote.eastmoney.com/sz000001.html`.

## `newsColumn` (type: `string`):

Kuaixun flash-feed column to browse.

## `marketRank` (type: `string`):

Which market board to rank.

## `rankSort` (type: `string`):

Sort criterion for the ranking.

## `rankDirection` (type: `string`):

Descending = top of the field (e.g. biggest gainers); ascending = bottom (e.g. biggest losers).

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

Drop stock records priced below this.

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

Drop stock records priced above this.

## `minChangePct` (type: `number`):

Drop records with changePct below this.

## `maxChangePct` (type: `number`):

Drop records with changePct above this.

## `containsKeyword` (type: `string`):

Only emit records whose title (news) or stock name contains this substring.

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

Hard cap on emitted records.

## Actor input object example

```json
{
  "mode": "search",
  "searchQuery": "贵州茅台",
  "searchSort": "default",
  "stockCodes": [
    "600519"
  ],
  "includeKline": true,
  "klineDays": 60,
  "klinePeriod": "day",
  "adjustPrice": "qfq",
  "stockNames": [
    "贵州茅台"
  ],
  "stockUrls": [
    "https://quote.eastmoney.com/sh600519.html"
  ],
  "newsColumn": "102",
  "marketRank": "allA",
  "rankSort": "changePct",
  "rankDirection": "desc",
  "maxItems": 50
}
```

# Actor output Schema

## `stocks` (type: `string`):

Dataset containing all scraped East Money quotes, K-line candles and news items.

# 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 = {
    "mode": "search",
    "searchQuery": "贵州茅台",
    "searchSort": "default",
    "stockCodes": [
        "600519"
    ],
    "includeKline": true,
    "klineDays": 60,
    "klinePeriod": "day",
    "adjustPrice": "qfq",
    "stockNames": [
        "贵州茅台"
    ],
    "stockUrls": [
        "https://quote.eastmoney.com/sh600519.html"
    ],
    "newsColumn": "102",
    "marketRank": "allA",
    "rankSort": "changePct",
    "rankDirection": "desc",
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/eastmoney-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 = {
    "mode": "search",
    "searchQuery": "贵州茅台",
    "searchSort": "default",
    "stockCodes": ["600519"],
    "includeKline": True,
    "klineDays": 60,
    "klinePeriod": "day",
    "adjustPrice": "qfq",
    "stockNames": ["贵州茅台"],
    "stockUrls": ["https://quote.eastmoney.com/sh600519.html"],
    "newsColumn": "102",
    "marketRank": "allA",
    "rankSort": "changePct",
    "rankDirection": "desc",
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/eastmoney-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 '{
  "mode": "search",
  "searchQuery": "贵州茅台",
  "searchSort": "default",
  "stockCodes": [
    "600519"
  ],
  "includeKline": true,
  "klineDays": 60,
  "klinePeriod": "day",
  "adjustPrice": "qfq",
  "stockNames": [
    "贵州茅台"
  ],
  "stockUrls": [
    "https://quote.eastmoney.com/sh600519.html"
  ],
  "newsColumn": "102",
  "marketRank": "allA",
  "rankSort": "changePct",
  "rankDirection": "desc",
  "maxItems": 50
}' |
apify call crawlerbros/eastmoney-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlerbros/eastmoney-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/1LhnJMEzeAuvKaHFL/builds/JMprXywHXwGefPKus/openapi.json
