不同编码的解码响应

Decoding responses of different encodings

我正在尝试从 python 金融教程编程 (link) 中获取标准普尔 500 指数中所有上市公司的代码数据。不幸的是,运行 我的代码出现以下错误:

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

我想这个问题是由于不同 stocks.How 的不同编码引起的,我可以更改我的代码(如下所示)以允许 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()

追溯(最近调用最后):

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

这里的根本问题是您正在学习 out-of-date 教程。

如果您查看 the docs for pandas-datareader,在顶部,有一个大方框,上面写着:

Warning

As of v0.6.0 Yahoo!, Google Options, Google Quotes and EDGAR have been immediately deprecated due to large changes in their API and no stable replacement.

每当您按照教程或博客 post 进行操作时,如果出现问题,您应该做的第一件事就是查看实际文档,了解他们教您使用的内容。事情在变化,包裹网络的东西 API 变化特别快。

无论如何,如果向下滚动到数据源列表,您会看到没有 Yahoo 条目。但是代码仍然在源代码中。因此,您不会收到有关没有此类源的错误,而是稍后会因尝试使用损坏的源而​​收到错误。

从表面上看,发生的事情是 datareader 代码发出某种请求(您必须深入研究库,或者使用 Wireshark 捕获它,以查看 URL 和 headers 是)得到一个声称使用 gzip content-encoding 的响应,但它做错了。

内容编码是由网络服务器应用于页面并由您的浏览器或客户端撤消的内容,通常是压缩,以缩短页面通过网络发送的时间。 gzip 是最常见的压缩形式。这是一种非常简单的格式,这就是它如此常用的原因(服务器可以 gzip 数千页而不需要超级计算机群),但这意味着如果出现问题——比如服务器只是将流截断 16KB 之类的——你除了 gzip 解压缩失败外,无法真正判断出了什么问题。

但无论如何,都没有办法解决这个问题;1您必须重写代码才能使用不同的数据源。

如果您对代码的理解不够好,无法做到这一点,您必须找到更多 up-to-date 教程来学习。


1.除非你想找出新的 Yahoo API,假设有一个,并弄清楚如何解析它,然后编写一个全新的 pandas-datareader 源代码,即使编写该库的专家已经给出试图与雅虎打交道……