【ETF分析 ①データ収集編】Python Selenium+Beautifulsoup4を使ってETF構成銘柄を取得する

今回はPythonを使ってネットからETFの月次構成銘柄データを取得する方法です。
データ収集→前処理→分析の「データ収集」段階のみ触れます。
その後のフェーズは改めてブログにしたいと思います。

1スマートベータ

突然ですが、『スマートベータ』と呼ばれる少し前から話題の運用手法はご存知でしょうか。簡単に説明すると、時価総額や株価にウエイトを置くのではなく、配当、株価変動率など特定の要素にウエイトを置く投資手法です。
例えば配当利回りが高い銘柄のみに絞って投資する高配当戦略もスマートベータにあたりますね。研究も活発に行われておりこれからも益々発展が望める運用手法です。

2背景と目的

そんなスマートベータ戦略ですが自身の興味分野の一つでもあります。
特に最小分散やリスクパリティなどのリスクベースのポートフォリオ戦略に興味があります。
また株/金利/コモディティなどのマルチアセットによるアセットアロケーション手法にも興味があります。
それらの分析用データ集めの一環として、ETF商品の構成銘柄をざっと取得したいというのが今回の目的です。
一応マウス操作でもCSVファイルを落とせますが、ファイルが月単位なので取得月数分ポチポチするのは非常に効率が悪いので、PythonSeleniumとBeautifulsoupを使って取得したいと思います。
今回はBlackRock社の「iシェアーズETF 東証上場シリーズ」から取得することにします。
(SeleniumやBeautifulsoupそのものの説明は今回は省略します)

Pythonコード

必要なモジュールのインポート

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import Select
from bs4 import BeautifulSoup
import time
import requests
import urllib.request

seleniumでブラウザを起動する

driver = webdriver.Chrome(executable_path = "(SeleniumChromeドライバのパス)/chromedriver.exe")

BlackRock ishares東証上場ETF一覧ページにアクセスして商品一覧と対応する商品ページのURLを辞書型にする

# BlackRock isharesの東証上場ETF一覧ページにアクセス
url = 'https://www.blackrock.com/jp/individual/ja/strategies/ishares-tse/'
driver.get(url)
time.sleep(1)
# BeautifulSoupでパース
soup = BeautifulSoup(driver.page_source, "html.parser")
# 予めETF一覧テーブルの情報を取得する
etf_table = soup.find("table", attrs={"class":"ishares-tse-table"})
# a要素を取得してurlとリンクの辞書を作成する
etf_link = [a.get("href") for a in etf_table.find_all("a")]
etf_name = [a.text.replace(" ", "").replace("・","") for a in etf_table.find_all("a")]
etf_dict = dict(zip(etf_name, etf_link))

ダウンロード先を指定しておく

dir_post = 'C:/Users/(ダウンロード先)/'

ダウンロード用の関数を定義

def download_etfcsv(etf_name, etf_url):
    # urlにアクセスする
    driver.get(etf_url)
    time.sleep(1)
    #すべての銘柄を見るボタンをクリック
    driver.find_element_by_xpath('//*[@id="holdingsTabs"]/ul/li[2]/a').click()
    time.sleep(1)
    # 基準日を選択する操作がドロップダウン形式となっているため、連続的に操作を行う
    cnt = 0
    # ドロップダウンを一つずつ選択してDLする
    for cnt in range(10000):
        try:
            # エレメントの取得
            dropdown_elm = driver.find_elements_by_class_name("date-dropdown")
            # 取得したいエレメントをSelectタグに対応したエレメントに変化
            dropdown_elm_select = Select(dropdown_elm[1])
            # ドロップダウンから日付を変更する
            dropdown_elm_select.select_by_index(cnt)
            # 選択した基準日を取得する
            time.sleep(3)
            base_date = dropdown_elm[1].get_attribute("value")
            # urlを取得する
            url = driver.find_elements_by_class_name("icon-xls-export")
            url = url[2].get_attribute("href")
            # csvファイルを保存する
            print('download date:{} name:{}'.format(base_date, etf_name))
            urllib.request.urlretrieve(url, dir_post + str(base_date) + 
                                            "_" + etf_name + ".csv")
            time.sleep(3)
        except:
            break

ダウンロードを実行
(実行には1時間程度要するのでご注意ください)

for etf in etf_dict:
    print(etf)
    download_etfcsv(etf, etf_dict[etf])

ブラウザを閉じる

driver.quit()

Pythonコードは以上になります。

次のステップ(前処理)に向けて

さて、ダウンロードしたcsvファイルを見ると最初にデータサマリーが記載され下の方に欲しいデータが表示されていますね。

f:id:k-bind:20190914125002p:plain
ダウンロードしたCSVファイル
次のステップでは以下のプロセスで前処理をかけたいと思います。

  • csvファイルから必要なデータのみを抽出する
  • ② 月次ファイルのデータをマージさせ一つのデータフレームにする

今回は以上になります。

損害等の責任について
当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますので、ご了承ください。