Python pandas datareader ya no funciona para yahoo-finance url cambiado

Desde que yahoo suspendió su soporte API, ahora falla el datareader pandas

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 

¿Hay alguna biblioteca no oficial que nos permita solucionar temporalmente el problema? ¿Algo en Quandl tal vez?

Encontré la solución por “fix-yahoo-finance” en https://pypi.python.org/pypi/fix-yahoo-finance útil, por ejemplo:

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

Tenga en cuenta que el orden de las últimas 2 columnas de datos es ‘Adj Close’ y ‘Volume’, es decir. No es el formato anterior. Para re-indexar:

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

Así que cambiaron su url y ahora usan protección de cookies (y posiblemente javascript), así que solucioné mi propio problema usando Dryscrape, que emula un navegador. Esto es solo un FYI, ya que seguramente ahora rompe sus términos y condiciones … así que use en su propio riesgo? Estoy buscando en Quandl una fuente alternativa de precios EOD.

No pude llegar a ninguna parte con las cookies navegando en CookieJar, así que terminé usando Dryscrape para “falsificar” una descarga de usuario.

 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 

Cambié de Yahoo a Google Finance y me funciona, así que desde

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

a

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

y adapté mi “viejo” Yahoo! símbolos de:

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

a

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

Probar esto:

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

Haga que el hilo entre en reposo después de cada dato. Puede funcionar la mayor parte del tiempo, así que intente de 5 a 6 veces y guarde los datos en el archivo csv, para que la próxima vez pueda leer el archivo.

 ### 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.