1. 程式人生 > >Python 爬取 Yahoo! Finance 資料問題總結

Python 爬取 Yahoo! Finance 資料問題總結

在《Python for Data Analysis》的第五章 Pandas 入門中,有一段分析 Yahoo! Fiannce 的股票價格和成交量的程式碼,此程式碼年代已久,如果照寫,根本不能正確執行,本篇文章總結了我遇到的幾個問題,以及解決辦法。

import pandas.io.data as web

all_data = {}
for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG']:
    all_data[ticker] = web.get_data_yahoo(ticker, start, end)

price = DataFrame({tic:
data['Adj Close'] for tic, data in all_data.iteritems()}) volumn = DataFrame({tic: data['Volume'] for tic, data in all_data.iteritems()})

接下來,解決以下問題:

  1. data 模組不能正常匯入
  2. is_list_like 不能正常匯入
  3. get_data_yahoo API 的問題
  4. google 的 ticker 改名

對著書敲完程式碼,得到第一個錯誤:
在這裡插入圖片描述
意思就是 data 找不到啊,谷歌一下,原來是因為 data 模組從

pandas.io 遷移到了 pandas_datareader 下面了,所以不能 import 進來。
解決方法:把 pandas.io.data 替換為 pandas_datareader.data 即可。
執行步驟:
1、先安裝 pandas_datareader

pip install pandas-datareader

2、把 pandas_datareader.data 模組 import 進來(我把別名從 web 換成了 pdr)

import pandas_datareader.data as pdr

接著,發現第二個問題:

ImportError: cannot import name is_list_like

根據錯誤提示:
在這裡插入圖片描述
進去相應的 fred.py 檔案檢視,發現了:

from pandas.core.common import is_list_like

谷歌之,發現是 is_list_like 也搬家了,從 pandas.core.common 搬到 pandas.api.types 中去了。這裡,基本有兩種解決辦法。第一種,是直接去修改 fred.py,第二種是在自己的程式碼裡面宣告一下匯入 is_list_like 途徑的改變。我採用了第二種方法:

import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like

至此,解決以上兩個問題。

接著,爬取 Yahoo! Finance 股票資料的時候,出現第三個問題:
在這裡插入圖片描述
很明顯,get_data_yahoo 這一 API 有問題。谷歌之,得到下面的解決辦法。
首先,安裝 fix_yahoo_finance:

pip install fix_yahoo_finance --upgrade --no-cache-dir

接著:

import fix_yahoo_finance as yf
yf.pdr_override()

這樣一步步下來,文章開頭書中的程式碼已經改善為下面可以正常執行的程式碼:

import datetime
import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_like
import pandas_datareader.data as pdr
import fix_yahoo_finance as yf
yf.pdr_override()
from  pandas import Series, DataFrame

start = datetime.datetime(2018, 1, 1)
end = datetime.date.today()
tickers = ['AAPL', 'IBM', 'MSFT', 'GOOGL']

all_data = {}
for ticker in tickers:
    all_data[ticker] = pdr.get_data_yahoo(ticker, start, end)

price = DataFrame({tic: data['Adj Close']
                        for tic, data in all_data.iteritems()})
volumn = DataFrame({tic: data['Volume']
                        for tic, data in all_data.iteritems()})

書中的結果:
在這裡插入圖片描述