【python】メンドクサイを自動にさせてみた２【seleniumで自動登録】

#解析したメールをseleniumで処理
[前回](https://qiita.com/ouranosu/items/ecdb9cce5fd8eac26b42)の記事で届いたメールから特定のメールを一時的にデスクトップのmailcheck.txtに出力させる方法を書きました。

次はこのmailcheck.txtの中身を使ってseleniumに自動で記入してもらいます。
ひとまず全体を載せます。

```python:mail.py

#selenium処理
def def_selenium():
    with open(UserPath,'r') as rf:
      read_text = rf.readlines()
      find_str1 = "特定文字１"
      find_str2 = "特定文字２"
      if find_str1 in read_text == True:
        return
      elif find_str2 in read_text == True:
        return

      read_text_strip = [line.strip() for line in read_text]
      l_XXX_both = [(i, read_text) for i, read_text in enumerate(read_text_strip) if '項目１' in read_text]
      i1 = l_XXX_both[0]
      l_XXX_both = [(i, read_text) for i, read_text in enumerate(read_text_strip) if '項目２' in read_text]

      Koumoku_Day = read_text[i1[0]] #項目１
      Koumoku_Name = read_text[i2[0]] #項目２
      

    #フォーマット処理
    pKoumoku_Day = datetime.strptime(Koumoku_Day, '%Y年%m月%d日')
    fKoumoku_Day = datetime.strftime(pKoumoku_Day, '%Y/%m/%d')
    fKoumoku_Name = Koumoku_Name.split(':')[1]
    
    #ネットに接続
    driver = webdriver.Chrome("C:/driver/chromedriver.exe")
    time.sleep(1)
    driver.get("予約管理のログインURL")
    time.sleep(4)
    #ログイン
    elem_search_word = driver.find_element_by_id("uid")
    elem_search_word.send_keys("ユーザーネーム")
    elem_search_word = driver.find_element_by_id("passwd")
    elem_search_word.send_keys("パスワード")
    elem_search_btn = driver.find_element_by_css_selector(".login-button")
    elem_search_btn.click()
    time.sleep(3)
    #予約管理ページに移行
    driver.get("予約管理のURL")
    time.sleep(3)

    #日付をKoumoku_Dayの日に
    elem_search_word = driver.find_element_by_id("currentDate")
    elem_search_word.clear()
    elem_search_word.send_keys(fKoumoku_Day)
    time.sleep(3)

    #ラジオボタンの選択
    elem_search = driver.find_element_by_id("equip_radio_9")
    driver.execute_script("arguments[0].click();", elem_search) #ラジオボタンを選択するためのJS
    time.sleep(3)

    #上から順に空欄を見つけるを押下
    elem_search_tr = driver.find_elements_by_xpath( "//div[@class='ui-selectee']" )
    for i in range(0,100,2):
        text_elem = elem_search_tr[i].text
        if text_elem.find("×") == -1:
            #空きを発見したので、ループを抜けて入力処理
            elem_search_tr[i].click()
            break
        else:
            continue

    time.sleep(3)
    driver.find_element_by_link_text(u"ページ２").click()
    time.sleep(3)

    #氏名
    elem_search_word = driver.find_element_by_id("client_name")
    elem_search_word.send_keys(fKoumoku_Name)
    time.sleep(3)
    
    #登録ボタン
    elem_search_btn = driver.find_element_by_id("submit")
    elem_search_btn.click()
    time.sleep(3)

    Alert(driver).accept()
    time.sleep(3)

    driver.quit()
```

seleniumに関してはもっと詳しくわかりやすい記事がいくらでもあるので、使った技術をピックアップしていきます。

```python:mail.py

#selenium処理
def def_selenium():
    with open(UserPath,'r') as rf:
      read_text = rf.readlines()
      find_str1 = "特定文字１"
      find_str2 = "特定文字２"
      if find_str1 in read_text == True:
        return
      elif find_str2 in read_text == True:
        return
```
最初にデスクトップに作成したファイルを読み取ります。
readlines()で一行ずつ区切って格納できます。
文章がきれいに並んでいてくれるおかげで、こうすることで文字の切り取りがやりやすくなりました。
特定の文字が含まれていた場合、処理を行わずに次のメールを見に行きます。

```python:mail.py

      read_text_strip = [line.strip() for line in read_text]
      l_XXX_both = [(i, read_text) for i, read_text in enumerate(read_text_strip) if '項目１' in read_text]
      i1 = l_XXX_both[0]
      l_XXX_both = [(i, read_text) for i, read_text in enumerate(read_text_strip) if '項目２' in read_text]

      Koumoku_Day = read_text[i1[0]] #項目１
      Koumoku_Name = read_text[i2[0]] #項目２
      
    #フォーマット処理
    pKoumoku_Day = datetime.strptime(Koumoku_Day, '%Y年%m月%d日')
    fKoumoku_Day = datetime.strftime(pKoumoku_Day, '%Y/%m/%d')
    fKoumoku_Name = Koumoku_Name.split(':')[1]
```

最初の一文でread_text_stripにリスト形式でテキストを格納します。
.strip()は、文字列型のメソッドで特定の文字列や空白文字を削除するためのメソッドです。
それからさらに「項目１」という文字を検索し、ヒットした行をl_XXX_bothに入れています。
こうすることで、文章の変更などにより、メール文の長さが変わってしまっても、定型部分は拾えるとしたわけです。

フォーマット処理で自分の扱いたい日付の形に変更しました。

```python:mail.py

    #ネットに接続
    driver = webdriver.Chrome("C:/driver/chromedriver.exe")
    time.sleep(1)
    driver.get("予約管理のログインURL")
    time.sleep(4)
    #ログイン
    elem_search_word = driver.find_element_by_id("uid")
    elem_search_word.send_keys("ユーザーネーム")
    elem_search_word = driver.find_element_by_id("passwd")
    elem_search_word.send_keys("パスワード")
    elem_search_btn = driver.find_element_by_css_selector(".login-button")
    elem_search_btn.click()
    time.sleep(3)
    #予約管理ページに移行
    driver.get("予約管理のURL")
    time.sleep(3)
```
やっとseleniumの出番です。seleniumがchromeのWEBドライバーという自動処理専用のソフトを起動します。
chromedriverは検索すればすぐ出てきます。

getで行きたいURLのページに飛びます。
ちょくちょくtime.sleepを挟むのは、処理が早すぎるとうまく動作しないためです。
sleepの時間は自分のPCのスペックや回線の速さを見て調整するといいです。

find_element_by_〇〇でそのページの必要な要素をターゲットします。
この要素を上手く見つけられるかがselenium成功の鍵と言って過言ではないと思っています。
idなのか、css_selectorなのか、xpathなのか、自分のやりやすい方法を探すのがいいです。
個人的にはidから探し、うまくいかなければxpathを使うようにしてます。
css_selectorも便利なんですけど、なぜか好きになれません。

elem_search_btn.click()のようにボタンの要素を見つければクリックもできます。

```python:mail.py

#ラジオボタンの選択
    elem_search = driver.find_element_by_id("equip_radio_9")
    driver.execute_script("arguments[0].click();", elem_search) #ラジオボタンを選択するためのJS
    time.sleep(3)
```

ラジオボタンには少し苦労しました。
終わってみればなんてことはない、javascriptでクリックするだけなんですが、JSに疎い私はなんとかfind_elementで済ませようとしました。
ですがどーにもうまくいきません。
要素だけ探して、JSでのクリックが一番いいとたどり着きました。
driver.execute_scriptは今後もお世話になる技術として覚えておきました。

```
 #上から順に空欄を見つけるを押下
    elem_search_tr = driver.find_elements_by_xpath( "//div[@class='ui-selectee']" )
    for i in range(0,100,2):
        text_elem = elem_search_tr[i].text
        if text_elem.find("×") == -1:
            #空きを発見したので、ループを抜けて入力処理
            elem_search_tr[i].click()
            break
        else:
            continue
```
この予約管理のシステムはエクセルを思い描いていただくとわかりやすいのですが、
予約が埋まっていると「ｘ」が記入されているため、find("x")で-1以外の数値が返ってきます。
-1が返ってくるとそこは空白とわかるので、空白を見つけたらクリックしてループを抜けます。

```

    Alert(driver).accept()
    time.sleep(3)

```
画面に出てくる確認のポップアップをaccept()でOKします。
これで一通りの処理を終了し、再度メールに特定のアドレスがないかを確認します。


#まとめ
文章に起こしてみるとそんなに難しいことはしてませんが、あれやこれや探しながらエラーに一つずつ対応してとしてるとまぁまぁ時間がかかりました。
でも実際に思ったように動いた時の達成感、やったった感は何とも言えないですね。
この記事が初学者の方、うまく動かなくて困ってる方の力に少しでもなれれば幸いです。

ここまでご覧いただきまして、ありがとうございました。