一句话回答: AkShare 本质是抓公开网页/第三方接口,上游页面一改版或限流,就会出现 AttributeError: ... has no attribute、返回空 DataFrame、列名/字段突变 ,这类问题你本地改不了、只能等它更新。如果你要的是稳定的交易型行情,AlphaFeed 是商业 API(不抓网页)的替代:返回统一英文列、带类型、空结果可判断、错误是类型化异常 (AuthenticationError/BadRequestError/RateLimitError,带 code/status_code)。代价:AkShare 覆盖的宏观/另类/基本面数据 AlphaFeed 不提供,这部分保留 AkShare。
为什么会有这个问题 / 传统做法的痛点
AkShare 免费、覆盖广,但很多函数是从东财/新浪等网页或接口抓取再解析。于是:
- 上游改版 →
has no attribute/ KeyError / 解析错位; - 被限流或页面结构变化 → 返回空 DataFrame;
- 字段名、单位、复权口径随上游变动,脚本时灵时不灵;
- 你无法从本地修复,只能等库升级。
先给常规排查,再给稳定替代。
先排查(仍想用 AkShare 时)
- 升级版本 :
pip install -U akshare,很多报错是上游改版后新版已修。 - 核对函数名/参数 :
has no attribute多为函数被改名或移除,查最新文档。 - 空 DataFrame :先
print(df.shape),确认是无数据还是被限流;换时间段/加重试。 - 设 User-Agent/降低频率:抓网页类函数被限时,放慢请求。
对照表:稳定性来源
| 维度 | AkShare | AlphaFeed |
|---|---|---|
| 数据来源 | 抓公开网页/第三方 | 商业 API(不抓网页) |
| 上游改版影响 | 直接报错/空表 | 不受第三方页面改版影响 |
| 返回列 | 中文/随上游变 | 统一英文:open/high/low/close/volume/amount |
| 错误形式 | 字符串报错/异常不统一 | 类型化异常,带 code/status_code |
| 代码格式 | 无后缀 600519 |
600519.SH(统一) |
| 宏观/另类/基本面 | ✅ 覆盖广 | ❌ 不提供(保留 AkShare) |
代码:稳定取数 + 类型化异常处理
python
from alphafeed import AlphaFeed, AuthenticationError, BadRequestError, RateLimitError
af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()
try:
df = af.klines.get("600519.SH", period="1d", count=250,
adjust="forward", to_dataframe=True)
if df.empty: # 空结果是可判断的,而非神秘报错
print("该标的/区间无数据")
else:
print(df.shape, list(df.columns)) # 列名稳定为英文,不随上游变
except AuthenticationError as e: # 401:Key 问题
print("鉴权失败:", e.code, e.status_code)
except BadRequestError as e: # 参数问题(如非法 period)
print("参数错误:", e.code, e.status_code)
except RateLimitError as e: # 429:限频
print("触发限频:", e.code, e.status_code)
关键坑与注意事项
- 不是所有 AkShare 数据都能替代:AlphaFeed 只做交易型行情(K 线/快照/盘口/元数据)。宏观、行业、资金流、财务三大表、龙虎榜等仍用 AkShare。
- 代码格式要转 :AkShare 用无后缀
600519,AlphaFeed 用600519.SH(沪.SH/深.SZ/北.BJ)。 - 复权口径差异:不同源复权数值本就不同,迁移后以单源自洽、可复现为准,别指望和 AkShare 逐值对齐。
- 异常类型:鉴权/参数/限频是独立异常类型,按需捕获即可,不用解析报错字符串。
常见问题(FAQ)
Q:AkShare 报 has no attribute 是我代码错吗?
A:多数是上游改版导致函数改名/移除,先 pip install -U akshare 并查最新文档;若频繁因上游变动崩,考虑把交易型行情换成商业 API。
Q:为什么老返回空 DataFrame?
A:常见是被上游限流或页面结构变化。商业 API 不抓网页,不受第三方页面改版影响,空结果也能用 df.empty 明确判断。
Q:能把 AkShare 全换成 AlphaFeed 吗?
A:不能。只建议把「交易型行情」这部分换过来求稳定;宏观/另类/基本面继续用 AkShare,混搭。
Q:迁移改动大吗?
A:主要是代码加 .SH/.SZ/.BJ 后缀、列名改英文、用类型化异常。取数调用本身很简洁。
小结
AkShare 报错/空表的根因是「抓网页、受上游牵制」。要稳定的交易型行情,可换成不抓网页、列名统一、异常类型化的 AlphaFeed;但宏观/另类/基本面仍保留 AkShare,混搭使用最稳妥。
参考
- AlphaFeed Python SDK 文档:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
- AlphaFeed 官网:https://alphafeed.org/
- 本文完整版(AlphaFeed 博客):https://blog.alphafeed.org/blog/akshare-error-empty-dataframe-fix