うぇぶすくれいぴん

毎週末,保有株と購入候補株の値段を調べ,Excel表を更新しています.そのExcelでは,値動きや利回りに応じて「売るべし」「買うべし」が表示されるようにしています.これで,気分に左右されることなく,比較的普遍的な評価基準で,何も考えずに判断できる仕組みになっています.

毎週末の作業は,銘柄コードをYahoo!ファイナンスページへコピペし,直近1週間の日次情報をExcelへコピペするものです.現在は37銘柄を監視しており,このコピペ作業,意外と手間.株を始めた頃はこの作業もそれなりに楽しめていたのですが,そろそろ煩わしさが勝ってきました.なんとか楽したい.

ということで以前,それらしいWebAPIを軽く突けないかと,Webページを軽くハッキングしてみました.しかし,私のHTMLおよびJavaScript力では,乗り越えるに至らず,タイムアップでギブアップしました.

5月の大型連休を前に,少し時間が確保できたので,再挑戦.今度はアプローチを変え,Webサイトに表示されている株価をHTMLから抽出することにしました.いわゆる,Webスクレイピングです.これまでやったことないけど,これならやれるでしょう.やれました.ExcelのVBAで実現しました.

まずは,指定のWebページのHTMLの取得.「Microsoft XML, v6.0」というライブラリの参照を追加し,XMLHTTP60というクラスを使ったサンプルに倣いました.こんなに簡単にできちゃうんですね.

Private Function GetHtml(ByVal url As String) As String
    Dim httpReq As New XMLHTTP60
    Call httpReq.Open("GET", url)
    Call httpReq.send
    Do While httpReq.readyState < 4
        DoEvents
    Loop
    GetHtml = httpReq.responseText
End Function

次に,HTMLから株価の部分を抽出するコード.正規表現で頑張ればなんとかなりそう.「Microsoft VBScript Regular Expressions 5.5」というライブラリの参照を追加し,VBScript_RegExp_55.RegExpというクラスを使いました.正規表現自体,あまり使ったことないので,調べながらでした.これでいいかと思ったら,株価に桁区切りのカンマが入るケースがあったり,小数部が入るケースがあったりで,何度か修正.

Private Sub Extract(ByVal html As String)
    'HTMLに埋まっている株価の表の一部の例
    '{"openPrice":"3,015","highPrice":"3,039","lowPrice":"3,007","closePrice":"3,023","volume":"1,161,200","adjustedClosePrice":"3,023","baseDate":"2021年4月23日","baseDateIso":"2021-04-23T00:00:00+09:00"},
    '{"openPrice":"3,047","highPrice":"3,057","lowPrice":"3,001","closePrice":"3,036","volume":"1,478,500","adjustedClosePrice":"3,036","baseDate":"2021年4月22日","baseDateIso":"2021-04-22T00:00:00+09:00"},
    '{"openPrice":"3,032","highPrice":"3,034","lowPrice":"2,976","closePrice":"2,997","volume":"3,178,600","adjustedClosePrice":"2,997","baseDate":"2021年4月21日","baseDateIso":"2021-04-21T00:00:00+09:00"}

    Const PTN0  As String = """openPrice"":""(\d*,?\d+\.?\d*)"""
    Const PTN1  As String = """highPrice"":""(\d*,?\d+\.?\d*)"""
    Const PTN2  As String = """lowPrice"":""(\d*,?\d+\.?\d*)"""
    Const PTN3  As String = """closePrice"":""(\d*,?\d+\.?\d*)"""
    Const PTN4  As String = """volume"":""(\d*,?\d*,?\d+\.?\d*)"""
    Const PTN5  As String = """adjustedClosePrice"":""(\d*,?\d+\.?\d*)"""
    Const PTN6  As String = """baseDate"":""(\d{4}年\d?\d月\d?\d日)"""
    Const PTN7  As String = """baseDateIso"":""(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2})"""
    Dim regex   As New VBScript_RegExp_55.RegExp
    Dim matches As MatchCollection
    Dim m       As match

    regex.Pattern = "{" & PTN0 & "," & PTN1 & "," & PTN2 & "," & PTN3 & "," & PTN4 & "," & PTN5 & "," & PTN6 & "," & PTN7 & "}"
    regex.Global = True
    Set matches = regex.Execute(html)
    For Each m In matches
        Debug.Print "日付:" & m.SubMatches(6) & " 終値:" & m.SubMatches(3)
    Next
End Sub

これで要素技術は確保できたので,あとはExcelの表を良い感じに操作するだけです.銘柄コードからURL化するところはExcel上の数式にしちゃって,並べた銘柄分と取得した日数分だけループを回し,縦や横に配置する感じ.程よくエラー処理を入れたりして無事完成.毎週末の作業がだいぶ楽になりました.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です