yfinance 故障排查 · 现象 → 复现 → 原因 → 解决 → 不可解
yfinance 报错排查:九类故障,按现象逐条对号入座
取不到数时最容易走的弯路是「改代码」——但本站实测到的失败里,有相当一部分是网络层或数据源层问题,改代码完全没用。本页按固定五段式(现象 / 最小复现 / 原因判断 / 解决方式 / 哪些情况下不能解决)整理九类真实故障,全部来自官方异常定义、官方文档原文或本站实测记录,并明确区分「代码问题」「数据源问题」「网络问题」。
报错怎么分类:三类失败的处理方式完全不同
把失败归类,能省掉大量无效尝试。
| 失败类别 | 典型信号 | 先做什么 | 不要做什么 |
|---|---|---|---|
| 网络 / 环境问题 | Failed to connect to …:443、超时、ConnectionError | 用已知可用标的做对照;确认目标主机连通性;考虑代理设置 | 不要改 ticker、不要改参数、不要重装库 |
| 数据源问题 | Yahoo 明确给出原因、该标的确实无该区间数据、被限流 | 读异常消息原文(打开 hide_exceptions=False);降低请求频率 | 不要怀疑自己的列名写法 |
| 代码 / 口径问题 | KeyError: 'Adj Close'、YFInvalidPeriodError、空表但无异常 | 对照复权语义页确认口径;对照签名文档确认参数名与取值 | 不要用 try/except 吞掉异常继续跑 |
常见故障有哪些:九类逐条对号入座
每一行都给出官方原文或本站实测原文,便于你直接搜索对比。
| 故障 | 现象 / 原文 | 原因判断 | 解决方式 | 能否彻底避免 |
|---|---|---|---|---|
| 限流 | Too Many Requests. Rate limited. Try after a while.(YFRateLimitError) | 请求频率/量超过 Yahoo 容忍度 | 配置 yf.config.network.retries(指数退避);合并标的、加本地缓存 | 不能——限流由数据源控制 |
| 无价格数据 | possibly delisted; no price data found (period=…)(YFPricesMissingError) | 该标的在该区间/粒度下没有数据;文案中的「退市」是推测 | 核对 ticker 格式与区间;换粒度;打开 hide_exceptions=False 看完整信息 | 不能——Yahoo 很少解释原因 |
| 缺少时区 | YFTzMissingError(继承自 missing ticker 异常,消息含 no timezone found) | 该标的拿不到时区信息 | 换标的验证;检查网络是否导致元数据未取到 | 视标的而定 |
| 周期不合法 | Period '…' is invalid, must be one of: …(YFInvalidPeriodError) | 传了白名单之外的 period | 改为官方白名单:1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max | 能——参数是确定的 |
| 分钟线为空 | 实测 period="40d", interval="1m" 返回空表 | 日内数据不能超过最近 60 天(官方原文);更早的细粒度数据也会被拒 | 缩短区间;需要长历史就用日线;自建历史归档 | 能——遵守窗口即可 |
| 财务空表 | 实测 income_stmt 返回 (0, 0),其余报表正常 | 单个接口本次取数失败(耗时约 21 秒后返回空) | 重试;改用 get_income_stmt(freq=…);记录本次失败 | 不能——属数据源侧不稳定 |
| 跨市场 NaN | 实测 download(["AAPL","600519.SS"]) 出现 NaN 且 Volume 变 float64 | 交易日历不同导致并集索引 | 按市场分开下载;或显式处理 NaN 并说明口径 | 能——分开处理即可 |
| 网络不可达 | 实测 Failed to connect to hk.yahoo.com port 443 after 21051 ms | 目标主机不可达(本机/网络出口/代理) | 确认连通性;必要时设置 yf.config.network.proxy;重试 | 不能——取决于你的网络 |
| 找不到 Adj Close 列 | KeyError: 'Adj Close' | 默认 auto_adjust=True 时该列被删除(源码行为) | 显式 auto_adjust=False,或改用复权口径的 Close | 能——写清口径即可 |
config 怎么配:把可调项一次配好
官方 yf.config 是全局配置(1.x 提供),先把这几项设对,能省掉一半排障时间。
| 配置项 | 默认值 | 作用 | 什么时候改 |
|---|---|---|---|
yf.config.debug.hide_exceptions | True(隐藏异常) | 设为 False 后不再隐藏异常 | 排障先改它 |
yf.config.debug.logging | False | 打开详细调试日志 | 需要看请求链路时 |
yf.config.network.retries | 0 | 瞬时网络错误的自动重试次数,采用指数退避(1s/2s/4s…) | 网络抖动频繁、但请求量不大时 |
yf.config.network.proxy | None | 为所有取数请求设置代理 | 出口受限、需要走代理时 |
yf.config.locale.lang / .region | en-US / US | 影响本地化字段(如 longName)的返回语言 | 需要中文名称时(仅对当地上市标的有翻译) |
yf.set_tz_cache_location(path) | 平台默认缓存目录(Windows 为 %LOCALAPPDATA%\py-yfinance) | 把时区/cookie 缓存改到可写目录 | 默认目录不可写时 |
yf.config,旧写法是 yf.set_config(proxy=…, retries=…),且会给出 DeprecationWarning。如果你的环境里 yf.config 报 AttributeError,说明版本较旧,详见安装与版本页。排障脚本怎么写:按顺序排除三类原因
把「先分类再处理」写成代码,避免每次凭感觉试。
import yfinance as yf
import pandas as pd
# 0) 先打开异常可见性(1.x)
try:
yf.config.debug.hide_exceptions = False
except AttributeError:
print("[info] this version has no yf.config; check version first:", yf.__version__)
# 1) 环境对照:已知可用标的能否成功
def probe(sym, **kw):
try:
df = yf.Ticker(sym).history(period=kw.get("period", "5d"))
return "ok", df.shape
except Exception as e:
return type(e).__name__, str(e)[:160]
print("control :", probe("AAPL"))
print("target :", probe("600519.SS"))
# 若 control 也失败 → 网络/环境问题(不要改 ticker)
# 若 control 成功而 target 失败 → 检查 ticker 格式与区间
# 2) 口径自检:确认当前口径到底有没有 Adj Close
df = yf.Ticker("AAPL").history(period="1mo")
print("auto_adjust default -> has Adj Close?", "Adj Close" in df.columns)
print("columns:", list(df.columns))hide_exceptions),再对照官方 exceptions.py 与 CHANGELOG——版本升级带来行为变化时,往往能在 CHANGELOG 里找到对应条目。yfinance 常见问题
下面的回答都指向可核验的官方文件或本站实测;与官方表述冲突时,以官方仓库与 docs 为准。
为什么异常没抛出来,只看到空表?
因为调试开关默认是「隐藏异常」。本站读取源码核实:yf.config.debug.hide_exceptions 默认为 True,官方文档也说明把它设为 False 就会停止隐藏异常。旧版本里对应的写法是已废弃的 raise_errors=True(源码给出的迁移提示是「'raise_errors' deprecated, do: yf.config.debug.hide_exceptions = False」)。排障时先打开它,很多问题会自己浮出来。
possibly delisted; no price data found 是什么意思?
这是 YFPricesMissingError 的默认消息。官方源码注释说明:Yahoo 很少解释数据缺失的原因,所以默认文案会猜测性地写成「可能退市」。1.6.0 起新增了行为:当 Yahoo 明确给出原因时,就不再声称 possibly delisted,而是直接展示 Yahoo 给的原因。所以看到这句话时,先别当成「这股票退市了」,要结合代码格式、区间与网络一起判断。
KeyError: 'Adj Close' 怎么修?
这是本站认为最不该出现在生产代码里的错误之一,因为原因很明确:默认 auto_adjust=True 时Adj Close 列不存在(源码里该列被删除并重命名)。两种修法:①显式写 auto_adjust=False 再用该列;②改用复权口径的 Close。不要用 try/except 把它吞掉——那会把口径问题藏起来。
Failed to connect to hk.yahoo.com port 443 是怎么回事?
这是本站实测到的网络层失败:请求目标主机不可达。hk.yahoo.com 是库内使用的一个主机名之一,它与你写的 ticker 无关。判断方法:换一个已知可用的标的(如 AAPL)做对照——如果对照也失败,就是环境/网络问题;如果对照成功而目标失败,再去看 ticker。这类失败还有一个特征:同一版本在不同时间窗的表现不同(本站实测 0.2.58 首轮 3 项超时、同环境重跑则通过)。
yfinance 被限流(429)会看到什么?怎么处理?
官方定义了独立异常:YFRateLimitError,消息原文是 Too Many Requests. Rate limited. Try after a while.。库内提供了重试配置:yf.config.network.retries(默认 0),重试采用指数退避(1s、2s、4s…)。但请注意边界:加重试不能保证不被限流,它只缓解瞬时错误;减少请求量(合并标的、减少频率、做本地缓存)才是根本手段。
yfinance 的分钟数与财务数据为什么更容易出问题?
分钟线有硬性窗口:官方文档写明日内数据不能超过最近 60 天,且 30m 是取 15 分钟重采样而来。实测 period="5d", interval="1m" 可返回 1,949 行,而 period="40d", interval="1m" 返回空表。财务数据方面,实测出现过单个报表返回空表(income_stmt 返回 (0,0))而其它报表正常的情况,按「本次取数失败」处理并重试即可。