2017年6月8日木曜日

図書館の休館日をGoogleカレンダーに自動登録する

ときどき図書館に行くのだが、そういうときに限って休館日だったりする。そこで、図書館の休館日を自動的にGoogleカレンダーに登録できるようにする。方法は、図書館のホームページからスクレイピングで休館日を取得して、Google Calendar APIでGoogleカレンダーに登録する。これをPaspberry PiのPython3でやってみる。登録するのは国立国会図書館の休館日

環境


OSはRaspbian Jessie、Python3のバージョンは3.4。



Google Calendar APIを使う


Python3でGoogleカレンダーにイベントを追加するには、Google Calendar APIを有効にして認証キーを取得する必要がある。Python Quickstartに手順があるのでこれを参照。Google Developers Consoleのウィザードにアクセスして、ステップ1のjson形式の認証キーを保存するところまで進める。認証キーはclient_secret.jsonというファイル名で保存しておく。


GoogleカレンダーIDの確認


Google Calendar APIでカレンダーにイベントを登録するにはカレンダーIDが必要なので確認しておく。Googleカレンダーにブラウザでアクセスし、設定画面を開いて「カレンダー」をクリック。

さらに対象のカレンダーをクリックして詳細画面を開く。カレンダーアドレスの欄でカレンダーIDを確認できる。後でこのカレンダーIDを使うので、これをどこかにコピペしておく。


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


まずはGoogle APIを使うためのモジュールgoogle-api-python-clientをpipでインストールする(Python Quickstartのステップ2)。


続いてスクレイピングに使うモジュールBeautiful Soup4をインストール。



コーディング


Python Quickstartのステップ3にサンプルコード(quickstart.py)があるが、これはカレンダーからイベントを取得するコード。やりたいことはイベントの登録なので、サンプルコードをベースにして、さらにイベントを登録するコードを追加する。

まずはスクレイピングで使うモジュールをインポートする。以下のように追記する。
import re
from urllib.request import urlopen
from bs4 import BeautifulSou

次に以下の箇所を変更。
# Quickstartのサンプルはカレンダー参照用で、カレンダーに書き込むにはSCOPESを変更する
# SCOPES = 'https://www.googleapis.com/auth/calendar.readonly'
SCOPES = 'https://www.googleapis.com/auth/calendar'
# 認証キーのファイル名
CLIENT_SECRET_FILE = 'client_secret.json'
# アプリケーション名(任意)
APPLICATION_NAME = 'Google Calendar API Python Quickstart'

続いて、main関数を以下のように変更。GoogleカレンダーIDは、事前に確認しておいたものを指定する。
def main():
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('calendar', 'v3', http=http)

    # 以降Quickstartから変更
    
    # 図書館カレンダーをスクレイピングして休館日を取得
    # 当月と翌月の2ヶ月分あるが、翌月のカレンダーのみ取得する
    url = "http://www.ndl.go.jp/jp/service/tokyo/time.html"
    html_data = urlopen(url).read()
    html_parsed = BeautifulSoup(html_data, "html.parser")

    calendar = html_parsed.findAll("table", class_="calendarTable")[1]

    # 年と月のリスト
    yearmonth = re.findall('\d+', calendar.caption.text)

    # 休館日を取得
    holidays = calendar.findAll("td", class_="holiday")
    days = []
    for holiday in holidays:
        days.append(holiday.text.strip('()'))


    # Googleカレンダーに休館日を登録
    for day in days:
        # Googleカレンダーに登録する日付(YYYY-MM-DD)を作成
        date = "{}-{:0>2}-{:0>2}".format(yearmonth[0], yearmonth[1], day)

        # 休館日を終日イベントとして登録するように設定
        event = {
            'summary': '国会図書館休館日',
            'description': '国会図書館の休館日',
            'start': {
                'date': date,
                'timeZone': 'Asia/Tokyo',
            },
            'end': {
                'date': date,
                'timeZone': 'Asia/Tokyo',
            },
        }

        # 休館日を登録するGoogleカレンダーIDをcalendarIdに指定し、イベントを登録する
        event = service.events().insert(calendarId='calendarId.calendar.google.com', body=event).execute()



実行


Pythonコードのファイルとclient_secret.jsonをRaspberry Piの同じディレクトリに置く。初回実行時は認証情報を保存するのでブラウザで開いてコードを取得する必要があるが、ターミナルで実行する場合はブラウザを使えない。そこで--noauth_local_webserverオプションを使う。実行するとURLが表示されるので、それをコピーして、別PCなどのブラウザで開くとコードが表示される。それをコピーして、ターミナルのコード入力欄にペーストする。


これでホームディレクトリに.credentialsというディレクトリが作成され、その配下に認証情報ファイルが作成される。2回目以降は、すでに認証情報ファイルが作成されているので、ターミナルでもオプションは不要。


カレンダーの確認


Googleカレンダーで確認すると、図書館休館日が登録されている。



cronの設定


作成したPythonスクリプトをcronで毎月実行し、自動で図書館休館日をGoogleカレンダーに登録する。

以下のコマンドでcronの設定を開く。


毎月10日5時ちょうどに実行する場合は、以下のような1行を追記する。


最後にcronを再起動。


4 件のコメント:

  1. 以降Quickstartから変更 とはどこから変更すればよいのでありましょうか大佐

    返信削除
  2. 熟読してもわからなかったのでソースコードを全てくださると辛いです

    返信削除
    返信
    1. 国立国会図書館の休館日ページのHTMLが変更されたようです。それにPython Quickにあるコードは、この記事を書いたときに参照したものと変わっていますので、ここで紹介したPythonコードは意図した通りに動作しないと思います。いつか直したいと思いますが、あまり期待はしないでください。

      削除