77Lifeworkベータ版

77Lifeworkベータ版

IT関係の話(ツール開発・インフラ構築)をメインとして、その他私の趣味や雑記用のブログです。ここに書いた内容が少しでも参考になれば嬉しいです。

【Python】BlackRockのWebページからHDVの構成銘柄リストを自動でダウンロードする方法

はじめに

こんにちは。今回は以下のBlackRockのWebページにあるHDVの構成銘柄一覧をダウンロードするプログラムを書いてみました。
www.blackrock.com

HDVとは米国ETFの1つで、複数の米国株を任意の割合で集めた投資商品のことです。
1つ1つの個別銘柄を購入しなくとも、HDVに投資することでこのETFに含まれている複数の銘柄に分散投資ができる、というわけです。
ここではあくまでもプログラムの話メインなので、これ以上の説明は省略します。

f:id:J-back:20210919220712p:plain:w600



動作環境

使用する言語はPython3で、動作させる環境は以下の通りです。
OS:CentOS 7.8 (2003)
プログラミング言語:Python3.6.8
ブラウザ:Firefox78.6
スケジューラ:cron

CentOSVPS上にインストールして24h稼働させています。
もちろん自前のPCにCentOSをインストールして実行することも可能です。
しかし、自前のPCを自宅で24h稼働させておくといろいろ心配なので(火事とか)、手軽で低価格なVPSを使用しています。

現在私が使っているVPSについては以下の記事に書いていますので、よかったら読んでみてください。
www.77-lifework.com


処理の流れ

では処理の流れですが、以下です。

  • ブラウザ(FireFox)を起動し、BlackRockのHDVのURLを開く
  • 保有銘柄一覧表の下にある、全銘柄のcsvファイルのダウンロードリンクを取得する
  • 上で取得したダウンロードリンクにアクセスし、csvファイルをダウンロードする
  • ダウンロードしたcsvファイルを開き、記載されている基準日が本日の日付だった場合、slackに通知する

ざっとこんな感じですね。今回はFireFoxを使用していますが、Chromeを使用することもできます。
このプログラムを毎日動かすことで基準日が変化した日、つまり銘柄の構成変更があった日にslackで通知がきます。

Linuxサーバ上でダウンロードされたcsvファイルを開いてみると、以下のような感じです。
構成銘柄の情報が取得できています。
f:id:J-back:20210919221801p:plain:w600


スクレイピングのコード

今回作成したPythonのコードは以下の通りです。

from bs4 import BeautifulSoup
from selenium import webdriver
import time
import urllib.request
import datetime
import os
import sns_post
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.firefox.options import Options
 
# 例外発生通知用のslack URL
SLACKURL_ex = '各自のアクセストークン'
 
# slack設定値
SLACKURL = '各自のアクセストークン'
 
# main処理
def main():
 
    # 日付
    today = datetime.date.today().strftime('%Y%m%d')
    today_compare = datetime.date.today().strftime('%Y年%-m月%d日') # for Lnx
 
    header = '【HDV構成銘柄】 hdv-composition-download.py\n'
    sendMessage = header
 
    # スクレイピング対象URL
    URL = 'https://www.blackrock.com/jp/individual/ja/products/239563/ishares-core-high-dividend-etf'
 
    # スクレイピング実行
    try:
        # ブラウザ設定
        options = Options()
        options.add_argument('--headless')        
 
        # 対象URLにアクセス
        driver = webdriver.Firefox(options=options)
 
        driver.get(URL)
        time.sleep(10)
 
        # 文字コードをUTF-8に変換し、html取得
        html = driver.page_source.encode('utf-8')
        soup = BeautifulSoup(html, "html.parser")
 
        download_link = soup.find('div', class_='holdings fund-component-data-export').find('a', class_='icon-xls-export').get('href')
        download_link = URL + download_link
 
        #ここは各自の環境に合わせてパスを記載 
        download_path = '/home/python-code/stock-HDV/'
        download_filename = download_path + 'HDV_composition_' + today + '.csv'
  
        #csvファイルダウンロード
        urllib.request.urlretrieve(download_link, download_filename)
        time.sleep(20)
  
        reference_date = ''
        with open(download_filename, 'r',encoding='utf-8') as f:
            reference_date = f.readline().split(',')[1].replace('"','').replace('"','').replace('\r','').replace('\n','')
 
         
        # 更新されている場合、slackに投稿
        if  reference_date == today_compare:
            sendMessage += '構成銘柄が更新されています。\n基準日:' + reference_date
            sns_post.slackPost(SLACKURL,sendMessage)
 
        else:
            os.remove(download_filename)
 
    except AttributeError as e:
        message = "[例外発生]"+os.path.basename(__file__)+"\n"+"type:{0}".format(type(e))+"\n"+"args:{0}".format(e.args)+"\n"
        sns_post.slackPost(SLACKURL_ex,message)
 
    except Exception as e:
        message = "[例外発生]"+os.path.basename(__file__)+"\n"+"type:{0}".format(type(e))+"\n"+"args:{0}".format(e.args)
        sns_post.slackPost(SLACKURL_ex,message)
 
    finally:
        # 起動したブラウザを閉じる
        driver.close()
        driver.quit() 
       
 
if __name__ == '__main__':
    main()

プログラム中で指定しているslackのURLについては皆さんそれぞれの環境に合わせたものを入れてください。
アクセストークンの取得方法については以下記事で解説しています。
www.77-lifework.com


また、「import sns_post」の部分は自作の関数を呼び出していますので、同じような記載にして動作させるには、
上記のプログラムの他に以下のファイルも作成して配置しておく必要があります。

import slackweb
import twitter

# slack送信メソッド
def slackPost(webhookurl,message):
    slack = slackweb.Slack(url = webhookurl)
    slack.notify(text = message)
 
# twitter送信メソッド
def twitterPost(message):
    # 取得したキーとアクセストークンを設定する
    auth = twitter.OAuth(consumer_key="wwwwwwwww",
                     consumer_secret="xxxxxxxxxxx",
                     token="yyyyyyyyyy",
                     token_secret="zzzzzzzzzzz")
 
    t = twitter.Twitter(auth=auth)
 
    # メッセージを投稿する
    t.statuses.update(status=message)

これはTwitterへの投稿とslackへの投稿メソッドを記載しています。(Twitterの方は今回使用していませんが)
snsへのメッセージ投稿は他のプログラムからも使用するので、共通して呼び出せるよう別ファイルで記載するようにしています。

また、ダウンロードしたcsvが更新されていないものだった場合には削除するようにしています。そうしないとcsvが無限にあふれてしまうので・・・。

おわりに

今回はBlackRockのWebページから米国ETFHDVについて、その構成銘柄リストを自動でダウンロードする処理を実装してみました。
次はダウンロードしたcsvを使って変更された部分の抽出などをやってみます。

最後まで読んでいただきありがとうございました。