Pandas与Yahoo财经接口报错:TypeError: string indices must be integers
解决Yahoo财经数据获取报错TypeError的方案
问题背景
数月前正常运行的Python脚本,如今使用pandas_datareader从Yahoo财经获取多资产数据时持续报错,推测是相关依赖包更新导致接口适配问题。
原代码
import warnings import datetime import numpy as np import pandas as pd import pandas_datareader.data as pdr import matplotlib.pyplot as plt, mpld3 import matplotlib.ticker as mtick date_from = datetime.date(2020, 1, 1) date_to = datetime.date(2022, 12, 30) tickerL = 'BTC-USD' print("Comparing " + tickerL +" to...") #tickerL2 = ['AAPL'] tickerL2 = input('Now enter your comparison ticker:\n') tickerList = [tickerL, tickerL2] print(tickerList) #tickerList = ['BTC-USD', 'AMZN', 'AAPL', 'CL=F', '^GSPC', '^DJI', 'GC=F'] #fetch multiple asset data def getMultiAssetData(tickerList, date_from, date_to): def getData(ticker): data = pdr.DataReader(ticker, "yahoo", date_from, date_to) return data datas = map(getData, tickerList) return pd.concat(datas, keys=tickerList, names=['Ticker', 'Date']) sort=False multiData = getMultiAssetData(tickerList, date_from, date_to) df = multiData.copy() #print(df) df = df.loc[tickerL, :] df.tail()
报错信息
Traceback (most recent call last): File "main.py", line 51, in <module> multiData = getMultiAssetData(tickerList, date_from, date_to) File "main.py", line 45, in getMultiAssetData datas = list(map(getData, tickerList)) File "main.py", line 42, in getData data = pdr.DataReader(ticker, "yahoo", date_from, date_to) File "/opt/virtualenvs/python3/lib/python3.8/site-packages/pandas/util/_decorators.py", line 207, in wrapper return func(*args, **kwargs) File "/opt/virtualenvs/python3/lib/python3.8/site-packages/pandas_datareader/data.py", line 370, in DataReader return YahooDailyReader( File "/opt/virtualenvs/python3/lib/python3.8/site-packages/pandas_datareader/base.py", line 253, in read df = self._read_one_data(self.url, params=self._get_params(self.symbols)) File "/opt/virtualenvs/python3/lib/python3.8/site-packages/pandas_datareader/yahoo/daily.py", line 153, in _read_one_data data = j["context"]["dispatcher"]["stores"]["HistoricalPriceStore"] TypeError: string indices must be integers
解决方案
原因分析
Yahoo财经API接口结构发生变更,pandas_datareader旧版本无法解析新的响应格式,代码尝试用字符串索引访问非字典结构内容,触发TypeError。
修复方案
方案1:改用yfinance库(推荐)
yfinance是专门针对Yahoo财经数据的第三方库,维护更活跃,适配最新接口变化:
- 安装库:
pip install yfinance - 修改数据获取逻辑:
# 替换原pandas_datareader导入 import yfinance as yf # 修改getMultiAssetData函数 def getMultiAssetData(tickerList, date_from, date_to): def getData(ticker): # 使用yfinance下载数据 data = yf.download(ticker, start=date_from, end=date_to) return data datas = map(getData, tickerList) return pd.concat(datas, keys=tickerList, names=['Ticker', 'Date'])
方案2:升级pandas_datareader到开发版
若坚持使用pandas_datareader,可安装适配新接口的分支版本:
pip install git+https://github.com/pydata/pandas-datareader.git
注:此方案稳定性不如yfinance,因为pandas_datareader对Yahoo接口的维护优先级较低。
验证修改
修改后运行脚本,输入对比标的(如AAPL),即可正常获取多资产历史数据。
内容的提问来源于stack exchange,提问作者FringeAnalytics
相关产品推荐
相关产品推荐

