「病院のWEB予約するのに朝早くに起きて頑張ってみたけど、早い番号が取れない」 と妻が困っていました。
昔は病院に行って受付してから、病院内で延々待たされていました。それから整理券を使うところが増えて、あとどれくらい待ったら自分の番が回ってくるのかがわかるようになったので、待ち時間が予想できるようになりました。
現在は、事前にWEBで予約して、今何番の患者まで診てもらっているのかが家でわかるようになってきています。病院で待つということは、院内感染のリスクも上がるし、何より家にいるような気楽さがない。 そういう意味では、ものすごく便利になった。
一方で、別の問題が発生しています。それが上でも述べている「WEB予約競争」。 朝7時や8時から当日分の予約を開始するのだけど、みんなスマホやパソコンにかじりついて、スタートと同時に我こそ先にと、予約を開始する。
妻も頑張っているようですが、大体取れるのが30番目くらい。2時間待ちコース。
そこで、ふと最近勉強し始めたpythonでこれを解決できるんじゃないかと思い立ちました。 WEBでも同じように考えている人がいるかなと検索したが、ほとんどヒットしません。みんな困っていないのかな。
ともあれ、pythonでプログラムを組んでみようと思ったので、情報共有のため残しておきます。 (python習い始めて1年弱なので、効率的でなかったり変なコードだったりするかもしれません。一応、予約はちゃんとできたので参考にしてください)
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from selenium.webdriver.common.by import By
from datetime import datetime
import sched, time
import requests
def reserve_doctor():
driver.get('病院の予約URLを入れる')
time.sleep(3)
#「受付する」ボタンを押す
login_bottun = driver.find_element(By.CSS_SELECTOR,"セレクタ名を入れる")
login_bottun.click()
#「診察券番号」を入力する
user_input = driver.find_element(By.CSS_SELECTOR,"セレクタ名を入れる")
user_input.send_keys('診察券番号')
#「確定するボタン」を押す
login_bottun = driver.find_element(By.CSS_SELECTOR,"セレクタ名を入れる")
login_bottun.click()
#先にEdgeを立ち上げておく
service = Service(EdgeChromiumDriverManager().install())
driver = webdriver.Edge(service=service)
driver.implicitly_wait(100)
# 予約した時間にプログラム実行
scheduler = sched.scheduler(time.time, time.sleep)
target_time = time.strptime("23 Dec 01 07:00:00","%y %b %d %H:%M:%S" ) #2023年12月1日 7時に実行する
target_timestamp = time.mktime(target_time)
scheduler.enterabs(target_timestamp, 1, reserve_doctor, ())
scheduler.run()
#LINEに通知する(LINEに通知する必要のない人は、以下省略でOK)
def send_line_notify(notification_message):
line_notify_token = '自分のトークンを入れる'
line_notify_api = 'https://notify-api.line.me/api/notify'
headers = {'Authorization': f'Bearer {line_notify_token}'}
data = {'message': f' {notification_message}'}
requests.post(line_notify_api, headers = headers, data = data)
send_line_notify('予約完了しました')
まず最初にコードを紹介。上のコードで何をしているのか解説します。
使用したライブラリ
標準ライブラリ以外でインストールする必要性のあるものは、seleniumだけです。
以下のコマンドでインストールできます。
py –m pip install selenium
py –m pip install webdriver-manager
Seleniumは、Edgeなどのブラウザ操作ができるライブラリです。
標準ライブラリであるschedを使って、定刻になったら予約ができるようにしています。
scheduleを使ってみたのですが、他の操作(具体的には予約完了のLine通知)にうまく移れなかったので、今回はschedを使っています。予約が完了したらLineに通知がくるようにすれば、わかりやすいですね。
入力しなければいけない項目
上に掲載しているコードの中で、個別に入力しなければいけない項目があります。
病院の予約URLを入れる:ここに病院の予約ができるURLを記入してください。
セレクタ名を入れる:指定のボタンを押したり、数字や名前などを入力する際に、「どこの部分を操作するのか」?という情報を与えてあげなければいけません。それがセレクタ名です。詳しくは下で解説します。
診察券番号を入れる:ここは病院によって異なります。今回は診察券番号にしていますが、誕生日や名前だったりします。
実行する時間を入れる:上の例では2023年12月1日7時に実行するように書いていますが、病院の予約の時間に変えてください。
自分のトークンを入れる:これはLine通知したい場合のみ記入してください。どうやってトークンを入れるのかは別記事で解説しています。
ボタンを押す
病院のwebページに行くと、「午前中の診察」とか「受付する」、「予約」などのボタンがあります。手作業だと、マウスでクリックする必要がありますが、pythonではマウスでクリックできません。
そこで、
1.ボタンのセレクタを調べる
2.ボタンを押す
ということをしなければいけません。
ボタンのセレクタ名を調べたあと、driver.find_elementで、押したいボタンの定義をします。
そのあと、.click()で、そのボタンを押すことができます。
#「受付する」ボタンを押す
login_bottun = driver.find_element(By.CSS_SELECTOR,"セレクタ名を入れる")
login_bottun.click()
セルに診察券番号などを入力したい
ボタンを押したあとには、「診察券番号」だったり「生年月日」、「氏名」などを入力してログインする必要があります。
この時、「診察券番号」などを入力するために、.send_keys( )を用います。
1. 入力したいセルのセレクタ名を調べる
2. セルに文字などを入力する。
#「診察券番号」を入力する
user_input = driver.find_element(By.CSS_SELECTOR,"セレクタ名を入れる")
user_input.send_keys('診察券番号など')
セレクタ名の調べ方
今回使ったブラウザはEdgeですが、Chromeなど他のブラウザでも調べることができます。
1.病院のWEBページで、右クリックを押すと「開発者ツールで調査する」を選びます。
2.対象となるボタンやボックスのセレクタ名を調べる
画面が切り替わると、下の図の赤い矢印の先にある「ページ上の検索対象となる要素の選択」ボタンを押します。
これを押してから、押したいボタンや、入力したいボックスにカーソルを合わせると対応するコードに色が付きます。
その後、自分が調べたい場所。たとえば、文字を入力するボックスなどを選択します。すると、該当するコードの部分に色が付きます。
そこで、右クリックを押して「コピー」→「selectorをコピー」を選びます。これで、対象となるセレクタを知ることができたので、これを貼ります。
予定時刻になったら、プログラムを作動させる
標準ライブラリのschedを使います。下のコードで、年月日のところを変更すればいいです。日にちや時間は一桁でもコード上では01とか02とか0をつけないといけないので注意してください。
あと、さりげに大事なのが先にEdgeを立ち上げておくということです。秒単位で、予約が埋まっていくのですが、schedで時間になったらプログラムを動かしてもEdgeが起動するのに数秒を要してしまうので、負けてしまうからです。
#先にEdgeを立ち上げておく
service = Service(EdgeChromiumDriverManager().install())
driver = webdriver.Edge(service=service)
driver.implicitly_wait(100)
# 予約した時間にプログラム実行
scheduler = sched.scheduler(time.time, time.sleep)
target_time = time.strptime("23 Dec 01 07:00:00","%y %b %d %H:%M:%S" ) #2023年12月1日 7時に実行する
target_timestamp = time.mktime(target_time)
scheduler.enterabs(target_timestamp, 1, reserve_doctor, ())
scheduler.run()
実行結果
これまでは、毎回朝7時に起きて、WEB予約競争をしていましたが、今回のコードを実行した結果、寝ながらにして予約することができるようになりました。
妻もニッコリです。すごく感謝されました。 ネット環境にもよると思いますが、私の場合はコード実行完了までに2秒程度でした。もっと早く実行できるコードがあるよ!という人はぜひ教えてください。python仲間募集中です!