こんにちは。タイトルが意味不明かもしれませんが、これは以下の記事の続き的な立ち位置です。
www.77-lifework.com
さわやかの待ち時間を調べられるサイトを定期的にスクレイピングし、待ち時間をスプレッドシートに記録した上、どの時間帯が空いているのか調べてみようというテーマです。
動機や背景は前の記事と同じなので、はしょります。
割と真剣にやっちゃいましたので、ぜひご覧ください。
処理の流れと出力結果
まず、使用しているプログラミング言語はPythonで、待ち時間をスクレイピングし、Googleスプレッドシートに結果を書き込むプログラムを作成しました。これをLinuxサーバに配置し、cronで15分ごとに実行しています。
結果は以下のようになります。日付ごとのシートが作成され、各店舗の待ち時間が書き込まれています。
営業時間外の場合は「-1」を書き込むようにしています。データベースで管理するほど大量のデータを扱う気はなかったので、今回は代わりにスプレッドシートを使用しました。
Pythonのコード
さて、今回のPythonコードですが、以下です。
# coding: UTF-8 import os import locale import gspread from oauth2client.service_account import ServiceAccountCredentials import slackweb import time import datetime from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.chrome.options import Options # 定数宣言 SLACKURL_ex = '例外発生時のslack通知用URLを入力' #jsonファイルを指定 CREDENTIAL_JSON = 'スプレッドシートアクセスのためのjsonファイルのパスを指定' # main処理 def main(): scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive'] # 認証 credentials = ServiceAccountCredentials.from_json_keyfile_name(CREDENTIAL_JSON, scope) gc = gspread.authorize(credentials) # 対象ブックを指定 target_book = gc.open('sawayaka_analysis') # 現在日付を取得 now_date = datetime.date.today().strftime('%Y-%m%d') # シート名一覧を取得 worksheet_list = target_book.worksheets() sheetname_list = [] for wsList in worksheet_list: sheetname_list.append(wsList.title) if not now_date in sheetname_list : target_book.add_worksheet(title=now_date, rows=100, cols=26) # 書き込み対象のシートを指定 target_sheet = target_book.worksheet(now_date) # スクレイピング対象URL URL = "https://www.genkotsu-hb.com/airwait.php" # スクレイピング実行 try: # 現在時刻取得 now_time = datetime.datetime.now().strftime('%H:%M') # Chrome設定 options = Options() options.add_argument('--headless') # Chromeを起動してurlを開く driver = webdriver.Chrome(options=options) driver.get(URL) time.sleep(20) # 文字コードをUTF-8に変換し、html取得 html = driver.page_source.encode('utf-8') soup = BeautifulSoup(html, "html.parser") # 対象店名読み込み storeTagList = soup.find_all('div', class_='sc-fONwsr bmOhpB') # 店名入力対象セルを取得 storeName_cells = target_sheet.range(1,1,1,len(storeTagList)+1) storeName_cells[0].value = '時刻/待ち時間' for i in range(0, len(storeTagList)): storeName_cells[i+1].value = str(storeTagList[i]).replace('<div class="sc-fONwsr bmOhpB">', '').replace('</div>', '') # スプレッドシートへ店名書き込み target_sheet.update_cells(storeName_cells) # 待ち時間入力対象列を決定 colList = target_sheet.col_values(1) target_rownum = len(colList) + 1 # 待ち時間入力対象セルを取得 waitTime_cells = target_sheet.range(target_rownum,1,target_rownum,len(storeTagList)+1) waitTime_cells[0].value = now_time for i in range(0, len(storeTagList)): # tagとclassを指定して要素を取り出す storeElement = soup.find('div', string=storeName_cells[i+1].value) waitingTimeObj = storeElement.find_parent('a').find('div',class_='sc-ipXKqB iHAIGD') if (waitingTimeObj is not None): waitTime_cells[i+1].value = waitingTimeObj.text.replace("約","").replace("分待ち", "") else: # 受付時間外は-1を代入 waitTime_cells[i+1].value = -1 # スプレッドシートへ待ち時間書き込み target_sheet.update_cells(waitTime_cells) except Exception as e: message = "[例外発生]"+ os.path.basename(__file__) +"\n"+"type:{0}".format(type(e))+"\n"+"args:{0}".format(e.args) slackweb.Slack(url = SLACKURL_ex).notify(text = message) finally: # 起動したChromeを閉じる driver.close() driver.quit() if __name__ == '__main__': main()
スプレッドシートへの書き込み処理については以下の記事を参考にしてください。
www.77-lifework.com
ちなみに、
# 定数宣言 SLACKURL_ex = '例外発生時のslack通知用URLを入力'
ってところと
except Exception as e: message = "[例外発生]"+ os.path.basename(__file__) +"\n"+"type:{0}".format(type(e))+"\n"+"args:{0}".format(e.args) slackweb.Slack(url = SLACKURL_ex).notify(text = message)
ってところはなくても大丈夫です。
不測の事態が起きた時に通知されてるといいなー、と思ってslackに通知する処理を入れているだけなので、本プログラムの動作には関係ない部分です。
このコードを毎日15分ごとに実行した結果がさっき貼ったスプレッドシートの画像ですね。とりあえず全店舗について取得していますが、ある程度しぼっても良いかな、とも思います。
データ分析
分析、というほどすごいことはできないのですが(というか、スクレイピングできたところで結構満足してしまっています)、せっかくデータ取得したので、少し中身を見てみましょう。
Pythonコードを実行して作成したスプレッドシートのデータを使って、ある1週間について「御殿場インター店」の空き具合を曜日ごとにまとめたものが以下です。
これをグラフにしてみると、以下のようになります。
平日に比べて土日のほうが全体的な待ち時間が多いのが見て取れますね、これは感覚的にも正しい結果です。
また、日曜日は基本的にどの時間帯も混んでいますが、土曜日だったら16:00〜17:30ぐらいが少し空いていそうな感じですね。
とはいえ、今回はデータが7日間分しかないので、たまたまこの土曜日だけこの傾向となっているのかもしれません。
もっと長い期間で曜日ごとに平均を出したりすれば、より現実に近い傾向がつかめるのではないでしょうか。
最後に
今回はさわやかの待ち時間データを取得して分析するところまでやってみました。今回はさわやかの待ち時間というテーマでやりましたが、こんな感じで様々なデータを集めて分析してみるとおもしろいですね、アイデア次第でいろいろ応用がききそうです。
最後まで読んでくださり、ありがとうございました。