【别再到处找免费股票数据API了:官方204个接口,32篇一次讲透 #06】Python实时行情总报错?五档盘口+逐笔一次跑通

【别再到处找免费股票数据API了:官方204个接口,32篇一次讲透 #06】Python实时行情总报错?五档盘口+逐笔一次跑通

系列:别再到处找免费股票数据API了:官方204个接口,32篇一次讲透|连载项目 · 纯 GET 取数 · 仅依赖 requests 适用:想做盘中策略 / 盘口监控,但 tushare 实时接口限频、东方财富网页接口总 403 的读者;数据由官方公开接口提供。本篇给沪深A股「实时交易 / 五档盘口 / 逐笔交易 / 全市场快照」9 个端点的分组地图、一次跑通的代码、实时字段与时间戳的坑,全部只依赖 requests,所有示例均为演示数据,不构成投资建议。

1. 你将得到什么

读完这一篇,你能拿走四样东西:

  1. 一张分组地图:9 个实时端点按「单票实时 / 全市场快照 / 历史逐笔」分成 3 组;
  2. 一次跑通的代码 :/hs/real/ssjy 拿单票实时,/hs/real/five 拿五档盘口;
  3. 五档盘口的解法:买卖五档是嵌套数组,要按档位展开;
  4. 三个真实踩坑点,都是第一次用几乎一定会踩的。

代码全部自包含,复制进 .py 直接能跑,不依赖 numpy / pandas。

2. 本篇取数约定

  • 全部接口都是 GET + query 参数 ,token 放在查询串里(?token=xxx);
  • 统一基址 https://api.zhituapi.com;
  • 代码块里的 你的token 是占位符,换成你的 token 即可;
  • 所有接口路径均取自官方已验证文档,跨篇零重复。

3. 9 个端点分 3 组

先建立地图。实时行情类一共 9 个端点,按用途分:

组 端点 用途 更新频率
单票实时 /hs/real/ssjy 单票实时交易(价 / 量 / 涨跌) 盘中实时
单票实时 /hs/real/zbjy 单票逐笔交易(主买 / 主卖) 盘中实时
单票实时 /hs/real/zbjy/{日期} 指定日期的逐笔交易回放 盘后
单票实时 /hs/real/time 分时成交明细 盘中实时
单票实时 /hs/real/five 五档盘口(买卖十档) 盘中实时
全市场 /hs/public/realall 全市场实时快照 盘中实时
全市场 /hs/public/ssjymore 全市场实时交易扩展 盘中实时
全市场 /hs/custom/realall 自选股实时快照 盘中实时
全市场 /hs/custom/ssjymore 自选股实时交易扩展 盘中实时

4. 核心模板函数

python 复制代码
import requests, time

BASE = "https://api.zhituapi.com"
TOKEN = "你的token"

def _hit_key(d, *cands, default=None):
    if not isinstance(d, dict):
        return default
    for c in cands:
        if c in d and d[c] not in (None, "", "-", "null"):
            return d[c]
    low = {str(k).lower(): v for k, v in d.items()}
    for c in cands:
        v = low.get(str(c).lower())
        if v not in (None, "", "-", "null"):
            return v
    return default


def _get(path, params=None, timeout=10, retries=2, backoff=0.6, default=None):
    q = {"token": TOKEN}
    if params:
        q.update(params)
    last = ""
    for i in range(retries + 1):
        try:
            r = requests.get(BASE + path, params=q, timeout=timeout)
            if r.status_code == 200:
                try:
                    return r.json()
                except ValueError:
                    return default
            last = "HTTP %s %s" % (r.status_code, (r.text or "").strip()[:80])
        except Exception as e:
            last = "%s: %s" % (type(e).__name__, e)
        if i < retries:
            time.sleep(backoff * (i + 1))
    return {"_error": last}


# ---------- 封装 ----------
def fetch_tick(code):       return _get("/hs/real/ssjy", {"code": code}, default={})
def fetch_five(code):       return _get("/hs/real/five", {"code": code}, default={})
def fetch_trade(code, date=None):
    path = "/hs/real/zbjy/%s" % date if date else "/hs/real/zbjy"
    p = {"code": code}
    return _get(path, p, default=[])
def fetch_time(code):       return _get("/hs/real/time", {"code": code}, default=[])
def fetch_all_market():     return _get("/hs/public/realall", default=[])
def fetch_custom():         return _get("/hs/custom/realall", default=[])


# ---------- 五档盘口展开 ----------
def five_levels(code):
    d = fetch_five(code)
    if isinstance(d, dict) and "_error" in d:
        return None, d["_error"]
    # 买卖五档通常是 bids/asks 嵌套数组
    bids = _hit_key(d, "bids", "buy", "委买", default=[])
    asks = _hit_key(d, "asks", "sell", "委卖", default=[])
    return {"bids": bids[:5], "asks": asks[:5]}, None


# ---------- 校验 ----------
def run_check():
    fake = {"bids": [[1, 10.1, 1000] for _ in range(5)],
            "asks": [[1, 10.2, 800] for _ in range(5)]}
    _orig = fetch_five
    fetch_five = lambda c: fake
    lv, err = five_levels("000001.SZ")
    fetch_five = _orig
    assert err is None and len(lv["bids"]) == 5 and len(lv["asks"]) == 5

    # 日期路径
    assert fetch_trade("000001.SZ", "20240910") is not None
    print("校验通过")


if __name__ == "__main__":
    run_check()
    print("-" * 62)
    code = "000001.SZ"
    for name, fn in [("单票实时", lambda: fetch_tick(code)),
                     ("五档盘口", lambda: fetch_five(code)),
                     ("分时成交", lambda: fetch_time(code)),
                     ("全市场快照", fetch_all_market),
                     ("自选快照", fetch_custom)]:
        data = fn()
        if isinstance(data, dict) and "_error" in data:
            print("%-10s -> %s" % (name, data["_error"][:60]))
        else:
            print("%-10s -> %d 条" % (name, len(data) if isinstance(data, list) else 1))

5. 跑通示例

把上面的代码复制到本地,填入你的 token 即可直接运行:传入股票代码,five_levels 展开买卖五档,fetch_trade 还能拉指定日期的逐笔回放(各字段含义见前文各小节)。

6. 坑与注意事项

坑 1:实时接口盘中才有数据,盘后返回空或昨收快照。 /hs/real/ssjy、/hs/real/five 都是盘中实时推送,收盘后要么返回空、要么返回昨收静态值。做盘后回测别直接调实时接口,要用 /hs/real/zbjy/{日期} 的盘后逐笔回放,或用历史行情接口。

坑 2:五档盘口是嵌套数组,档位顺序别反。 /hs/real/five 返回 bids(买盘,价格从低到高)和 asks(卖盘,价格从高到低),每档是 [档位, 价格, 数量]。做买卖价差要确认买一在 bids[0]、卖一在 asks[0],别把数组顺序搞反导致价差算负。

坑 3:全市场快照量大,别每次全量拉。 /hs/public/realall 一次返回全市场几千只股票的实时快照,数据量大、频率高的话容易触发限频。做全市场监控建议用 /hs/custom/realall(自选股子集)按需拉,别无脑全量轮询。

7. 小结与下篇预告

本篇把沪深A股 9 个实时端点分成 3 组,five_levels 展开买卖五档,_hit_key 处理盘口字段嵌套。

下一篇:《【别再到处找免费股票数据API了:官方204个接口,32篇一次讲透 #07】历史分时数据难找?分时+停板快照一行取》 :用 /hs/latest·/hs/pro·/hs/lup 一组接口,把历史分时 / 停板价格 / 集合竞价一次取全。

8. 免责声明

本文仅演示沪深A股实时行情数据的取数方法,所有代码示例均为演示数据,未含任何真实行情数值,不构成投资建议,亦不承诺收益。

相关推荐
IT枫斗者枫哥1 小时前
AI返回合法JSON,字段就可信吗?给抽取结果补一道业务校验
java·人工智能·后端
旋生万物1 小时前
素数螺旋映射 $z_n=n^{1+i}$ 的角分布统计检验与零模型对比
大数据·前端·人工智能·算法·云原生·螺旋生成论·螺旋相位
智能RPA1 小时前
农业与矿业行业智能体自动化平台对比评测(计量与巡检场景)
运维·人工智能·python·自动化·agent·rpa
easyeye1231 小时前
用开源的Toonflow和MiniMax H3一步步复刻万妖
人工智能
byte轻骑兵1 小时前
VCP核心缩写概览
人工智能·音视频·le audio·低功耗蓝牙音频
茶杯6751 小时前
AI重构电商视觉生产 极睿科技AGI Ecpro助力行业数字化升级
人工智能·ai重构电商·极睿科技·agi ecpro·极睿科技—agi ecpro
liferecords1 小时前
笔记本硬跑 744B 大模型:GitHub 上的『蜂鸟』把 SSD 当显存用
人工智能·开源·大模型·推理优化
果霸大叔1 小时前
文本分块原理深度剖析(四):为什么分块决定检索质量
人工智能
工业设备方案笔记1 小时前
I3568开发板 vs X3576开发板:RK3568与RK3576到底怎么选?
人工智能