#はじめに
今回の目標は最新の時間割を大学のポータルサイトからスクレイピングしてLINEnotifyで通知を受け取れるようにすることです。
動機は先日、大学の授業変更に気付けず1コマ分の出席を無駄にしてしまった(せっかく早起きしたのに...)からです。
#準備
準備として、大学のポータルサイトへの自動ログインを以下のコードで書きました。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless')
webdriver = webdriver.Chrome(options=options)
webdriver.get("<ポータルサイトのURL>")
#Xpathで指定
webdriver.find_element_by_xpath('//*[@id="userId"]').send_keys("USERID")
webdriver.find_element_by_xpath('//*[@id="password"]').send_keys("PASSWORD")
#クリックするボタン
webdriver.find_element_by_css_selector("#loginButton").click()
optionでheadlessを付けることでブラウザが立ち上がらなくなるので便利です。
他のサイトの場合はwebdriver.get
とwebdriver.find_element_by_〇〇
の中身をサイトの形式に合わせて変えると動くと思います。
##スクレイピング
週末は時間割がなく、空欄が返ってくるのでif文で簡単な関数を作っておきました。
#週末は空欄になってしまうので...
def check (subjects):
x=[]
for subject in subjects:
x.append(subject.text)
if x == ['']:
return '''""""""""""""
授業はありません♪
"""""""""""" '''
else:
for subject in subjects:
x=subject.text
return '''""""""""""""
%s
"""""""""""" ''' % x
try:
today_list = webdriver.find_elements_by_xpath('//*[@id="weekly"]/tbody/tr[3]/td[2]')
tomorrow_list = webdriver.find_elements_by_xpath('//*[@id="weekly"]/tbody/tr[3]/td[3]')
msg='''
今日の時間割
%s
明日の時間割
%s'''%(check(today_list),check(tomorrow_list))
print(msg)
finally:
webdriver.quit()
ここでmsgの中身を確認しておくと、
print(msg)
>>今日の時間割
""""""""""""
1時限
基幹物理学ⅠB
2時限
中国語Ⅱ
3時限
課題協学科目
4時限
課題協学科目
""""""""""""
明日の時間割
""""""""""""
3時限
情報科学
""""""""""""
いい感じにスクレイピング出来ました。
#LINE Notifyで通知
(https://notify-bot.line.me/ja/ )にアクセスしログイン後、マイページにてトークンを発行します。この際、モバイルからだとトークン発行画面が表示されなかったのでpcからアクセスすると表示されるはずです。以下のコードは「Pythonでスクレイピングした情報をLINE Notifyを使って通知する」を参考にさせて頂きました。
import urllib.request
import sys
LINE_TOKEN = "<取得したTOKEN>"
LINE_NOTIFY_URL = "https://notify-api.line.me/api/notify"
def class_info(msg):
method = "POST"
headers = {"Authorization": "Bearer %s" % LINE_TOKEN}
payload = {"message": msg}
try:
payload = urllib.parse.urlencode(payload).encode("utf-8")
req = urllib.request.Request(
url=LINE_NOTIFY_URL, data=payload, method=method, headers=headers)
urllib.request.urlopen(req)
except Exception as e:
print ("Exception Error: ", e)
sys.exit(1)
def main():
class_info(msg)
#最終的なコード
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import urllib.request
import sys
options = Options()
options.add_argument('--headless')
webdriver = webdriver.Chrome(options=options)
webdriver.get("<URL>")
#Xpathで指定
webdriver.find_element_by_xpath('//*[@id="userId"]').send_keys("USERID")
webdriver.find_element_by_xpath('//*[@id="password"]').send_keys("PASSWORD")
#クリックするボタン
webdriver.find_element_by_css_selector("#loginButton").click()
#週末は空欄になってしまうので...
def check (subjects):
x=[]
for subject in subjects:
x.append(subject.text)
if x == ['']:
return '''""""""""""""
授業はありません♪
"""""""""""" '''
else:
for subject in subjects:
x=subject.text
return '''""""""""""""
%s
"""""""""""" ''' % x
try:
today_list = webdriver.find_elements_by_xpath('//*[@id="weekly"]/tbody/tr[3]/td[2]')
tomorrow_list = webdriver.find_elements_by_xpath('//*[@id="weekly"]/tbody/tr[3]/td[3]')
msg='''
今日の時間割
%s
明日の時間割
%s'''%(check(today_list),check(tomorrow_list))
print(msg)
finally:
webdriver.quit()
LINE_TOKEN = "<TOKEN>"
LINE_NOTIFY_URL = "https://notify-api.line.me/api/notify"
def class_info(msg):
method = "POST"
headers = {"Authorization": "Bearer %s" % LINE_TOKEN}
payload = {"message": msg}
try:
payload = urllib.parse.urlencode(payload).encode("utf-8")
req = urllib.request.Request(
url=LINE_NOTIFY_URL, data=payload, method=method, headers=headers)
urllib.request.urlopen(req)
except Exception as e:
print ("Exception Error: ", e)
sys.exit(1)
def main():
class_info(msg)
if __name__ == '__main__':
main()
そして以下のように問題なく通知がきました。
#おまけ
pythonファイルを手動で実行するのはめんどくさいので、今回は簡単なバッチファイルを作り、windowsのタスクスケジューラで自動実行させようと思います。
##バッチファイル作成
cd \
cd C:\Users\ユーザー名\〇〇〇 (←実行するpythonファイルの階層まで移動)
call C:\\Users\\ユーザー名\\Anaconda3\\Scripts\\activate.bat
python class_notify.py
(cd \
をせずに階層まで移動しようとするとエラーが出たため、いったんcd \
を付けています。)
anacondaの環境で実行したいので(anaconda promptで実行!的なことが出来ます。)call
でactivate.bat
の場所を書いています。activate.bat
の場所が違う場合があるので確認して記述します。
##タスクスケジューラ
windowsのスタートメニューの検索欄からタスクスケジューラを検索し、起動します。
タスクの作成
を選択し、操作のタブから新しい操作を選択し、参照から、作成したバッチファイルを選択します。後は名前とトリガーを記述するだけで完了です。
自分はpcをスリープからログインした際に実行されるように、トリガーのタスクの開始を「ワークステーションアンロック時」に設定しました。
詳しくはこちらを参考にしてください。
#おわりに
pythonのコードを書くところまでは順調だったのですが、意外にも、タスクスケジューラの使い方で結構詰まりました。
スクレイピングしたり何かしらのAPI使うことは楽しいので、これからも気が向けばやってみようと思いました。
#参考にした記事
Pythonでスクレイピングした情報をLINE Notifyを使って通知する
Python3 文字列中に変数展開したい
XPathのまとめ、要素の参照方法いろいろ
初心者でもわかるWindowsタスクスケジューラの使い方
タスクスケジューラ:トリガー