【python】メンドクサイを自動にさせてみた１【メール解析】

#この記事について

python使って自分で儲けれるようになりたい！
と思いながらも儲けにつなげるまでいけないヘボプログラマが仕事上のメンドクサイをpythonで解決（主に自分の為）したことのメモ

アウトプットが必要ってどっかの誰かが言ってたから自分もとりあえずやってみます。
物凄い自己流なのでスパゲティコードかもしれません。
そんな時は暖かい眼差しでご指導、ご指摘いただければ心より感謝させていただきます。

##メールで届く予約がメンドクサイ
業種的に予約のメールが届きます。
これを自社の予約管理に入力する必要があるのですが、とにかくメンドクサイ！

「pythonでメール解析できたら後はseleniumで何とかできるのになぁ」
と思い立ったので、pythonのメール解析を勉強しました。

#mailbox?imapclient?ssl?
難しい名前は覚えられない質でして、クライアントどうのこうの、暗号どうのこうのよくわからないところから始まります。
最初はサンダーバードのメールボックスを解析しようとしました。
mailboxを使ってみて、サンダーバードのローカルフォルダに保存されたメールで処理を開始。
（そのコードは消してしまいました・・・）

ただなぜか受信順が変だったり、消したはずのものが残っていたり、望んだ処理ができませんでした。

そこで見方を変え、サーバーのメールが直接解析できればいいのにと思い至ったのです。（これが普通？）

ちゃちゃっと以下にコードを載せます。

```python:mail.py
import os
import email
import ssl
import imaplib
from email.header import decode_header, make_header
from imapclient import IMAPClient

#メール処理
"""
IMAP4サーバにログインする
"""
host = "サーバー名(mail.yahoo.com的なやつ)"
username = "sample@sample.com(メールアドレス)"
password = "passwd(パスワード)"
server = imaplib.IMAP4_SSL(host)
server.login(username, password)

"""
メール受信
"""
select_info = server.select('INBOX')
typ, data = server.search(None, 'FROM', 'xxx@aaaa.com')

msg_list = [] 
for num in data[0].split():
    typ, data = server.fetch(num, '(RFC822)')
    msg = email.message_from_bytes(data[0][1])
    msg_encoding = 'iso-2022-jp'

    if msg.is_multipart() == False: #シングルパート
        byt = bytearray(msg.get_payload(), msg_encoding, 'ignore')
        body = byt.decode(encoding=msg_encoding)
    else: #マルチパート
        prt = msg.get_payload()[0]
        byt = prt.get_payload(decode=True)
        body = byt.decode(encoding=msg_encoding)

    #ユーザーパス
    UserPath = os.path.join(os.path.expanduser('~'),"Desktop\\mailcheck.txt")
    with open(UserPath,'w') as wf:
        wf.write(body)
```
@takey様の[こちら](https://qiita.com/takey/items/1498af9e1113eeb7bb21)の記事や
@ekzemplaro様の[こちら](https://qiita.com/ekzemplaro/items/a35e15865d57372f1d2b)の記事を参考にさせていただきました。本当にありがとうございます。

自分も細かく説明してある記事には助けられているので、習って細かく説明したいと思います。

```python:mail.py
メール処理
"""
IMAP4サーバにログインする
"""
host = "サーバー(mail.yahoo.com的なやつ)"
username = "sample@sample.com(メールアドレス)"
password = "passwd(パスワード)"
server = imaplib.IMAP4_SSL(host)
server.login(username, password)
```

なんとこれだけでメールサーバーにログインできます。
びっくりするぐらい簡単でした。
hostなんかはメーラーのアカウント設定とかで確認できます。
（例：サンダーバードの場合、【アカウントの設定をする】→【サーバ設定】内のサーバ名）

```python:mail.py
"""
メール受信（MIMEメッセージを受信）
"""
select_info = server.select('INBOX')
typ, data = server.search(None, 'FROM', 'xxx@aaaa.com')
```
selectでINBOX内のメールを取得します。
INBOXの名前を変えると好きなフォルダを選べるようです。（INBOXがデフォルト）
searchの前にtyp,dataとあるのは、searchを行って値を取得できると、["OK","〇〇"]のような感じで値が返ってくるので、typに"OK"部分を入れて分けたいからですね。
typを使って条件文も書けそうです。
searchの第二引数がFROMになっているのは、そのあとにメールアドレスを記入して、特定のメールだけを取得したいからです。

```python:mail.py
msg_list = [] 
for num in data[0].split():
    typ, data = server.fetch(num, '(RFC822)')
    msg = email.message_from_bytes(data[0][1])
    msg_encoding = 'iso-2022-jp'

    if msg.is_multipart() == False: #シングルパート
        byt = bytearray(msg.get_payload(), msg_encoding, 'ignore')
        body = byt.decode(encoding=msg_encoding)
    else: #マルチパート
        prt = msg.get_payload()[0]
        byt = prt.get_payload(decode=True)
        body = byt.decode(encoding=msg_encoding)
    #ユーザーパス
    UserPath = os.path.join(os.path.expanduser('~'),"Desktop\\mailcheck.txt")
    with open(UserPath,'w') as wf:
        wf.write(body)
    def_selenium()
```

ごめんなさい。ここは僕の中でただのおまじないと処理されました。
シングルパート、マルチパートの詳しい方わかりやすく教えてください。
とりあえず数字の羅列で得たメール本文をencodingで人にわかる文章に変えてます。

ユーザーパス以下は後々メールの文章を切り取りたいために、一度デスクトップのmailcheckというテキストファイルを作って出力しています。
送られてくる定型文を簡単に加工するための処理ですので、読み込むだけの人には不要な処理かもしれません。
最後のdef_selenium()でseleniumの処理にループで飛ばせるようにしてます。

メール部分の処理は以上です。
これでサーバーの受信フォルダ（INBOX）にある特定のメールアドレスから送られてくるメールを取り出すことができました。
これからpythonでメール処理をしたい方の手助けになれば幸いです。

次回は得られたメール文からseleniumを使った処理を書いてみようと思います。

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