Расшифровка ответов разных кодировок

Я пытаюсь получить данные тикеров из всех списков в S&P 500 из учебников по программированию на python для финансов ( ссылка). К сожалению, я получаю следующую ошибку при запуске моего кода:

requests.exceptions.ContentDecodingError: ('Received response with 
content-encoding: gzip, but failed to decode it.', error('Error -3 while
decompressing data: incorrect data check',))

Я предполагаю, что эта проблема возникает из-за разных кодировок для разных акций. Как я могу изменить свой код (показанный ниже), чтобы разрешить декодирование gzip?

import bs4 as bs
import pickle
import requests
import datetime as dt
import os
import pandas as pd
import pandas_datareader.data as web

def save_sp500_tickers():
response = requests.get('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
#retrieve src code from url

soup = bs.BeautifulSoup(response.text, 'lxml')
#convert src code into bs4 format

table = soup.find('table', {'class':'wikitable sortable'})
#search the new soup object for the table tag of class wikitable sortable

tickers = []
#create a target array

for row in table.findAll('tr')[1:]:
#for each row in table find all rows sliced from index1
    ticker = row.findAll('td')[0].text
    #find all tableDefinitions and convert to text
    tickers.append(ticker)
    #add ticker to our tickers array
with open("sp500tickers.pickle","wb") as f:
    pickle.dump(tickers, f)

print(tickers)

return tickers

def getDataFromYahoo(reload_sp500 = False):
if(reload_sp500):
    tickers = save_sp500_tickers()
else:
    with open("sp500tickers.pickle","rb") as f:
        tickers = pickle.load(f)

if not os.path.exists('stock_dfs'):
    os.makedirs('stock_dfs')

start = dt.datetime(2010,1,1)
end = dt.datetime(2018,7,26)

for ticker in tickers:
    print(ticker)
    if not os.path.exists('stocks_dfs/{}.csv'.format(ticker)):
        df = web.DataReader(ticker, 'yahoo', start, end)
    else:
        print('Already have {}'.format(ticker))

getDataFromYahoo()

Traceback (последний вызов был последним):

  File "C:\Users\dan gilmore\Desktop\EclipseOxygen64WCSPlugin\cherryPY\S7P\index.py", line 55, in <module>
    getDataFromYahoo()
  File "C:\Users\dan gilmore\Desktop\EclipseOxygen64WCSPlugin\cherryPY\S7P\index.py", line 51, in getDataFromYahoo
    df = web.DataReader(ticker, 'yahoo', start, end)
  File "C:\Users\dan gilmore\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pandas_datareader\data.py", line 311, in DataReader
    session=session).read()
  File "C:\Users\dan gilmore\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pandas_datareader\base.py", line 210, in read
    params=self._get_params(self.symbols))
  File "C:\Users\dan gilmore\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pandas_datareader\yahoo\daily.py", line 129, in _read_one_data
    resp = self._get_response(url, params=params)
  File "C:\Users\dan gilmore\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pandas_datareader\base.py", line 132, in _get_response
    headers=headers)
  File "C:\Users\dan gilmore\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\sessions.py", line 525, in get
    return self.request('GET', url, **kwargs)
  File "C:\Users\dan gilmore\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\sessions.py", line 512, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\dan gilmore\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\sessions.py", line 662, in send
    r.content
  File "C:\Users\dan gilmore\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 827, in content
    self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b''
  File "C:\Users\dan gilmore\AppData\Local\Programs\Python\Python36-32\lib\site-packages\requests\models.py", line 754, in generate
    raise ContentDecodingError(e)
requests.exceptions.ContentDecodingError: ('Received response with content-encoding: gzip, but failed to decode it.', error('Error -3 while decompressing data: incorrect data check',))

1 ответ

Решение

Основная проблема заключается в том, что вы следуете устаревшему учебнику.

Если вы посмотрите на документы для pandas-datareader справа вверху есть большая коробка с надписью:

Предупреждение

Начиная с v0.6.0 Yahoo!, Google Options, Google Quotes и EDGAR были немедленно объявлены устаревшими из-за значительных изменений в их API и отсутствия стабильной замены.

Всякий раз, когда вы читаете учебное пособие или сообщение в блоге, и что-то не работает должным образом, первое, что вы должны сделать, это взглянуть на фактическую документацию на предмет того, что они учат вас использовать. Все меняется, и вещи, которые обертывают веб-API, меняются особенно быстро.

В любом случае, если вы прокрутите список источников данных вниз, вы увидите, что в Yahoo нет записи. Но код все еще там в источнике. Таким образом, вместо того, чтобы получить ошибку об отсутствии такого источника, вы получаете ошибку чуть позже при попытке использовать неработающий источник.

На поверхностном уровне происходит то, что datareader код делает какой-то запрос (вам нужно будет покопаться в библиотеке или, возможно, перехватить его с помощью Wireshark, чтобы увидеть, что такое URL и заголовки), который получает ответ, который утверждает, что использует gzip контент-кодировка, но делает это неправильно.

Кодирование содержимого - это то, что применяется к странице веб-сервером и отменяется вашим браузером или клиентом, обычно с помощью сжатия, чтобы страница отправлялась по сети быстрее. gzip это самая распространенная форма сжатия. Это очень простой формат, поэтому он так часто используется (сервер может сжать тысячи страниц без фермы суперкомпьютеров), но это означает, что если что-то идет не так - как сервер просто усекает поток до 16 КБ или что-то еще - вы не могу сказать, что пошло не так, за исключением того, что распаковка gzip не удалась.

Но независимо от этого, нет способа исправить это; 1 вы должны переписать свой код, чтобы использовать другой источник данных.

Если вы недостаточно хорошо понимаете код, чтобы сделать это, вам нужно найти более современное учебное пособие для изучения.


1. Если вы не хотите выяснить новый API Yahoo, при условии, что есть один, и выяснить, как его проанализировать, и написать совершенно новый pandas-datareader источник, хотя эксперты, которые пишут эту библиотеку, перестали пытаться иметь дело с Yahoo...

Другие вопросы по тегам