競馬について徒然と

競馬について適当に書きます. ちょっとtech系風味も入れて.

TARGETで足りない情報をnetkeibaからスクレイピングして持ってくる

TARGETのGUIが辛いので、CSVで出力してPerlスクリプト書いて色々処理する事が多いのですが、そもそも欲しい情報がない場合とか結構あります。例えばコーナーごとの通過順位、こういうやつです。

14,3-8,5(2,6,17)(4,1,9)(7,12,15)(18,13)16-(11,10)

見方はここにあります。

単にコーナーの順位だけならTARGETでも取れます。こういう感じで。

ただ、これだと「内」「外」がわからないのですよね。まあ枠順に近い形にはなるんですけど、内から大外持ち出すとか内に切り込むとかもあるので、できればこの情報がほしい。

じゃああるところから持ってくればいいじゃないか、ということでnetkeibaからスクレイピングして引っ張ってみたいと思います。

目次

注意

  • スクレイピングは節度を守って行いましょう。
  • スクレイピングを行ったことによるいかなる損害等についても保証しません。(いつアクセス拒否されてもおかしくないですし、場合によっては訴えられる可能性もあります。)
  • リニューアル等によりスクレイピングが動作しなくなる可能性は大いにあります。それと付き合っていく必要があります。

まあスクレイピングってそういうものだから、色々考えても可能ならあまりやりたくないのが本音です・・・

レースIDについて

TARGETでもnetkeibaでも各レースごとにそれぞれ固有のIDを持っています。なので、

  • TARGETからレースIDを含めたCSVを出力
  • TARGETのレースIDを元にnetkeibaの該当レースから必要な情報をスクレイピング

すればできるはずです。

まず最初にIDがどうなっているのか見てみましょう。

TARGET

TARGET(というかJRA-VAN)のレースID(新レースIDで馬番なしの場合)はこうなっています。2022年の日本ダービーの場合。

2022052905021211

JRA-VANの仕様だとこうなります。

2022 - 開催年
05   - 開催月
29   - 開催日
05   - 場所コード
02   - 回次
12   - 日次
11  - レース番号

回次と日次は「5回東京2日目」みたいなやつです。

レース番号はその日の1〜12Rのことですね。

場所コードは競馬場のIDのことです。中央競馬だとこうなります。

01 - 札幌
02 - 函館
03 - 福島
04 - 新潟
05 - 東京
06 - 中山
07 - 中京
08 - 京都
09 - 阪神
10 - 小倉

ちなみに地方や海外なども定義されています。

netkeiba

netkeibaの2022年ダービーのページのURLはこうなっています。

https://race.netkeiba.com/race/result.html?race_id=202205021211&rf=race_list

ここのrace_idというやつですね。

race_id=202205021211

これはこういうふうになっています。

2022 - 開催年
05   - 場所コード
02   - 回次
12   - 日次
11   - レース番号

場所コードは同じっぽいですね。

01 - 札幌
02 - 函館
03 - 福島
04 - 新潟
05 - 東京
06 - 中山
07 - 中京
08 - 京都
09 - 阪神
10 - 小倉

TARGETからnetkeibaへの変換はカンタンですね。逆の場合は日付を算出しないといけないのでちょっと難しいかもしれないですね。

Googleスプレッドシートでnetkeibaをスクレイピングする

では、実際にスクレイピングしてみましょう。今回はGoogleスプレッドシートを使ってカンタンにやってみます。

最初にこういうシートを用意します。

JRA-VANのレースIDをB1に入力します。今回は2022年のダービーのものにしますので2022052905021211を入力。

JRA-VANのレースIDをnetkeibaのものに変換します。B2に以下の数式を入れます。

=CONCATENATE(LEFT(B1,4),RIGHT(B1,8))

こうなります。

このnetkeibaのレースIDを使って、該当レースのページのURLを作ります。B3に以下を入力します。

=CONCATENATE("https://race.netkeiba.com/race/result.html?race_id=",B2,"&rf=race_list")

URLができていますね。

次にスクレイピングです。GoogleスプレッドシートにはIMPORTXMLという関数があります。

HTMLは構造化された文書です。この構造の要素を抽出するための指定方法としてXpathというものがあります。IMPORTXMLを使うと、URLで指定したページのXPathを指定して特定の情報を引っ張ってくることができます。

ではnetkeibaのページから取りたい情報のXpathを取得しましょう。さきほど生成したURLにアクセスします。

Chromeデベロッパーツールを開きます。

開きました。

ではスクレイピングしたい要素のXPathを取得します。右側の画面の左上にある「ページ内の要素を選択して検査」のアイコンをクリックします。

左の画面の取得したい情報のところにカーソルを移動してクリックします。今回の例だと、4コーナーの通過順位になりますね。

クリックすると、右上のHTMLのソースの一部分が選択されているのがわかると思います。これがさきほど選択した部分のHTMLになります。

タグが折りたたまれているのを開くと、それっぽい感じになっているのがわかると思います。

では、この部分のXPathを取得します。選択されている部分を右クリックして、「コピー」 → 「XPathをコピー」を選択します。

これをスプレッドシートB4にペーストします。これが4コーナーの通過順位の部分のXPathです。

//*[@id="tab_ResultSelect_1_con"]/div[2]/div[1]/div[2]/table/tbody/tr[4]/td

ではIMPORTXMLで引っ張ってきてみましょう。以下をB5に入力します。

=IMPORTXML(B3,B4)

こうなります。

取れてはいる・・・けど一つのセルに収まってないですね。XPathで指定した階層の下にもHTMLタグなどの要素があると配列で返ってくるのでセルごとに別れてしまうようですね。以下のようにして一つの文字列として結合しましょう。

=JOIN("",IMPORTXML(B3,B4))

できました!

実際のスクリプトでやる場合にはスクレイピング負荷とかも考える必要がありますが、取得した隊列情報をさらに解析すれば内・外とかもわかりますし、より予想に役立つ情報をまとめることができそうです!