日記/2019-2-26

最終更新時間:2019年02月26日 09時40分48秒

Googleカレンダーにプロ野球の日程をインポートするためスクレイピング

 

calendar.png
 
 Googleカレンダーには、「関心のあるカレンダーを探す」から追加できるように、日本のプロ野球の日程があらかじめ用意されている(参考)。
 が、球団名が英語表記だったりしてどうも気に入らない。
 そこで、日本野球機構の試合日程のページをスクレイピングして、試合日程の情報をゲットし、これをGoogleカレンダーに表示してみた。
 スクレイピングするスクリプトは勉強中のPythonで書いてみた。習作ということで。
 

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

#scrapingnpb.py

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

data = {}

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', '10':'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:])
        data[month][day + 1].setdefault('id_date', 'date' + month + ('0' + str(day + 1))[-2:])

for month in month_days.keys():
    html = urllib.request.urlopen("http://npb.jp/games/2019/schedule_" + month + "_detail.html")
    soup = BeautifulSoup(html, features="lxml")
    for day in data[month].keys():
        for n in range(6):
            data[month][day].setdefault(n, {})
        num = 0
        for tr in soup.find_all("tr", attrs={"id": data[month][day]['id_date']}):
            div = tr.select_one("td>div.place")
            if div:
                p = re.sub(r'\s+', '', div.text)
                data[month][day][num].setdefault('place', p)
            div = tr.select_one("td>div.time")
            if div:
                data[month][day][num].setdefault('time', div.text)
            div = tr.select_one("td>div.team1")
            if div:
                data[month][day][num].setdefault('team1', div.text)
            div = tr.select_one("td>div.team2")
            if div:
                data[month][day][num].setdefault('team2', div.text)
            div = tr.select_one("td>div.commentLong")
            if div:
                data[month][day][num].setdefault('comment', div.text)
            num += 1

for month in month_days.keys():
    for day in data[month].keys():
        for num in range(6):
            if data[month][day][num].get('time'):
                m = re.match(r'(\d+):(\d+)', data[month][day][num]['time'])
                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][num].get('comment'):
                        summary = data[month][day][num]['comment']
                    else:
                        summary = data[month][day][num]['team1'] + "対" + data[month][day][num]['team2']
                    #head = "Subject, Start Date, Start Time, End Date, End Time, Description, Location"
                    if len(sys.argv) > 1:
                        m = re.search(sys.argv[1], summary)
                        if m:
                            print(f"{summary}, {data[month][day]['date']}, {sttm}, {data[month][day]['date']}, {entm}, {summary}, {data[month][day][num]['place']}")
                    else:
                        print(f"{summary}, {data[month][day]['date']}, {sttm}, {data[month][day]['date']}, {entm}, {summary}, {data[month][day][num]['place']}")

 使い方は「./scrapingnpb.py」、もしくは「./scrapingnpb.py 阪神」という風に球団名を与える。何も与えないとすべての日程が、球団名を与えるとその球団のみの日程が出力される。
 出力結果をcsvファイルとして保存し、GoogleカレンダーにインポートすればOK。