株式会社シスアナコム

情報システムに関することなら、どんなことでも適切に助言いたします!

この投稿は1年以上前に公開されました。
現在では状況や内容が変わっている可能性があります。
ご注意下さい。m(_ _)m

ヤフーファイナンスから株式の基本情報を取得する

      2015/04/19

「ゼロからの週末プログラマー」に掲載していた記事を改訂して掲載しています。

ヤフーファイナンスから株式の基本情報を取得する

ヤフーファイナンスのHTMLソースを取得するまでやりました。

次は取得したHTMLソースから必要な情報を取り出すことをやります。

株式の基本情報を格納するテーブルを作成

まずはマイクロソフトACCESSのテーブルを作成します。

テーブル名は「T_株式_基本情報」としました。

  • 銘柄コード(テキスト型4桁)
  • 業種(テキスト型20桁)
  • 市場(テキスト型10桁)
  • 名称(テキスト型50桁)

将来的にフィールドは増やすつもりですが、今回は必要最小限にしました。

HTMLソースの中身を見る

ウェブページのHTMLソースを見るためには、インターネットエクスプローラの画面上で右クリック→ソースの表示、または、コマンドバーのページ→ソースの表示を実行します。

するとメモ帳が起動して、HTMLソースを見ることができます。

試験的にヤフーファイナンスのページを表示させて、どの銘柄でもいいので銘柄コードを入力して検索して、HTMLソースを表示させて下さい。

この文字列の中から、VBAプログラムを使って株式に関する情報を取り出します。

どうすれば良いかというと、取り出したい情報(文字列)の近くに存在する特徴的なHTMLタグを見つければいいのです。

HTMLから情報を取り出すVBAプログラム

まずは銘柄名

銘柄名はHTMLのTITLEタグ(=<title>)のすぐ右側に記述されています。

そこから、左括弧(=【)までの間の文字列を取り出せばいいのです。

プログラムはこうなります。

Function GetMeishou(HTMLSRC As String) As String
'YAHOOファイナンスのHTMLソースから名称を返す

    Dim POSS As Long
    Dim POSE As Long
    Dim RET As String

    POSS = InStr(1, HTMLSRC, "<title>", vbBinaryCompare)

    If POSS > 0 Then
        POSS = POSS + 7
        POSE = InStr(POSS, HTMLSRC, "【", vbBinaryCompare)
        If POSE > 0 Then RET = Trim(Mid(HTMLSRC, POSS, POSE - POSS))
    End If

    GetMeishou = RET

End Function

TITLEタグをINSTR関数で検索して、存在したらそのすぐ右側の位置を記憶。

その位置から左括弧を検索して終了位置を記憶。

HTMLソースからMID関数を使って取り出せばOK。

次は市場名

プログラムはこんな感じです。

Function GetShijyou(HTMLSRC As String) As String
'YAHOOファイナンスのHTMLソースから市場名を返す

    Dim POSS As Long
    Dim POSE As Long
    Dim RET As String

    POSS = InStr(1, HTMLSRC, "<span class=""stockMainTabName"">", vbBinaryCompare)

    If POSS > 0 Then
        POSS = POSS + 31
        POSE = InStr(POSS, HTMLSRC, "</span>", vbBinaryCompare)
        If POSE > 0 Then RET = Trim(Mid(HTMLSRC, POSS, POSE - POSS))
    End If

    GetShijyou = RET

End Function

市場名付近に存在する特徴的なHTMLタグは「<span class=”stockMainTabName”>」なので、これを検索。

同様に、存在したらそのすぐ右側の位置を記憶。

その位置から「</span>」というタブを検索して終了位置を記憶。

最後は業種

Function GetGyoushu(HTMLSRC As String) As String
'YAHOOファイナンスのHTMLソースから業種を返す

    Dim POSS As Long
    Dim POSE As Long
    Dim RET As String

    POSS = InStr(1, HTMLSRC, "<dd class=""category yjSb"">", vbBinaryCompare)

    If POSS > 0 Then
        POSS = POSS + 26
        If Mid(HTMLSRC, POSS, 2) = "<a" Then
        '業種にリンクが設定されている場合
            POSS = InStr(POSS, HTMLSRC, """>", vbBinaryCompare) + 2
            POSE = InStr(POSS, HTMLSRC, "</a>", vbBinaryCompare)
        Else
            POSE = InStr(POSS, HTMLSRC, "</dd>", vbBinaryCompare)
        End If
        If POSE > 0 Then RET = Trim(Mid(HTMLSRC, POSS, POSE - POSS))
    End If

    GetGyoushu = RET

End Function

特徴的なHTMLタグは「<dd class=”category yjSb”>」

業種にはリンク(=<a …></a>)が設定されている場合と設定されていない場合があるので、これを判断して処理を分けています。

銘柄コードを指定して株式の基本情報を取得するVBAプログラム

プログラムはこうなります。

Sub GetBasicInfo(CD As String)
'銘柄コードを指定して、株式の基本情報を取得して、テーブルを更新する

    Dim DB As DAO.Database
    Dim RS As DAO.Recordset
    Dim S As String
    Dim Meishou As String
    Dim Shijyou As String
    Dim Gyoushu As String

    Set DB = CurrentDb
    Set RS = DB.OpenRecordset("T_株式_基本情報", dbOpenTable)
    RS.Index = "PrimaryKey"

    S = GetHttpDocFromYahooFinance(CD)

    If S <> "" Then
    'ヤフーファイナンスから情報を取得できた場合
        Meishou = GetMeishou(S)
        Shijyou = GetShijyou(S)
        Gyoushu = GetGyoushu(S)
        If Meishou <> "" And Shijyou <> "" And Gyoushu <> "" Then
        '名称、市場名、業種、全て取得できた場合
            RS.Seek "=", CD
            If RS.NoMatch Then RS.AddNew Else RS.Edit
            'すでにレコードがあれば編集、なければ新規
            RS![銘柄コード] = CD
            RS![業種] = Gyoushu
            RS![市場] = Shijyou
            RS![名称] = Meishou
            RS.Update
            '基本情報を更新する
        End If
    Else
    'ヤフーファイナンスから情報が取得できないのにレコードが存在する場合
    '指定した銘柄コードが存在しない場合だけでなく、
    '何らかのエラーの場合もあるので、
    '自動削除はしないでメッセージを表示する
        RS.Seek "=", CD
        If Not RS.NoMatch Then
            Debug.Print "削除すべきデータ?=" & CD
        End If
    End If

End Sub

銘柄コードを指定して、ヤフーファイナンスからHTMLソースを取得。

HTMLソースを取得できたら、名称、市場名、業種を取得。

全て取得できたらテーブルにレコードを作成または既存のレコードを編集。

更新して終了。

HTMLソースを取得できないのにレコードが存在する場合はメッセージを表示。

全ての銘柄コードを使ってループ

最後に全ての銘柄コードを試してループを作ります。

銘柄コードは4桁なので1000~9999までループさせます。

プログラムは簡単。

Sub GetBasicInfoAll()
'全ての銘柄コードを対象として、株式の基本情報を取得する

    Dim I As Integer

    For I = 1000 To 9999
        Call GetBasicInfo(CStr(I))
        DoEvents
    Next I

End Sub

これで完成。

コンパイルしてイミディエイトウィンドウから以下の命令を実行すれば、テーブルにレコードが作成されるはずです。

CALL GetBasicInfoAll

全ての情報を取得するためには、パソコンの性能やネットワークの速度に依存すると思いますが、20~30分ぐらいかかると思います。

つまり、リアルタイムトレードには全く使えません。

あと、頻繁にこのプログラムを実行するとヤフーファイナンスに負荷をかけるので止めて下さい

注意点を2つ

Instr関数について

特定の文字を検索する場合で、結構悩んでしまいました。

具体的に悩んだのは「7202いすゞ自動車」

例えば、

Instr(“あいうえお”,”う”)=3

ですが、

Instr(“あゞうえお”,”う”)=4

になってしまうのです。

正しく判定させるためには、

Instr(1,”あゞうえお”,”う”,vbBinaryCompare)

と記述しなければダメで、これなら3だと判断してくれました。

ヤフーファイナンスのHTMLは変わる

今回、プログラムで特徴的なHTMLタグを検索しましたが、ヤフーファイナンスのHTMLタグは変更される事が多いので注意が必要です。

データが上手く取り込めなくなった場合、新しくなったHTMLソースをよく観察してプログラムを修正しましょう。

今回はここまで。

 - ACCESSデータベース, 週末プログラマー

↓ブログランキングに参加しています!


ネット・PC(全般) ブログランキングへ
にほんブログ村 IT技術ブログ ITコンサルティングへ
にほんブログ村

Message

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