まるっとワーク

データ分析・電子工作など気になることを残していきます

Python(BeautifulSoup4):ネットのページから必要情報を取得する(野球の試合状況を取得する)

特定の(最新)情報を入手して、何かをしたい場合、情報入手先にアクセスして、情報を取得する作業が必要となります。その方法をこのページではまとめます。
今回はその例として野球試合情報を入手するコードを紹介します。

目次

使用環境

$wmic os get caption
>Microsoft Windows 10 Pro

$wmic os get osarchitecture
>64ビット

$python -V
Python 3.11.2

手順

  1. 必要モジュールのインストール
  2. コード作成/実行

必要モジュールのインストール

今回は、Requests, BeautifulSoup4モジュールを使用します。
Requestsモジュールは、HTMLデータの取得に使用します。
その後、必要情報のみを抽出する為、HTMLデータの抽出で使用するのが、BeautifulSoup4モジュールになります。
HTMLとは「ハイパーテキストマークアップ・ランゲージ(Hyper Text Markup Language)」のことで、WEBページを作成するための言語で、ほとんどのウェブページは、HTMLで作成されています。
Google Chrome(グーグルクローム)のブラウザを使う場合、F12キーを押すと、デベロッパーツールが起動して、HTMLの内容を確認できますね。必要情報が、HTML内のどこに存在するのかを確かめながら、コードを組むのがよさそうです。

まずはBeautiful Soupをインストールしましょう。pipのコマンドでインストールすることが出来ます。
モジュールの詳細は以下をご参照ください。
www.crummy.com

pip install requests
pip install beautifulsoup4


コード作成/実行

今回の目的(野球の試合状況を取得する)は、以下コードで実現しています。
このコードを短期間で連続使用する場合、サーバーに負荷がかかるため、気を付けた方がよさそうです。

import requests
from datetime import datetime
from time import sleep
from bs4 import BeautifulSoup

#######野球設定
OUR_TEAM = "広島" #情報取得したいチーム名をTEM_LIST内から1チーム選ぶ
TEAM_LIST = ["広島", "ヤクルト", "阪神", "DeNA", "中日", "巨人"]

def live_scores(date) ->"yyyy-mm-dd":

    # URLを指定
    url = "https://baseball.yahoo.co.jp/npb/schedule/?date=" + date

    # URLにアクセスしてHTMLを取得
    try:
        print(url)
        response = requests.get(url)
    except: 
        print('Error')
    html = response.text

    # HTMLを解析してBeautiful Soupオブジェクトを作成
    soup = BeautifulSoup(html, "html.parser")
    #print("soup",soup)

    # スコアのテーブルを取得    
    game_card = soup.find_all("ul", class_="bb-score__card bb-score__card--separate")
    game_card_several_team_name = soup.find_all("div", class_="bb-score__team")
    game_card_several_score = soup.find_all("div", class_="bb-score__detail")

    num = []
    for row in range(len(game_card_several_team_name)):
        # 日付、対戦相手、スコア、勝敗、詳細ページのURLを取得
        if OUR_TEAM in str(game_card_several_team_name[row]):
            num.append(row)

    if num :
        check_dict = {}
        buff = game_card_several_team_name[num[0]].find_all("p")
        for i in range(len(buff)):
            for name in TEAM_LIST:
                if name in str(buff[i]):
                    check_dict[name] = i
        n=0
        for i in list(check_dict.keys()):
            if n == 0:
                home_team = i
            else:
                away_team = i
            n+=1
        if home_team == OUR_TEAM:
            home_team_flg = 1
        else:
            home_team_flg = 0
        
        print(home_team, away_team)

        try: 
            if home_team_flg:
                game_status = "ホーム"
                home_score = game_card_several_score[num[0]].find("span", class_="bb-score__score bb-score__score--left").text.strip()
                away_score = game_card_several_score[num[0]].find("span", class_="bb-score__score bb-score__score--right").text.strip()
            else:
                game_status = "アウェイ"
                away_score = game_card_several_score[num[0]].find("span", class_="bb-score__score bb-score__score--left").text.strip()
                home_score = game_card_several_score[num[0]].find("span", class_="bb-score__score bb-score__score--right").text.strip()
                
            now_game_status = game_card_several_score[num[0]].find("p", class_="bb-score__link").text.strip()        
            if now_game_status == "試合終了":
                if home_score > away_score:
                    status_comment = "勝った"
                elif home_score < away_score:
                    status_comment = "負けた"
                elif home_score == away_score:
                    status_comment = "引き分けた"
            else:
                if home_score > away_score:
                    status_comment = "勝っている"
                elif home_score < away_score:
                    status_comment = "負けている"
                elif home_score == away_score:
                    status_comment = "引き分けている"
            return date + "の" + OUR_TEAM + "の試合は" + now_game_status + "で、スコアは" + home_score + "-" + away_score + "で"+status_comment
        except:
            print("skip")
        
            now_game_status = game_card_several_score[num[0]].find("p", class_="bb-score__link").text.strip()
            return  date + "は" + OUR_TEAM + "の試合は開催前で、午後開催" 
    else:
        return  OUR_TEAM + "は" + "の試合はない"


簡単にコードを解説すると、

  • requests.get(url)にて指定のURLのHTMLを取得する
  • soup = BeautifulSoup(html, "html.parser")にてHTMLを解析する(HTMLパーサー)

 Webページから必要情報を取得したりすることを、スクレイピングと呼びますが、スクレイピングは、“データを収集した上で利用しやすく加工すること"のようです。その後、必要情報を取得するコードは、BeautifulSoupライブラリを使って実行しており、今回は、".find"などを使って、必要情報を抽出しています


参考までに実行結果を紹介すると、

live_scores("2023-04-22")

Output: '2023-04-22の広島の試合は試合終了で、スコアは3-0で勝った'


まとめ

今回は、ネットページから必要情報を取得する例を紹介しました。
定期的に何かの情報を取得して使用するといった処理が必要な場合に重宝しそうですね