備忘メモ。
Python3で「mbox」形式のファイルから1つずつメール(=メッセージ)を取り出すのに利用した方法。
ライブラリ「mailbox」を利用する。
https://docs.python.jp/3/library/mailbox.html
import mailbox def read_contents(file): mbox = mailbox.mbox(file) keys = mbox.keys() return [(k, mbox.get_bytes(k)) for k in keys]
mbox形式のファイルパスを引数fileで指定し、mbox形式で開く。
keys()でキーを全て取得。
その後、キーを指定してmboxからメッセージをバイナリ形式で取り出している。
これで「メッセージを一意に表すキー」と「対応するメッセージのバイナリデータ」の組み合わせの配列が戻り値となる。
なお、キーは0から始まる連番である。つまり、1通目はキーが0、2通目はキーが1となる。
そのため「N通目以降から取り出したい」という場合なら、「if k >= N -1」をfor文に付与してやる。
return [(k, mbox.get_bytes(k)) for k in keys if k >= N -1]
メールヘッダの先頭にある"From "の扱い
「mbox.get_bytes(k)」で取得した場合、メッセージの区切りである「メールヘッダの先頭にある"From "(From+半角スペース)」の行が削除されている。
「メールヘッダの先頭にある"From "」の行も欲しかったのでソースコードを確認してみると、クラス「_mboxMMDF」の場合は「def get_bytes(self, key, from_=False):」で定義されていた。なお、「_mboxMMDF」は「mailbox.mbox()」の「__init__」で設定されている。
https://github.com/python/cpython/blob/3.6/Lib/mailbox.py
https://github.com/python/cpython/blob/3.6/Lib/mailbox.py#L789
https://github.com/python/cpython/blob/3.6/Lib/mailbox.py#L835
これにならい、「mbox.get_bytes(k)」を「mbox.get_bytes(k, True)」にして実施してみたところ、「メールヘッダの先頭にある"From "」の行も取得することができた。
import mailbox def read_contents(file): mbox = mailbox.mbox(file) keys = mbox.keys() return [(k, mbox.get_bytes(k, True)) for k in keys]
余談:
「mbox 固有の動作をするメッセージ」は以下に書かれてもいる。
https://docs.python.jp/3/library/mailbox.html#mailbox.mboxMessage