爬蟲第七步:用 Python 爬蟲取得 ETF 配息歷史

Python 爬蟲系列閱讀:

我們在進行回測時,最先遇到的問題往往是:除權息的跳空該怎麼處理?不妥善處理的話,有偏差的回測結果會導致數據完全不具參考性。因此,為求回測結果準確,我們需要標的配息時間和股息金額的歷史資料。本篇接下來就一步一步帶大家完成 ETF 配息歷史資料爬蟲的實作吧!

ETF 配息歷史資料來源

首先,我們使用查詢 ETF 相關資料常用的網站 MoneyDJ,在每檔 ETF 資訊的頁面中,其中有一個頁籤叫做「配息紀錄」,其中就包含了我們需要的配息歷史表格!如下方截圖,或是從下方連結進入 0050 (台灣 50 ETF)的配息紀錄頁面。

資料來源:https://www.moneydj.com/

台灣 50 ETF的配息紀錄頁面:https://www.moneydj.com/ETF/X/Basic/Basic0005.xdjhtm?etfid=0050.TW

注意網址的命名規則

在切換幾檔 ETF 之後,我們發現不同 ETF 的網址只差在 etfid 後的值。這樣的話一切都很單純了!代表我們可以建立一個函數,只要傳入不同的 ETF股票編碼,就能爬取到它的配息歷史數據了!

爬蟲實作ETF 配息歷史

我們現在有網址了,那接下來解說一下爬取方式吧!

首先,我們 import 爬蟲及資料整理的常用套件。相關套件的基礎操作教學請詳見量化通其他文章。

import requests 
import numpy as np 
import pandas as pd from bs4 
import BeautifulSoup

接著,為了方便重複使用爬蟲程式碼,如先前所述,我們確定了網址的命名規則。因此,下面我們展示設計完成的函數直接進行解說:

def get_dividend_list(symbol):     
    div_url = f'https://www.moneydj.com/ETF/X/Basic/Basic0005.xdjhtm?etfid={symbol}.TW'
     r = requests.get(div_url)
     soup = BeautifulSoup(r.text, "lxml")
     table = soup.findAll("table", class_ = "datalist")[0]

     list_rows = []
     rows = table.find_all('tr')
     for row in rows:
         row_td = [i.text for i in row.find_all('td')]
         if len(row_td)>1:
             list_rows.append(np.array(row_td)[[1,2,6]])
     df = pd.DataFrame(list_rows, columns =
 ['ex_div_date','pay_date','div_amount'] )
     df['symbol_id'] = [symbol] * len(df)
     return df
  • 函數的傳入參數 symbol 為字串,例如 ”006208” 等。
  • 在傳入參數後,我們把代碼放入 URL 中。這裡使用的是 Python 3.6 之後新增的字串格式寫法:雙引號左側放一個 f,中間的變數用大括號 {} 包起來。
  • 接著我們用 requests 套件的 get 方法把 URL 的訪問內容拿回來,如函數內第二行程式碼。
  • 再來,用 BeautifulSoup 解析網頁內容,並且搜尋第一個 class_ 值為 “datalist” 的table(知道要這麼解析,是因為我們已經事先把訪問內容列印出來,知道網頁結構是如此)
  • 進入 for 迴圈即是典型的表格解析方法,先以 te 區分每一列,再以 td 區分每一個儲存格。在這個範例中,我們僅需要用到第 1, 2, 6 行,因此在儲存每一列資料到 list_rows 時,我們刻意只取 [1, 2, 6]。
  • 最後,我們把解析完的資料製作成 pd.DataFrame,另外再加入一個 column 來註記這是哪個 ETF 的配息歷史資料,就大功告成啦!

為什麼要另外製作 ETF 代碼的 colomn 呢?試想一下,如果我們現在有 200 個 ETF 的配息歷史資料需要爬取,搭配 ETF 代碼的 colomn 後,我們就能夠把所有資料整併進一個 pd.DataFrame ,方便管理和後續取用。

以 0050 為例,我們試著運行看看這個爬蟲程式:

dividend = get_dividend_list(“0050”) 
print(dividend)

延伸閱讀:


量化通粉絲社群,一起討論程式交易!

加入LINE匿名群組量化通QuantPass」無壓力討論與分享!

追蹤量化通的粉絲專頁量化通QuantPass」即時獲取實用的資源!

python_course_all_1920X400
QP66
QP66

具備逾十年交易經驗,研究交易資產橫跨股票、債券、外匯、原物料,以及加密貨幣。現為量化避險基金交易員,亦曾任職於資金規模逾百億的避險基金,以及在區塊鏈企業擔任顧問一職。

擅長從宏觀至微觀,由淺入深挖掘交易機會,並運用Python實現全自動化的投資組合管理。

文章: 23

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *