はじめに
野球を見ていると「試合の流れ」があると言われます。
野球は素人ですが、長く試合を見ていると点が入りそうな雰囲気を分かるときがたまにあります。
セイバーメトリクスなど色々なデータがありますが、自分なりにスコアを分析してみたくなりました。
スコアデータの取得
試合結果のデータを取得できるようなAPIは見つけられなかったので、プロ野球公式のページがからスクレイピングしてデータを取得することにします。
elixirでスクレイピング
少し調べるとelixirでスクレイピングするには、HTTPoison, Flokiというライブラリを使えばいいようです。
手始めに3/29の阪神-巨人戦のスコアを取得してみます。(ちなみに阪神ファンです)
document = HTTPoison.get!("https://npb.jp/scores/2024/0329/g-t-01/").body
|> Floki.parse_document!
|> Floki.find("div#table_linescore")
htmlをFlokiに渡せばmapとして取得できるようです。
データ整形
今考えている分析に欲しい情報は、チーム名、イニングごとの得点、最終スコアなのでFlokiのセレクタを駆使して取得します。
inning = document
|> Floki.find("tr.top")
name = inning
|> Floki.find("span.hide_sp")
|> Floki.text()
scores = inning
|> Floki.find("td")
|> Enum.filter(fn {_tag, attrs, _value} ->not Enum.any?(attrs, fn{attr, _attr_val} -> attr == "class" end)end )
|> Enum.map(fn {_tag,_attr,value} -> value end)
total = inning
|> Floki.find("td.total-1")
|> Floki.text()
%{name: name,scores: List.flatten(scores),total: total}
スケジュールからスコアのリンクを作成
https://npb.jp/scores/2024/0329/g-t-01/
上記のような試合速報のリンクは下記の試合結果のページから取得できます。
game_links = HTTPoison.get!("https://npb.jp/games/2024/schedule_03_detail.html").body
|> Floki.parse_document!
|> Floki.find("tbody a[href]")
|> Floki.attribute("href")
これで2024年3月の試合速報のリンクがリストとして取得できるので、データを整形します。
JSON形式でファイル保存
取得したデータをJsonファイルに保存します。
chatGPTに聞くと次のようなコードが出てきました。
case Jason.encode(data) do
{:ok, json_string} ->
# JSON文字列を指定したファイルに書き込み
case File.write(file_path, json_string) do
:ok -> {:ok, "File saved successfully!"}
{:error, reason} -> {:error, "Failed to save file: #{reason}"}
end
{:error, reason} ->
{:error, "Failed to encode JSON: #{reason}"}
end
終わりに
分析に必要そうなファイルは保存することができたので、次はこのファイルを使って何か分析してみたいと思います。
追記
整理したソースをgithubにあげました。
下記のように実行すると2024年3月分の試合結果がscoresフォルダに作成されます。
NpbGamesCrawler.crawl("2024","03")