教程

批量取数:把 5000 次请求压到 23 次

扫一遍全市场 5000 多只,逐只循环要 5000 多次请求;用批量端点按 250 只一批,只要 23 次。下面是对照表、可运行代码,以及日额度怎么算。

什么时候该用批量端点

只要你的循环里出现「对一批代码反复调同一个接口」,就该换批量端点。典型场景:全市场选股、自选池定时刷新、多标的回测前的数据准备。

批量端点不只是「快」——它按返回只数计费,而且失败的不计费,比逐只循环更省额度、更容易做错误处理。

逐只循环 /v1/snapshot
5000 多次请求
约 30 分钟(受限于限流)
批量 /v1/snapshot-batch(250 只/次)
23 次请求
约 10 秒

9 个批量端点:单次上限与每日额度

单次上限与每日额度因端点而异(数据源限制不同),下表是当前值。每日额度按「调用次数」计,次日 0 点自动重置。

/v1/quote-batch 行情
200 / 1000 只
200 次
1000 次
/v1/kline-batch K 线
200 / 1000 只
200 次
1000 次
/v1/snapshot-batch 全字段快照
200 / 250 只
200 次
1000 次
/v1/fund-batch 资金流
200 / 1000 只
200 次
1000 次
/v1/technical-batch 技术指标
500 / 1000 只
200 次
500 次
/v1/chip-batch 筹码
200 / 300 只
200 次
1000 次
/v1/shareholder-batch 股东
200 / 300 只
200 次
1000 次
/v1/profile-batch 公司简况
100 / 150 只
100 次
300 次
/v1/finance-batch 财务
10 / 20 只
100 次
500 次

「一次最多」一列是专业版 / 机构版两个值。finance-batch 单次只有 10~20 只(财务数据源限制),扫全市场要 250 多次 —— 日额度 500 次仍够用,但要按这个数规划。

可运行示例:一次拿 50 只完整画像

返回是逐只标明成功与否的数组:{code, ok, data} 或 {code, ok:false, error}。所以一批里个别代码写错,不会拖垮整批 —— 按 ok 过滤即可。

Python(把 KEY 换成你的)
import requests

KEY = "ct-你的Key"
codes = ["sh600519", "sz000001", "sz300750"]   # 最多 250 只(机构版)

r = requests.get(
    "https://api.ashareapi.com/v1/snapshot-batch",
    params={"codes": ",".join(codes), "key": KEY},
    timeout=20,
).json()

print(r["requested"], r["returned"], r["failed"])   # 3 3 0
for item in r["data"]:
    if item["ok"]:
        d = item["data"]
        print(item["code"], d["name"], d["price"], d["pe"])
    else:
        print(item["code"], "失败:", item.get("error"))

全市场扫描:23 次请求写完整

批大小取该端点的上限(上表「一次最多」)。取小了不会报错,但会白白多花调用次数 —— 这正是最常见的额度浪费方式。

Python(分批 + 断点续跑)
def chunks(seq, n):
    for i in range(0, len(seq), n):
        yield seq[i:i + n]

all_rows, failed = [], []
for i, batch in enumerate(chunks(all_codes, 250), 1):   # 5000 多只 ⇒ 约 23 批
    r = requests.get(
        "https://api.ashareapi.com/v1/snapshot-batch",
        params={"codes": ",".join(batch), "key": KEY},
        timeout=30,
    ).json()
    all_rows += [x for x in r["data"] if x["ok"]]
    failed   += [x["code"] for x in r["data"] if not x["ok"]]
    print(f"第 {i} 批,累计成功 {len(all_rows)} 只")

额度怎么算:按支数、失败退回、次日重置

查今日各端点剩余次数
u = requests.get("https://api.ashareapi.com/v1/usage",
                  params={"key": KEY}).json()

print(u["heavy_quotas"]["snapshot-batch"])
# {'used': 0, 'limit': 1000, 'left': 1000}
  • 计费按实际返回只数:传 250 只、回来 248 只,只算 248 次
  • 失败的不计费:ok:false 的条目会自动退回额度,不用你处理
  • 每日额度按调用次数:上表的「日额度」是调用次数上限,不是支数上限
  • 次日 0 点重置(北京时间),用完后返回 429 并带 retry_after_s
  • 随时可查余量:GET /v1/usage?key=你的Key,看 heavy_quotas 字段

跑批量任务前先查一次余量,比跑到一半撞 429 划算得多。

三个容易踩的坑

  • 只支持 A 股:snapshot-batch / profile-batch 只认 sh / sz / bj,港股美股传了会标 ok:false
  • 代码要带前缀:sh600519 而不是 600519(裸 6 位在批量端点里会失败)
  • 超上限会被整批拒绝:传 300 只给 snapshot-batch(上限 250)会直接报错,不会静默截断

常见问题

一次传满 250 只,会不会很慢或超时?

snapshot-batch 实测 300 只 0.40 秒(比 /v1/quote-batch 快 10 倍);profile-batch 150 只约 10 秒(最慢的一个)。建议超时设 30 秒,finance-batch 设 60 秒。

日额度用完了怎么办?

次日 0 点(北京时间)自动重置。当天要跑更多,可以换另一个批量端点(如 quote-batch 与 snapshot-batch 额度各自独立),或升级档位。

批量端点和逐只接口的数据一样吗?

字段一致。snapshot-batch 返回的就是 /v1/snapshot 的全字段(35+ 项),只是打包成数组。单位与逐只接口相同(volume 手 / amount 万元 / 市值 亿元)。

为什么我传 250 只只回来 200 只?

说明其中有 50 只代码格式错或不在 A 股范围。看返回里 ok:false 的条目和 error 字段即可定位 —— 失败的不计费。

最后更新: 2026-11-02

单次上限与日额度取自后端配置(2026-11-02 校验:HEAVY_DAILY 与 _batch_cap 全表 22 / 9 项)。耗时数据来自实测:snapshot-batch 300 只 0.40s、profile-batch 150 只 10.02s。