Web開発修行中のやきうオタクです。
NPB公式戦のスコアや勝敗を自動取得する方法を探しているのですが、それっぽい手頃なAPIが見つかりませんでした。
NPB公式サイトの日次試合結果が掲載されているページが
・日程別にページURLが規則的であること
・チーム名、スコア部分のhtml書式が規則的であること
・年度問わず掲載コンテンツのレイアウトが統一されていること
から、スクレイピング的な処理でも簡単に任意日程のスコアを取得できそうだったので試してみました。
スクレイピングといってもPHPでページコンテンツの簡易的な解析を行うのみで、特にライブラリなどは使用していません。
サンプルコード
<?php
// 対象チームと試合日の指定
$targetTeam = 'オリックス';
$date = new DateTime('2023-08-05');
$dateStr = $date->format('Ymd');
// 試合結果ページのURL生成
$url = 'https://npb.jp/bis/' . $date->format('Y') . '/games/gm' . $dateStr . '.html';
// ページのコンテンツを文字列で取得
$html = file_get_contents($url);
// 試合結果の情報テキスト部分を分割
$scoreTexts = explode('<td class="contentsTeam">', $html);
// テキストを試合ごとに配列に分割
$elements = [];
foreach($scoreTexts as $text) {
$elements[] = explode('</td>', $text);
}
// 配列の各テキストから要素を抽出
$output = [];
for($i=1; $i<=12; $i++) {
$output[$i] = [
$elements[$i][0], // ホームチーム名
$elements[$i+1][0], // ビジターチーム名
$elements[$i][1], // ホームチーム得点
$elements[$i][3], // ビジターチーム得点
];
// スコア部分のタグを除去
$output[$i][2] = str_replace('<td class="contentsRuns">', '', $output[$i][2]);
$output[$i][3] = str_replace('<td class="contentsRuns">', '', $output[$i][3]);
$i += 1; // 偶数番目は必要情報を持たないためスキップ
}
// 抽出結果を出力
print $date->format('Y年n月j日') . 'の' . $targetTeam . 'の試合結果は、';
foreach($output as $item) {
if ($item[0] == $targetTeam || $item[1] == $targetTeam) {
print ($item[0] . ' ' . $item[2] . '-' . $item[3] . ' ' . $item[1] . "\n");
}
}
出力結果
調査過程と処理について
ざっくりとだけ書きますとただの泥臭い作業です←
まず file_get_contents
でHTMLテキストを取得し、欲しい球団名とスコアの部分の構造を解析しながら抽出・加工 → テキスト出力 を期待する文字列結果になるまで繰り返します。
- 抽出ターゲットとなる箇所を囲っているタグを見つける
- 対象の開始タグ・閉じタグ部分で
explode
関数を使ってテキストを切り取る - 配列に入れて出力してみる
- 球団名、スコアを値として持つ要素番号を見つける
- 不要タグなどを除去しながら出力する
課題と応用
スクレイピング共通の課題ですが、NPB公式ページを勝手に解析しているだけなので、サイト側の書式やレイアウト、URLの構造などが変わると一発で詰みます。
応用パターンとしては、コード上にベタ書きしている対象球団・日程を変数として任意の入力値で計算させれば、贔屓球団の特定日程のスコアと勝敗を取得できるので、「自分が観に行った日の推しチームの通算成績」などが算出できるようになると思います。
※ゆくゆく自分用の観戦備忘録として活用したいなと考えています。
NPBさん、個人開発者にも手を出せるいい感じの速報APIの提供をぜひともお願いします!←