Python pandas datareader 不再适用于 yahoo-finance 更改的 url

Posted

技术标签:

【中文标题】Python pandas datareader 不再适用于 yahoo-finance 更改的 url【英文标题】:Python pandas datareader no longer works for yahoo-finance changed url 【发布时间】:2017-10-18 02:45:14 【问题描述】:

由于 yahoo 停止了对 API 的支持,pandas datareader 现在失败了

import pandas_datareader.data as web
import datetime
start = datetime.datetime(2016, 1, 1)
end = datetime.datetime(2017, 5, 17)
web.DataReader('GOOGL', 'yahoo', start, end)

HTTPError: HTTP Error 401: Unauthorized

是否有任何非官方的库可以让我们临时解决这个问题? Quandl 上可能有什么?

【问题讨论】:

不支持的 Yahoo Finance API 已关闭:forums.yahoo.net/t5/Yahoo-Finance-help/… pshep123,我从没想过要搜索 *** 的好建议!!!但是像许多其他人一样,除了知道 yahoo 停止了他们的 API 之外,我没有临时解决方案 【参考方案1】:

所以他们更改了网址,现在使用 cookie 保护(可能还有 javascript),所以我使用模拟浏览器的 dryscrape 解决了我自己的问题 这只是一个仅供参考,因为这肯定会违反他们的条款和条件......所以使用风险自负?我正在寻找 Quandl 寻找替代的 EOD 价格来源。

我无法通过 cookie 浏览 CookieJar,因此我最终使用 dryscrape 来“伪造”用户下载

import dryscrape
from bs4 import BeautifulSoup
import time
import datetime
import re

#we visit the main page to initialise sessions and cookies
session = dryscrape.Session()
session.set_attribute('auto_load_images', False)
session.set_header('User-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/39.0.2171.95     Safari/537.36')    

#call this once as it is slow(er) and then you can do multiple download, though there seems to be a limit after which you have to reinitialise...
session.visit("https://finance.yahoo.com/quote/AAPL/history?p=AAPL")
response = session.body()


#get the dowload link
soup = BeautifulSoup(response, 'lxml')
for taga in soup.findAll('a'):
    if taga.has_attr('download'):
        url_download = taga['href']
print(url_download)

#now replace the default end date end start date that yahoo provides
s = "2017-02-18"
period1 = '%.0f' % time.mktime(datetime.datetime.strptime(s, "%Y-%m-%d").timetuple())
e = "2017-05-18"
period2 = '%.0f' % time.mktime(datetime.datetime.strptime(e, "%Y-%m-%d").timetuple())

#now we replace the period download by our dates, please feel free to improve, I suck at regex
m = re.search('period1=(.+?)&', url_download)
if m:
    to_replace = m.group(m.lastindex)
    url_download = url_download.replace(to_replace, period1)        
m = re.search('period2=(.+?)&', url_download)
if m:
    to_replace = m.group(m.lastindex)
    url_download = url_download.replace(to_replace, period2)

#and now viti and get body and you have your csv
session.visit(url_download)
csv_data = session.body()

#and finally if you want to get a dataframe from it
import sys
if sys.version_info[0] < 3: 
    from StringIO import StringIO
else:
    from io import StringIO

import pandas as pd
df = pd.read_csv(StringIO(csv_data), index_col=[0], parse_dates=True)
df

【讨论】:

【参考方案2】:

我发现https://pypi.python.org/pypi/fix-yahoo-finance 中“fix-yahoo-finance”的解决方法很有用,例如:

from pandas_datareader import data as pdr
import fix_yahoo_finance

data = pdr.get_data_yahoo('APPL', start='2017-04-23', end='2017-05-24')

注意最后 2 个数据列的顺序是“Adj Close”和“Volume”,即。不是以前的格式。重新索引:

cols = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close']
data.reindex(columns=cols)

【讨论】:

我在调用 get_yahoo_data 时收到有关音量列的错误,但谢谢,我会调查一下 是的@Scilear 我一开始也是这样-尝试将pandas_datareader重新安装到最新版本,应该没问题。【参考方案3】:

我从 Yahoo 更改为 Google Finance,它对我有用,所以从

data.DataReader(ticker, 'yahoo', start_date, end_date)

data.DataReader(ticker, 'google', start_date, end_date)

并改编了我的“旧”雅虎!符号来自:

tickers = ['AAPL','MSFT','GE','IBM','AA','DAL','UAL', 'PEP', 'KO']

tickers = ['NASDAQ:AAPL','NASDAQ:MSFT','NYSE:GE','NYSE:IBM','NYSE:AA','NYSE:DAL','NYSE:UAL', 'NYSE:PEP', 'NYSE:KO']

【讨论】:

我试过这种方式,但它不起作用,给出“RemoteDataError”。【参考方案4】:

在读取每个数据之后让线程休眠。 可能大部分时间都可以工作,所以尝试 5-6 次并将数据保存在 csv 文件中,以便下次您可以从文件中读取。

### code is here ###
import pandas_datareader as web
import time
import datetime as dt
import pandas as pd

symbols = ['AAPL', 'MSFT', 'AABA', 'DB', 'GLD']
webData = pd.DataFrame()
for stockSymbol in symbols:
    webData[stockSymbol] = web.DataReader(stockSymbol, 
    data_source='yahoo',start= 
               startDate, end= endDate, retry_count= 10)['Adj Close']   
    time.sleep(22) # thread sleep for 22 seconds.

【讨论】:

【参考方案5】:

试试这个:

import fix_yahoo_finance as yf
data = yf.download('SPY', start = '2012-01-01', end='2017-01-01')

【讨论】:

【参考方案6】:

Yahoo Finance 与 pandas 配合得很好。像这样使用它:

import pandas as pd
import pandas_datareader as pdr
from pandas_datareader import data as wb

ticker='GOOGL'
start_date='2019-1-1'
data_source='yahoo'

ticker_data=wb.DataReader(ticker,data_source=data_source,start=start_date)
df=pd.DataFrame(ticker_data)

【讨论】:

【参考方案7】:

fix_yahoo_finance 包的名称已更改为 yfinance。所以你可以试试这段代码

import yfinance as yf
data = yf.download('MSFT', start = '2012-01-01', end='2017-01-01')

【讨论】:

以上是关于Python pandas datareader 不再适用于 yahoo-finance 更改的 url的主要内容,如果未能解决你的问题,请参考以下文章

通过python中的yahoo和pandas_datareader获取来自不同市场的市场数据

Python pandas datareader 不再适用于 yahoo-finance 更改的 url

Yahoo Finance API / URL 不起作用:Pandas DataReader 的 Python 修复

Error:cannot import name'is_list_like' --python使用pandas_datareader时出现错误,解决方案

金融数据获取

没有名为 pandas_datareader 的模块