(v_07)Python メールの受信 popLib
popLib
Pythonでいろいろ試してみたことを記載しています。※開発環境はThonnyを使用しています。
popLibモジュールを使ってメールの受信を試しました。
popLibモジュールはクラス POP3(POP:Post Office Protocol)を定義しているそうです。イメージ的にはメーラーを使ってメールサーバーからメールをダウンロードするような感じです。
class poplib
以下で初期化します。
class poplib.POP3(host, port=POP3_PORT[, timeout])
port が省略されると、POP3標準のポート(110)が使われます。
class poplib.POP3_SSL(host, port=POP3_SSL_PORT, *, timeout=None, context=None)
port が指定されていない場合、 POP3-over-SSL 標準の 995 番ポートが使われます。
自分が使っている受信メールサーバー名、ポート番号に合わして初期化します。
※udat[0]は受信メールサーバー名 (例:’pop.***.ne.jp’)
M=poplib.POP3(udat[0], port=110, timeout=10) #port=110
M=poplib.POP3_SSL(udat[0], port=995, timeout=10) #port=995 SSL
私の場合は、現在のメーラーの設定を参照してpoplib.POP3_SSLを使いました。
ちなみに、poplib.POP3でも動作確認すると問題なさそうな感じでした。
使い方
初期化からログイン、ログオフを確認してみます。※ThonnyのShellで動作確認しています。
>>> M=poplib.POP3_SSL(udat[0], port=995, timeout=10)
>>> M
<poplib.POP3_SSL object at 0x03AF42B0>
ユーザー名を送ります。※udat[1]はユーザーアカウント名 (例:’abcd@****.ne.jp”)
>>> M.user(udat[1]) # udat[1]:'user_account'
b'+OK'
パスワードを送ります。※udat[2]はパスワード
>>> M.pass_(udat[2]) # udat[2]:'Passwords'
b'+OK Logged in.' # ログインできたようです
サインオフします。
>>> M.quit()
b'+OK Logging out.' # ログアウトできたようです
以下はログイン後の各動作の確認です。
メールボックスのメール数とmailbox sizeを返します。
>>> M.stat()
(6, 28291) # 6通、28291bytes
受信メールのリストを(応答,[メール番号とサイズ,・・],octets)で返します。
>>> M.list()
(b'+OK 6 messages:', [b'1 8974', b'2 4294', b'3 3913', b'4 3639', b'5 5145',
b'6 2326'], 48)
>>>
メッセージに削除のためのフラグを立てます。quit()が実行されると削除されます。
>>> M.dele(6) #番号6を削除のフラグを付けます
b'+OK Marked to be deleted.'
サインオフします。
>>> M.quit()
b'+OK Logging out, messages deleted.'# 削除フラグ付が削除された
受信ボックスのリストを再確認します。
>>> M.list()
(b'+OK 5 messages:', [b'1 8974', b'2 4294', b'3 3913', b'4 3639',
b'5 5145'], 40) # (6)は削除されています。
>>>
指定した受信メールの内容(メッセージ)を返します。((応答, [‘行’,’行’,…], octets)で返ります。
>>> M.retr(5)
大幅に抜粋しています。メッセージの内容は以下のようになっていました。大半は読めませんでした。
(b'+OK 5145 octets', [b'Return-Path: <information@ma.email.aeon.co.jp>',
省略
b'Content-Type: text/plain;', b'\tcharset="utf-8"', b'Content-Transfer-Encoding: 8bit',
b'', b'\xe2\x80\xbb\xe6\x9c\xac\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab\xe3\x81\xaf\xe5\xa4
\xa7\xe5\x88\x87\xe3\x81\xaa\xe3\x81\x8a\xe7\x9f\xa5\xe3\x82\x89\xe3\x81\x9b\xe3\x81\xae
\xe3\x81\x9f\xe3\x82\x81\xe3\x80\x81\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab\xe9\x85\x8d\xe4
\xbf\xa1\xe3\x81\xae\xe8\xa8\xb1\xe8\xab\xbe\xe3\x82\x92\xe3\x81\x84\xe3\x81\x9f\xe3\x81
\xa0\xe3\x81\x84\xe3\x81\xa6\xe3\x81\x84\xe3\x81\xaa\xe3\x81\x84\xe6\x96\xb9\xe3\x81\xab
\xe3\x82\x82\xe9\x85\x8d\xe4\xbf\xa1\xe3\x81\x97\xe3\x81\xa6\xe3\x81\x8a\xe3\x82\x8a\xe3
\x81\xbe\xe3\x81\x99\xe3\x80\x82', b'',
省略
b'\xe3\x81\x84\xe3\x81\xa4\xe3\x82\x82\xe3\x82\xa4\xe3\x82\xaa\xe3\x83\xb3\xe3\x83\x9e
\xe3\x83\xbc\xe3\x82\xaf\xe3\x81\xae\xe3\x82\xab\xe3\x83\xbc\xe3\x83\x89\xe3\x82\x92\xe3
\x81\x94\xe6\x84\x9b\xe9\xa1\xa7\xe3\x81\x84\xe3\x81\x9f\xe3\x81\xa0\xe3\x81\x8d\xe3\x81
\x82\xe3\x82\x8a\xe3\x81\x8c\xe3\x81\xa8\xe3\x81\x86\xe3\x81\x94\xe3\x81\x96\xe3\x81\x84
\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82', b'',, b'\xe3\x80\x90\xe5\xa4\x89\xe6\x9b\xb4\xe7
\x82\xb9\xe3\x80\x91', b'\xe3\x…
一行づづ表示して見ます。以下のよう見やすくなりましたが読めないです。
>>> g_msg=M.retr(2)
>>> msg=g_msg[1] #(応答, ['行','行',...], octets)の ['行','行',...]の部分
>>> m=len(msg)
>>> for i in range(m):
print(msg[i])
読めないので試しに
msg[i].decode()
にしてみました。
From:、Subject:など読めない部分もありますが本文は読めました。
>>> g_msg=M.retr(5)
>>> msg=g_msg[1] #(応答, ['行','行',...], octets)の ['行','行',...]の部分
>>> m=len(msg)
>>> for i in range(m):
print(msg[i].decode()) # decode
Return-Path: <information@ma.email.aeon.co.jp>
省略
From: =?utf-8?B?44Kk44Kq44Oz44OV44Kj44OK44Oz44K344Oj44Or44K144O844OT44K55q
Cq5byP5Lya56S+?= <information@ma.email.aeon.co.jp>
Subject: =?utf-8?B?44Kk44Kq44Oz44K344ON44Oe54m55Yil6ZGR6LOe5YSq5b6F?=
=?utf-8?B?44Gu54m55YW444Oq44OL44Ol44O844Ki44Or44Gr44Gk44GE44Gm?=
省略
MIME-Version: 1.0
X-mailer: nlserver, Build 6.7.0
Message-ID: <NM615C1EE87014602A2acsprd@ma.email.aeon.co.jp>
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: 8bit
※本メールは大切なお知らせのため、メール配信の許諾をいただいていない方にも配信しております。
いつもイオンマークのカードをご愛顧いただきありがとうございます。
省略
※スマートフォン限定のサービスとなります。
──────────
カード発行元:株式会社イオン銀行
業務受託会社:イオンフィナンシャルサービス株式会社
http://t.ma.aeon.co.jp/r/?id=t26c80fdd,17e1ccf7,cff6dd3
──────────
>>>
調べてみました。
From:、Subject:のような’=?’で始まり’?=’で終わる形式は「MINE(Multipurpose Internet Mail Extensions)」と言うそうです。
MIMEエンコードは=?<文字コード>?<エンコード方式>?<エンコードされた内容>?=の形式で記載するそうです。
エンコード方式は’B’ならbase64、’Q’ならquoted-printableだそうです。
上記の例では’B’なのでbase64になるようです。
上記の本文は
charset=”utf-8″, Content-Transfer-Encoding: 8bitだったのでdecode()だけで読めたようです。
他のメールなど確認してみるとエンコードには、
‘Content-Transfer-Encoding: quoted-printable’
‘Content-Transfer-Encoding: base64′
また、文字コードには
charset=’utf-8′
charset=’iso-2022-jp’
がありました。別の機会に試したいと思います。
スクリプトの例
以下はメールデータを得るまでの一連の処理をまとめた例です。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import poplib
udat=[' ']*3 #['POP server','user_account','Passwords']
#user data
udat[0]='****.****.jp' #'POP server'
udat[1]='****@*****.ne.jp' #'user_account'
udat[2]='*********' #'Passwords'
#M=poplib.POP3(udat[0], port=110, timeout=10) #udat[0]:''POP server'
M=poplib.POP3_SSL(udat[0], port=995, timeout=10) #udat[0]:''POP server'
M.user(udat[1]) #udat[1]:'user_account'
M.pass_(udat[2]) #udat[2]:'Passwords'
rs=M.list()
print('List',rs)
which=int(input('Open email num ? = ')) #INPUT
print('')
#g_msg[1]がメール本文になります。
g_msg=M.retr(which) #(response, ['line', ...], octets)
#print(g_msg)
# sighn off
M.quit()
実行結果
以下は実行した結果例です。※Thonnyのshellに表示されます。
まとめ
popLibモジュールを使って受信メールのデータ確認をしました。
データの確認だけなら簡単にできました。
しかし、データを可読するには各文字コード、エンコードで変換する必要があるようです。
別の機会に試したいと思います。