使用pandas_datareader和yfinance拉取股票数据报JSONDecodeError如何解决
错误根因分析
这个JSONDecodeError: Expecting value: line 1 column 1的错误核心原因是yfinance向雅虎金融接口发送请求后,拿到的响应不是合法JSON格式,是空内容或者HTML错误页面,和你升级的pandas、pandas_datareader版本没有直接关系,具体触发原因通常有三类:
- yfinance版本过旧:雅虎金融接口规则频繁更新,旧版本yfinance(低于0.2.x的很多历史版本)的请求逻辑已经不兼容当前接口,请求会被直接拒绝,返回空响应或错误页。
- 网络连通性问题:雅虎金融接口在国内访问存在不稳定的情况,或者你的设备开启了不兼容的代理、DNS解析被污染,导致请求根本没拿到正确的接口返回内容。
- 你的第一段代码存在额外语法错误:
json.load(df)是错误用法,json.load()只能接收文件类对象,你传入的是pandas DataFrame对象,就算接口请求成功这行代码也会报错。
解决步骤
- 优先升级yfinance到最新稳定版本,这是最高发的问题原因,执行命令:
pip install --upgrade yfinance - 排查网络问题:
- 如果你使用代理,在调用yfinance接口时显式传入proxy参数,示例:
amd = yf.Ticker("AMD", proxy="http://你的代理地址:端口"),web.get_data_yahoo()方法也支持传入同名proxy参数。 - 没有代理的话,可以尝试将本地DNS更换为公共DNS(114.114.114.114或8.8.8.8),排查域名解析污染问题。
- 如果你使用代理,在调用yfinance接口时显式传入proxy参数,示例:
- 修正代码错误:如果需要将DataFrame转为JSON格式,直接用pandas自带的
df.to_json()方法即可,不需要调用json库读取DataFrame对象;如果需要转Python字典,用df.to_dict()。
验证测试代码
完成上述操作后,先运行最简测试代码验证接口连通性:
import yfinance as yf # 无代理可以去掉proxy参数 amd = yf.Ticker("AMD", proxy="http://127.0.0.1:你的代理端口") # 先打印股票基础信息,能正常输出说明接口连通 print(amd.info) # 再拉取历史行情 hist = amd.history(period="max") print(hist[["Volume"]].sort_values(by="Volume").tail(1))
如果仍然报错,可以临时在yfinance库的base.py文件的history()方法中,打印请求返回的data.text内容,确认是否返回了403、5xx等错误页,此类情况属于IP被雅虎接口限制,更换代理IP或间隔一段时间后重试即可。
内容的提问来源于stack exchange,提问作者Muhannad ١
相关产品推荐
相关产品推荐

