ボートレースデータを取得する その3

コンピューター

Visual Studio Community & C#に変更します。

その1その2では、ExcelVBAベースでデータの取得を行っていましたが、その後の内容を行うにあたり、VBAでは難しい部分が出てきた為、Visual Studio Communityをインストールし、勉強を兼ねてC#で進行することにしました。

以下の記事に、Visual Studio Communityのインストールについて記事にしてあります。

Windowsプログラミングを始めてみる for desktop
windowsでデスクトップアプリケーションを作る windows11の発表がありましたね。ふと、デスクトップアプリケーションでも作ってみるかと思い、どうせ作るなら、勉強がてら、新しい言語でもと記事を書いています。かなり思い付きなんので、...

ボートレース公式サイトからデータを取得する

ボートレース公式では、各種データの公開が行われています。

https://boatrace.jp/

今回は、Visual Studio Communityを使い、C#で、指定した年月に該当する番組表、競走成績を取得します。検証等に時間がかかるので、分割して記事にしてあります。

2021年6月20日の時点では、ボートレース公式サイトのSSL化は行われていません。各種データも実質非標準となりつつあるlha形式を使用しています。コードを作成するにあたり、運営の方針変更等で構成の変更がある事も想定しておく事が必要です。

その1 公式サイトからダウンロードする

操作画面

簡単な画面ですが、カレンダーで年月を行い、番組表又は競走成績を選択した状態で、下記ボタンで処理を行います。中央の部分には、処理状況を表示します。

ダウンロード、解凍、ファイル出力は一連で処理可能ですが、今回は個別に実行する様にしました。

ダウンロード

番組表:http:www1.mbrace.or.jp/od2/B/{YYYYMM}/b{YYMMDD}.lzh
競走成績: http://www1.mbrace.or.jp/odds2/K/{YYYYMM}/k{YYMMDD}.lzh

指定した年月、種類を元に公式サイトからlzhファイルをダウンロードします。

private void BtnDownload_Click(object sender, EventArgs e)
{
    string strExePath = Application.StartupPath;
    if (strExePath.Substring(strExePath.Length - 1) != @"\")
    {
        strExePath = string.Concat(strExePath, @"\");
    }

    DateTime dtmEom = new DateTime(DtpMonth.Value.Year, DtpMonth.Value.Month, 1).AddMonths(1).AddDays(-1);

    LsbLog.Items.Add($@"[{DateTime.Now:yyyy/MM/dd hh:mm:ss}]BoatRaceTools Download Start {dtmEom:yyyy 年 MM 月}");

    if (RbProgram.Checked)
    {
        string strUrl = $@"http://www1.mbrace.or.jp/od2/B/{dtmEom:yyyyMM}/";
        DownloadUrlFile(strExePath, strUrl, dtmEom, "b"); // "b"は小文字
    }
    else
    {
        string strUrl = $@"http://www1.mbrace.or.jp/odds2/K/{dtmEom:yyyyMM}/";
        DownloadUrlFile(strExePath, strUrl, dtmEom, "k"); // "k"は小文字
    }

    LsbLog.Items.Add($@"[{DateTime.Now:yyyy/MM/dd hh:mm:ss}]BoatRaceTools Download End");

}

strExePath : 実行ファイルのパス
dtmEom : 画面で選択された年月の月末日
strUrl : 選択された処理(番組表、競走成績)によりダウンロードアドレスを設定

private void DownloadUrlFile(string strExePath, string strUrl, DateTime dtmEom, string strType)
{
    string strOutPath = $@"{strExePath}{dtmEom:yyyyMM}\";
    Directory.CreateDirectory(strOutPath);

    for (int i = 1; i <= dtmEom.Day; i++)
    {
        string strFileName = $@"{strType}{dtmEom:yyMM}{i:00}";
        string strUrlFile = $@"{strUrl}{strFileName}.lzh";
        string strArcFile = $@"{strOutPath}{strFileName}.lzh";

        try
        {
            using (WebClient webClient = new WebClient())
            {
                webClient.DownloadFile(strUrlFile, strArcFile);
                LsbLog.Items.Add($@"[{DateTime.Now:hh:mm:ss}]Download {strFileName}");
            }
        }
        catch (Exception e)
        {
            LsbLog.Items.Add($@"[{DateTime.Now:hh:mm:ss}]Download {strFileName} [{e.Message}]"); // 開催日でなければ無い
        }
        finally
        {
            Thread.Sleep(2000);
            LsbLog.Refresh();
        }
    }
}
  • 実行ファイル配下に対象年月のフォルダを作成(既に存在するフォルダに対して、Directory.CreateDirectoryを実行してもエラーになりません)
  • 対象年月を1日から月末日迄、繰り返す。
  • webClient.DownloadFileは、格納先フォルダが無いとエラーになります
  • 非開催日はエラーになるので例外処理を使い継続する
  • サーバー負荷を考慮し、ダウンロード間隔を2秒空ける

まとめ

文字列の結合方法は複数あり、規約等で事前に決めていない限り、好みの問題だと思います。今回は、string.Concatと$特殊文字を使った文字列補間を利用しています。文字列補間に使用するリテラル内にエスケープ文字が存在する場合、@特殊文字も付加する必要があります。2つの特殊文字を付加する場合、$@の順番で付加します。

コメント

タイトルとURLをコピーしました