教習所の技能教習予約が24時間見張ってないと空きを見つけられず、システムを自動化すべくpythonを勉強中のよっしーです。
タイトルの書籍の演習11.10.1で出てきたコマンドライン電子メーラーを作ったので、整理してみました。
今回はExciteメールを利用したのですが、理由としてはGmailやyahooだと何らかの多段階認証になっていたので、idとパスワードだけで簡単にログインできるのがExciteメールだったからです。
#環境
- python 3.6.0
- PyCharm 2017.1
- MacbookAir sierra 10.12.5
- Safariは「リモートオートメーションを許可」をオン
#方針
- コマンドラインから、メールアドレスとテキストを受け取る
- seleniumでExciteメールにログインする
- メールを新規作成し、引数として受け取ったメールアドレス宛にテキストを送る
#プログラムの方針
- sysモジュールを使い、sys.argv[1]にメールアドレス sys.argv[2]にテキストを受け取る。
- seleniumモジュールのwebdriverで、Exciteメールのログインページを開き、sendKeysでユーザー名とパスワードを送信し、submit()でログイン
- 新規作成のリンクからメール送信画面を開き、引数で受け取ったメールアドレスとテキストを入力しsubmit()する
#実装
CommandlineMailer.py
#! python 3.6.0
# commnadlineMailer.py - コマンドラインで受け取ったメールアドレス宛に文章を送る
# Usage:
# commnadlinMailder.py <some@excite.co.jp> <sometext> - 第一引数でメールアドレス, 第二引数でテキストを受け取る
import sys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
if len(sys.argv) > 2:
email_adress = str(sys.argv[1])
main_text = str(sys.argv[2])
# Exciteメールを開いてログインする
browser = webdriver.Safari()
browser.get('https://ssl2.excite.co.jp/idc/login/?si=mail&ru=http%3A%2F%2Femail.excite.co.jp')
# idタグがなかったのでnameタグを利用した
email_elem = browser.find_element_by_name('loginid')
email_elem.send_keys('yourMailAdress@excite.co.jp')
password_elem = browser.find_element_by_id('id-password')
password_elem.send_keys('yourPassword')
password_elem.submit()
# ページの表示待ちをしてから、新規作成画面を開く
link_elem = WebDriverWait(browser, 10).until(
EC.element_to_be_clickable((By.LINK_TEXT, '新規作成'))
)
link_elem.click()
# ページの表示待ちをしてから、メアドと本文を入力して送信
to_elem = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.ID, 'to'))
)
to_elem.send_keys(email_adress)
main_text_elem = browser.find_element_by_id('body')
main_text_elem.send_keys(main_text)
send_elem = browser.find_element_by_id('_sendmail')
send_elem.submit()
else:
print('引数が少ないです')
引っかかった点
最初、表示待ちをせずに実装をしていてエラーがバンバン出て「?」て感じでしたが、未表示の時点でアクセスをするとエラーが出ることに気がつきました。
WebDriverWaitを使って「特定の要素が現れるまで ≒ 更新成功まで」の停止処理をするのがポイントでした。WebDriverWait(browser, 10)で指定した10秒以内に更新できなかったら、タイムアウトのエラーが帰ってきます。
手を抜いた点
演習でしか使わないので正規表現でメールアドレスかどうか確かめたり、引数が逆だった時の処理などは省きました。