web-dev-qa-db-fra.com

Le datareader de Python pandas ne fonctionne plus pour Yahoo modifié - URL modifiée

Depuis que yahoo a cessé son assistance API, le datareader des pandas échoue

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

existe-t-il une bibliothèque non officielle nous permettant de contourner temporairement le problème? Quelque chose sur Quandl peut-être?

2
Scilear

Donc, ils ont changé leur URL et utilisent maintenant la protection des cookies (et peut-être de javascript). J'ai donc corrigé mon propre problème en utilisant dryscrape, qui émule un navigateur. Ceci est juste un FYI, car cela enfreint à présent leurs conditions d'utilisation ... vos propres risques? Je cherche Quandl pour une source alternative de prix EOD.

Je ne pouvais me rendre nulle part avec les cookies en parcourant un CookieJar, j'ai donc utilisé dryscrape pour "simuler" le téléchargement d'un utilisateur.

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
Scilear

J'ai trouvé la solution de contournement de "fix-yahoo-finance" dans https://pypi.python.org/pypi/fix-yahoo-finance utile, par exemple:

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')

Notez que l'ordre des 2 dernières colonnes de données est "Fermé Adj" et "Volume", c'est-à-dire. pas le format précédent. Pour réindexer:

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

J'ai changé de Yahoo à Google Finance et cela fonctionne pour moi, donc de

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

à

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

et adapté mon "vieux" Yahoo! symboles de:

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']
2
Alex L.

Essayez ceci:

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

Faites en sorte que le thread dorme entre les lectures après chaque donnée. Peut fonctionner la plupart du temps, alors essayez 5 à 6 fois et enregistrez les données dans le fichier csv afin que vous puissiez lire à partir du fichier la prochaine fois.

### 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.
0
Dipen Lama