用 Python SDK 获取 A 股数据:pip install ashareapi
官方 SDK 已发布:`pip install ashareapi`。5 个免费端点无需 Key,返回 pandas DataFrame(没装 pandas 就返回 `list[dict]`);代码格式随便写;出错时 5 类异常分别告诉你该做什么。
安装
pip install ashareapi # 基础:返回 list[dict]
pip install "ashareapi[pandas]" # 加 DataFrame 支持(推荐)- 要求 Python 3.9+;强依赖只有 `requests`,pandas 是可选的
- 没装 pandas 时所有方法自动返回 `list[dict]` —— 不会因为缺依赖而报错
30 秒上手(免费端点不需要 Key)
5 个免费端点:`quote` / `kline` / `hot` / `market_overview` / `changedist` —— 无需注册、无需 Key,装上就能调。
from ashareapi import AShareAPI
cli = AShareAPI() # 免费端点无需 Key
df = cli.quote("sh600667") # 实时行情 → DataFrame
print(df[["date", "last", "turnover"]])
print(cli.kline("600667.SH", count=5)) # 代码格式随便写(自动归一化)
print(cli.hot(limit=10)) # 热搜榜
print(cli.changedist()) # 涨跌分布(市场广度)代码格式:三种写法都认
写 `cli.quote("600667.SH")` 和 `cli.quote("sh600667")` 是同一件事 —— 从别的数据源迁过来的代码不用改。
| 你写的 | 会被归一化为 | 说明 |
|---|---|---|
| `sh600667` | `sh600667` | 原生格式(市场前缀 + 代码) |
| `600667.SH` | `sh600667` | 常见后缀写法,自动转换 |
| `600667` | `sh600667` | 纯 6 位按首位推断:5/6 → 沪、0/3 → 深、4/8 → 北 |
付费端点:带 Key 调用
from ashareapi import AShareAPI
cli = AShareAPI("ct-你的Key") # 或设环境变量 ASHARE_API_KEY
df = cli.screen(preset="low_pe", orderby="ROETTM", limit=10)
print(df.head())
print(cli.fund("sh600667")) # 资金流 + 龙虎榜 + 大宗 + 两融
print(cli.finance("sh600667")) # 三大报表
print(cli.lhb("institution")) # 龙虎榜机构榜- Key 从 [定价页](https://ashareapi.com/pricing/) 获取(¥9.9 起)
- 32 个端点 = 32 个方法,命名与端点一一对应(`/v1/margin-trade` → `margin_trade()`)
- 完整清单见 [端点文档](https://ashareapi.com/endpoints/)
返回形态:DataFrame 还是 list?
SDK 把对象数组转成 DataFrame(优先取 `structured`,没有则取 `data`);表列表(`finance`)与多段结构(`shareholder` / `calendar`)原样返回(不硬套 DataFrame,避免退化成 3×1 的怪表);`raw=True` 可拿完整信封。
| 环境 | 返回 | 用法 |
|---|---|---|
| 装了 pandas(`ashareapi[pandas]`) | `pandas.DataFrame` | 直接 `df.head()` / `df[["date","last"]]` / 画图 |
| 没装 pandas | `list[dict]` | 自己遍历 —— 同样的代码不会崩 |
错误处理:5 类异常各说各的
from ashareapi import (AShareAPI, AuthError, RateLimitError,
UpstreamError, EmptyResultError)
cli = AShareAPI()
try:
df = cli.fund("sh600667")
except AuthError as e: # 401 → 这是付费端点,去拿 Key
print(e)
except RateLimitError as e: # 429 → 降频 / 解一次 PoW 提额 / 升级档位
print(e)
except UpstreamError as e: # 上游取数失败(已自动换源、不扣次数)→ 重试一次
print(e)
except EmptyResultError as e: # 当前无数据(如当天无大宗交易)→ 不计费,换条件
print(e)| 异常 | 什么时候抛 | 你该做什么 |
|---|---|---|
| `AuthError` | 401 / 缺 Key 调了付费端点 | 去拿 Key,或改用免费端点 |
| `RateLimitError` | 429 超出档位频率 | 降频;或解 PoW 挑战提额;或升级 |
| `UpstreamError` | 上游取数失败(已自动换源、不扣次数) | 重试一次通常就好 |
| `EmptyResultError` | 请求成功但当前无数据(如当天无大宗交易) | 换条件或稍后再试,不计费 |
| `APIError` | 其他(网络 / 5xx 重试耗尽) | 看异常信息 |
SDK vs 直接调 HTTP vs Tushare / AkShare
| ashareapi SDK | 自己 requests | Tushare | AkShare | |
|---|---|---|---|---|
| 上手成本 | pip 装完即用 | 自己封装重试/异常 | 注册 + 积分门槛 | 装完即用 |
| 返回形态 | DataFrame(无 pandas 降级 list) | 自己解析 JSON | DataFrame | DataFrame |
| 免费试用 | 5 个端点免 Key | 同样免 Key | 需注册(有积分门槛) | 免费 |
| 错误处理 | 5 类异常(含"无数据≠失败") | 自己判断 | 看返回值 | 自己判断 |
| 维护 | 我们维护(多源自动切换) | 上游改了你改 | 官方维护 | 上游改版常需跟进 |
常见错误与边界
- `401` 调付费端点 → 没带 Key:免费端点只有 5 个,其余需要 Key
- `429` → 匿名限额较低;解一次 PoW(`cli.challenge()`)可提到 60 次/分,或升级档位
- `EmptyResultError` 不是失败:是"当前确实没有这类数据"(例如当天没有大宗交易)—— 不计费,别当异常处理
- 数据日期:休市日不会变成"今天",看返回里的 `date` 字段判断数据属于哪个交易日
- 单位:`volume` 是手(×100 = 股)· `amount` 是元 · 比率字段是百分数(`20` = 20%)
- 分钟级 K 线:当前只提供日/周/月,分钟级不在范围内(明写,别猜)
常见问题
SDK 本身免费(MIT 开源),5 个免费端点(行情 / K线 / 热搜 / 市场总览 / 涨跌分布)无需 Key、无需注册即可调用。其余 25 个端点需要 API Key(¥9.9 起),SDK 不额外收费。
不必须。pandas 是可选依赖:装了返回 `DataFrame`(推荐),没装自动返回 `list[dict]`,代码不会崩。用 `pip install "ashareapi[pandas]"` 一起装。
SDK 内置代码归一化:`sh600667`、`600667.SH`、`600667` 三种写法都接受,会统一转成 `sh600667` 再请求。纯 6 位按首位推断市场(5/6 → 沪、0/3 → 深、4/8 → 北)。
EmptyResultError = 当前没有这类数据(例如当天没有大宗交易)——请求是成功的、不计费,换条件或稍后再试即可。UpstreamError = 上游取数失败(我们已自动换源、同样不扣次数),重试一次通常就好。分开是为了让你一眼知道"该换条件"还是"该重试"。
`pip install -U ashareapi`。最新版本与全部变更见 [更新日志](/changelog)。
最后更新: 2026-09-23
代码与返回形态取自 SDK 的真实运行结果(2026-09-23 从 PyPI 安装验证:quote 30 行 / hot 3 行 / 匿名限流时正确抛 RateLimitError)。Tushare、AkShare 的描述依据其官方文档,其接口与门槛由对方变更。