Googleカレンダーに阪神タイガースの試合日程をインポートするためスクレイピング

最終更新時間:2019年02月27日 07時46分19秒

calendar2png.png
 
 昨日、Googleカレンダーにプロ野球の日程をインポートする方法を紹介したが、スクレイピングの情報源の日本野球機構の試合日程のページには、公式戦の日程しか載っていない。
 私は阪神ファンなのだが、すでに始まっているオープン戦の情報もぜひ載せたいと思い、阪神タイガースの公式サイトの試合日程のページをスクレイピングして(スクレイピングのしやすさから、ケータイ向けのページを参照している)、試合日程の情報をゲットし、これをGoogleカレンダーに表示してみた。
 スクレイピングするスクリプトは勉強中のPythonで書いてみた。これまた習作ということで。
 

#!/usr/bin/python3
#coding: utf-8

#scrapingtigers.py

import re
import datetime
import urllib.request
import pprint
from bs4 import BeautifulSoup

data = {}

team = {
    't':'阪神',
    's':'ヤクルト',
    'd':'中日',
    'h':'ソフトバンク',
    'e':'楽天',
    'f':'日本ハム',
    'l':'西武',
    'db':'DeNA',
    'm':'ロッテ',
    'bs':'オリックス',
    'g':'巨人',
    'c':'広島',
}

head = "Subject, Start Date, Start Time, End Date, End Time, Description, Location"
print(head)

month_days = {'03':'31', '04':'30', '05':'31', '06':'30', '07':'31', '08':'31', '09':'30'}

for month in month_days.keys():
    data.setdefault(month, {})
    for day in range(int(month_days[month])):
        data[month].setdefault(day + 1, {})
        data[month][day + 1].setdefault('date', '2019/' + month + "/" + ('0' + str(day + 1))[-2:])

for month in month_days.keys():
    html = urllib.request.urlopen("https://m.hanshintigers.jp/game/schedule/2019/" + month + ".html")
    soup = BeautifulSoup(html, features="lxml")
    day = 1
    for tag in soup.select('li.box_right.gameinfo'):
        text = re.sub(' +', '', tag.text)
        info = text.split("\n")
        if len(info) > 3:
            if info[1] == '\xa0':
                info[1] = ''
            data[month][day].setdefault('gameinfo', info[1])
            data[month][day].setdefault('start', info[2])
            data[month][day].setdefault('stadium', info[3])
            if re.match('オールスターゲーム', info[2]):
                data[month][day]['gameinfo'] = info[2]
                data[month][day]['start'] = '18:00'

        text = str(tag.div)
        if text:
            m = re.match(r'^.*"nologo">(\w+)<.*$', text, flags=(re.MULTILINE|re.DOTALL))
            if m:
                gameinfo = m.group(1)
                data[month][day].setdefault('gameinfo', gameinfo)
            m = re.match(r'^.*"logo_left (\w+)">.*$', text, flags=(re.MULTILINE|re.DOTALL))
            if m:
                team1 = m.group(1)
                data[month][day].setdefault('team1', team[team1])
            m = re.match(r'^.*"logo_right (\w+)">.*$', text, flags=(re.MULTILINE|re.DOTALL))
            if m:
                team2 = m.group(1)
                data[month][day].setdefault('team2', team[team2])

        day += 1

for month in month_days.keys():
    for day in data[month].keys():
        if data[month][day].get('start'):
            m = re.match(r'(\d+):(\d+)', data[month][day]['start'])
            if m:
                sthr = m.group(1)
                stmn = m.group(2)
                start = datetime.datetime(2019, int(month), int(day), int(sthr), int(stmn), 0)
                delta = datetime.timedelta(hours=4)
                end = start + delta
                sttm = start.strftime("%H:%M:%S")
                entm = end.strftime("%H:%M:%S")
                summary = ''
                if data[month][day]['gameinfo']:
                    summary = data[month][day]['gameinfo'] + " "
                if not re.match('オールスターゲーム', data[month][day]['gameinfo']):
                    summary += data[month][day]['team1'] + "対" + data[month][day]['team2']
                #head = "Subject, Start Date, Start Time, End Date, End Time, Description, Location"
                print(f"{summary}, {data[month][day]['date']}, {sttm}, {data[month][day]['date']}, {entm}, {summary}, {data[month][day]['stadium']}")

 使い方は「./scrapingtigers.py」と実行するだけ。
 3月からの情報をスクレイピングしている(2月のイベントはすでに終わってしまったと言うこともあるが、2月には、起亜タイガース相手の練習試合とか、紅白戦とか、イレギュラーな処理が必要なイベントがあり、それらが無視できるとうれしいということもある)。
 また、オープン戦、交流戦の場合は、イベント名の頭にそれぞれ「オープン戦」「交流戦」と表示される。
 さらには、試合開始時刻が不明だとイベントとして登録できないため、オールスターゲームの試合開始は勝手に18時とした。
 出力結果をcsvファイルとして保存し、GoogleカレンダーにインポートすればOK。