平日,休日問わず子供の通院時に困った事がある.かかりつけの病院のWeb予約は競争率が高く,予約開始時間に1分でも遅れてしまうと受付が終了してしまう.平日も午前中に休みを取って行かざるを得ない場合もあるのだが,予約を確実に取れる確証がない.
この不安が少しストレスとなっている.そこで今回は病院予約を確実に勝ち取るためにGo×agoutiでWeb予約受付を自動化していく.
実現したいこと
以下のオペレーションを病院予約当日の08:00に処理する.
- 病院のWeb予約受付サイトを開く
- 自身のアカウントでログインを行う
- 予約受付確認を行う
- 予約登録を行う
実際に動作させたプログラムはこちらにあげている.
環境
以下環境で動作を確認した.
Name | version |
---|---|
macOS Mojave | 10.14.6 |
GoogleChrome | 79.0.3945.79 |
ChromeDriver | 79.0.3945.36 |
Go | 1.12.9 |
導入準備
ChromeDriverのインストール
macなのでbrew install
でchromedriverをインストールする.
❯❯❯ brew install chromedriver
agoutiをインストール
go get
でagoutiをインストールする.
❯❯❯ go get github.com/sclevine/agouti
処理の流れ
エラー時については割愛するが,プログラム全体の流れは以下とした.
init
関数を実行waiting
ファイルを確認し,処理継続可否の判断config
ファイルを読み込みScrapingList
へconfig
ファイルの値を設定img
ファイルの削除- Google Chromeをヘッドレスモードで起動
- 予約受付サイトへ遷移
- スクリーンショットを取得
- 予約受付リンクをクリックし、ログイン画面へ遷移
- ログイン情報の入力
- スクリーンショットを取得
- ログインの実行
- スクリーンショットを取得
- 予約受付確認を実行
- スクリーンショットを取得
- 予約受付登録を実行
- スクリーンショットを取得する
- アクティブなウインドウを閉じる
waiting
ファイルの削除- Google Chromeを終了する
実装
今回,agoutiで使用した機能を以下に抜粋する.
WebDriver
Webブラウザを操作するためプロセスを制御する.
ChromeDriver
Google ChromeのWebブラウザ操作を制御する.ここではヘッドレスとしてブラウザを非表示で起動を行う.オプションを付けずにdriver := agouti.ChromeDriver()
とすることでブラウザの表示が行われる.
driver := agouti.ChromeDriver( agouti.ChromeOptions( "args", []string{ "--headless", }), )
Start
WebDriverプロセスを開始するために必要となる.
Stop
WebDriverプロセスを停止するために必要となる.main
関数の最後でプロセスを停止したいのでdefer
で処理を行う.
NewPage
WebDriverに対応したPage
のレシーバが返ってくる.ここではGoogle Chromeが対象,以降のPage
機能を使用するために必要となる.
target, err := driver.NewPage()
Page
Page
は開いているブラウザのセッションを指す.前提条件として以下のように指定したWebDriverとそれに対応するセッションを作成する事が必要となる.
driver := agouti.ChromeDriver() target, err := driver.NewPage()
Navigate
URLを渡して画面遷移を行う.
target.Navigate("targetUrl")
CloseWindow
アクティブなウィンドウを閉じる.
target.CloseWindow()
Screenshot
現在開いているページのスクリーンショットを指定したファイル名で保存する.相対パス,もしくは絶対パスで指定する.
target.Screenshot("filePath")
Selection
要素の取得,選択や実行を行う.
FindByLink
引数に指定したアンカー要素のテキストを検索する.
target.FindByLink("今すぐ受付")
Fill
要素を検索し,引数に指定したテキストで埋める.
target.FindByID("user_email").Fill("your mailadress")
Click
要素を検索し,クリックを行う.
target.FindById("sample").Click()
Submit
指定した要素を検索し,フォーム値を送信する.
target.FindByName("commit").Submit()
cronを設定する
macへcron
の設定を行っていく.実行結果を自分宛にメールで送信,毎日08:00の起動とするようcrontab -e
で編集を行う.
※ここではcrontab -e
としているが,このコマンドはe
の隣にあるキーがr
なのでオプションに-r
で大惨事となる可能性があるので,普段からこのオプションに慣れないよう注意して欲しい.
MAILTO = "example@example.com" 0 8 * * * cd /your project path}; bash -l -c 'go run /your project path/main.go'
実行結果
12月21日(土)に実行した結果は以下となった.これはアクセス先のシステムから送信されてきたメール内容を抜粋している.
日付:2019/12/21 8:00 ◇ 受付完了のお知らせ ・診察日:2019年12月21日 ・時間 :午前診察 ・受付No:31
受付Noがニ桁だった事に驚きではあるが,予約受付が無事完了していることが確認出来た.これでストレスは抱えずともかかりつけの病院予約がスムーズに行える.
また,どのような動作となるかヘッドレスオプションを外し,掲載可能範囲の画面を以下に記す.ここではログインを失敗させているが,実際はログイン以降の処理も問題なく行われている事は確認済みだ.
課題
Web予約受付を自動化する.と題しプログラムを作成したが,蓋を開けると完全な自動化とは言い難い点があったため,下表に内容をまとめた.
# | 詳細 |
---|---|
1 | macがスリープ状態だとcron が起動しないため,サーバー配置が必要. |
3 | waiting ファイルを手動で作成する運用になっているため,スマートフォンからwaiting ファイルを作成するように改善する. |
4 | スクリーンショットを取得しているものの,現状だと息をしていない. |
5 | 予約受付順にムラがある. |
まとめ
課題はあるものの,Web予約受付を自動操作することで確実な予約が可能となった.前日にwatingファイルを仕込んでいく事で当日の不安も解消され,いつもより惰眠も貪る事が出来る.これは良いことづくしと言える.他の展開としては,ブログに書いた内容を連携対象外のWebアプリに書き込んだり,手動のテストも自動化が出来るだろう.実装するにあたって特段難しい事はなかったので,今後も自動化出来る事は積極的に取り組む.