最近、Rで解析の学習をする中で、自分のメールからスパムメールを抜き出して、形態素解析をしてみようと思いました。
経緯としては、書籍のサンプルデータじゃなくて、リアルを追求したかったからですね。
あとサンプルデータは英語のものが多くて、いまいち実感が湧きません。
しかし、いざメールを解析できる形で用意しようと思ったところ、思わぬ壁が……
メールクライアントはmbox形式など保存されているため、テキストそのままで保存されているわけではありませんでした……
というわけ、ちょっと前置きが長くなりましたが、imaplibを使用して、Gmailから設定した条件に応じたメールのタイトルと本文をテキストで抽出するスクリプトを作っていきます。
##設定した環境
Windows10
Python 3.6.3
##準備
###imaplibはインストール不要
imaplibの詳しい説明
https://docs.python.jp/3/library/imaplib.html
標準ライブラリとのことで、pipしてインストールは不要でした。
###Gmailの設定をする
Gmailで2段階認証をしていない場合に、imaplib経由でアクセスを試みると“安全性の低いアプリからのアクセス”と見なされて、エラーが表示されることがあります。
自分のアカウント2つで試してみたところ、片方は2段階認証無しで、通常のID、パスワードで普通にアクセスできましたが、もう一つは2段階認証した上で、安全性の低いアプリからのアクセスの許可とアプリケーション用の専用パスワードの発行が必要でした。
細かい条件は分かりませんが、セキュリティ関連のエラー表示されたら、下記ヘルプページを参考に設定してみましょう
https://support.google.com/mail/accounts/answer/78754
https://support.google.com/accounts/answer/6010255
##メールアカウントへのアクセス
自分のメールアカウントのユーザー名とパスワードを指定します。
欲しいメールのラベルや送信者、宛先などをgmail.search()内で条件設定します。
今回は、シンプルにALLを使いましたが、
未読のみを取り出したいときは、UNSEENを使います。
その他、送り主のFROMなどもあります。
import imaplib
import email
UserName = "(自分のメールアドレス)"
PassName = "(自分のパスワード[もしくは、アプリケーション専用パスワード])"
gmail = imaplib.IMAP4_SSL("imap.gmail.com", '993')
gmail.login(UserName, PassName)
gmail.select("(読み込みたいメールのラベルを指定する。空なら全て。)")
# ALLでSearchすると指定したラベルの全てのメールを読み込む
head, data = gmail.search(None, 'ALL')
##読み込んだメールのタイトルと本文を表示
ひとつのメールには、宛名やタイトル、本文、エンコード、送り主、送信時間など様々な情報が格納されています。
以下は、そこから欲しい情報を取得するための作業です。
タイトルの取得は少々手間ですが、本文は比較的短いコードで取れます。
ちなみに、メールは複数取れる想定なので、for文で取得したメール分だけ繰り返しタイトルと本文を出力しています。
# ------上のコードからの続き------
# 取得したメール一覧の処理
for num in data[0].split():
h, d = gmail.fetch(num, '(RFC822)')
raw_email = d[0][1]
# 文字コード取得
msg = email.message_from_string(raw_email.decode('utf-8'))
msg_encoding = email.header.decode_header(msg.get('Subject'))[0][1] or 'iso-2022-jp'
# タイトルの情報を抽出
msg_subject = email.header.decode_header(msg.get('Subject'))[0][0]
# エンコーディング
subject = str(msg_subject.decode(msg_encoding))
print(subject)
# 本文の抽出
body = msg.get_payload()
print(body)
# 終了処理
gmail.close()
gmail.logout()
print("メール読み込み完了")
これで、メールの情報をテキストで抽出することができました。
自分はこの後は、CSVに書き出しとかやってみました。