LoginSignup
0
0

More than 3 years have passed since last update.

C# .NetCoreで、ボートレース結果の解析 スタ展スクレイピング

Last updated at Posted at 2020-10-31

やらなきゃならないこと

ボートレース公式サイトからスタート展示情報のスクレイピングを行う。

開発環境

Windows10
Visual Studio Community 2019
C# .Net Core 3.1

注意

スクレイピングは取得先のサーバの過負荷にならないように注意して扱うこと。
また、スクレイピングに関する規定があるため、確認は行うこと。

.NetCoreでのスクレイピング

参考:https://www.casleyconsulting.co.jp/blog/engineer/183/

大まか流れ

  • URLに対してのRequestを作成
  • URLに対してRequestを投げResponseを取得。
  • 必要な内容をパターンで検出する。

Requestを生成

var req = (HttpWebRequest)System.Net.WebRequest.Create(string url)

でURLに対するリクエストを生成する。

Requestに対するResponseを取得

var resreq = (HttpWebResponse)req.GetResponse()

Responseを読み込むためにStreamを取得

var resSt = resreq.GetResponseStream()

Streamを使いHTMLを読み込む。

string htmlData = "";
using( var sr = new StreamReader(resSt, Encoding.UTF8)) )
{
   htmlData = sr.ReadToEnd()
}

まとめると

static public string GetHtmlString(string url)
{
    string rtn = "";
    var webReq = (HttpWebRequest)WebRequest.Create(url);
    using (var webResponse = (HttpWebResponse)webReq.GetResponse())
    using (var responseStream = webResponse.GetResponseStream())
    using (var streamReader = new StreamReader(responseStream, Encoding.UTF8))
    {
        rtn = streamReader.ReadToEnd();
    }
    return rtn;
}

実際にやる

直前情報のURLを対象に実際にやってみる。

URLパターン

https://www.boatrace.jp/owpc/pc/race/beforeinfo?rno=[RaceNum]&jcd=[RacePlace]&hd=[RaceDate]
  • [RaceNum]:レース番号(1,2,3,4,5,6,7,8,9,10,11,12)
  • [RacePlace]:開催場下2桁固定(01,02,03,.....,21,22,23,24)
  • [RaceDate]:開催年月日8桁(yyyymmdd)

例:2020年9月31日 ボートレース戸田 8R の場合(実際あるかは知らない)

https://www.boatrace.jp/owpc/pc/race/beforeinfo?rno=8&jcd=02&hd=20200931

HTMLのパターン

実際に取得しパターンを確認してみた。
以下の部分がスタート展示の情報。

<tr>
  <td colspan="3">
              <div class="table1_boatImage1">
                <span class="table1_boatImage1Number is-type1">1</span>
              <span class="table1_boatImage1Line"><span class="table1_boatImage1Boat" style="left: 59%;"><img src="/static_extra/pc/images/img_boat2_1.png" width="54" height="27" alt=""></span></span>
                <span class="table1_boatImage1Time">.06</span>
          </div><!-- /.table1_boatImage1 -->
  </td>
</tr>
<tr>
  <td colspan="3">
              <div class="table1_boatImage1">
                <span class="table1_boatImage1Number is-type2">2</span>
              <span class="table1_boatImage1Line"><span class="table1_boatImage1Boat" style="left: 37%;"><img src="/static_extra/pc/images/img_boat2_2.png" width="54" height="27" alt=""></span></span>
                <span class="table1_boatImage1Time">.28</span>
          </div><!-- /.table1_boatImage1 -->
  </td>
</tr>
<tr>
  <td colspan="3">
              <div class="table1_boatImage1">
                <span class="table1_boatImage1Number is-type3">3</span>
              <span class="table1_boatImage1Line"><span class="table1_boatImage1Boat" style="left: 56%;"><img src="/static_extra/pc/images/img_boat2_3.png" width="54" height="27" alt=""></span></span>
                <span class="table1_boatImage1Time">.09</span>
          </div><!-- /.table1_boatImage1 -->
  </td>
</tr>
<tr>
  <td colspan="3">
              <div class="table1_boatImage1">
                <span class="table1_boatImage1Number is-type4">4</span>
              <span class="table1_boatImage1Line"><span class="table1_boatImage1Boat" style="left: 42%;"><img src="/static_extra/pc/images/img_boat2_4.png" width="54" height="27" alt=""></span></span>
                <span class="table1_boatImage1Time">.23</span>
          </div><!-- /.table1_boatImage1 -->
  </td>
</tr>
<tr>
  <td colspan="3">
              <div class="table1_boatImage1">
                <span class="table1_boatImage1Number is-type5">5</span>
              <span class="table1_boatImage1Line"><span class="table1_boatImage1Boat" style="left: 54%;"><img src="/static_extra/pc/images/img_boat2_5.png" width="54" height="27" alt=""></span></span>
                <span class="table1_boatImage1Time">.11</span>
          </div><!-- /.table1_boatImage1 -->
  </td>
</tr>
<tr>
  <td colspan="3">
              <div class="table1_boatImage1">
                <span class="table1_boatImage1Number is-type6">6</span>
              <span class="table1_boatImage1Line"><span class="table1_boatImage1Boat" style="left: 38%;"><img src="/static_extra/pc/images/img_boat2_6.png" width="54" height="27" alt=""></span></span>
                <span class="table1_boatImage1Time">.27</span>
          </div><!-- /.table1_boatImage1 -->
  </td>
</tr>

上から1,2,3,4,5,6コースとなる(艇番ではなく)

競番の検出はここで行う。

<span class="table1_boatImage1Number is-type[Course]">[Value]</span>

- [Course]:コース
- [Value]:枠番

タイムの検出はここで行う。

<span class="table1_boatImage1Time">[Time]</span>
  • [Time]:スタートタイム(.XX)

実際にまとめると以下の通りとなる。

        static public string[] SearchTenjiSt(string html)
        {
            var lines = html.Split('\n');
            string[] rtn = new string[12] { "", "", "", "", "", "", "", "", "", "", "", "" };

            int num = 0;
            foreach (var line in lines)
            {
                if (line.Contains("table1_boatImage1Number"))
                {
                    var temp = line.Replace("<", ">");
                    var temp2 = temp.Split(">");
                    rtn[num++] = temp2[2];
                }
                if (line.Contains("table1_boatImage1Time"))
                {
                    var temp = line.Replace("<", ">");
                    var temp2 = temp.Split(">");
                    rtn[num++] = temp2[2];
                }
            }
            if (num == 0)
            {
                rtn = null;
            }
            return rtn;
        }

実行結果

まとめることが可能になった。

2019,10,01,5,1,1,.06,2,.28,3,.09,4,.23,5,.11,6,.27,

まとめ

スクレイピングが可能になった。
試しに1年間分を取得間隔2.5秒で実施したら、3日かかった。

次回は今まで取得したデータをまとめていきたいと思う。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0