ゴミ箱の中のメモ帳

まだ見ぬ息子たちへ綴る手記

Pythonでメールを受信する(POP)

プログラミングを勉強した10年ほど前のトラウマで私はメール関連のプログラムを書くことに恐怖を感じている。当時はPerlでメールを書くことが非常に難しく、文字コードでゲロを吐く思いを何度もしていた。

それからというものメール関連のコードを書くことを避けて生きてきたのだが、少々メールを扱うコードを書く必要が出来たのでPythonで調べてみた。そうすると最近はShiftJISでメールを送るアホも減ってきたということで、結構すんなりメールが扱えるようになっているとのことだ。Python自身にもメールを扱うモジュールが付属しておりある程度容易にコードをかけた。

ただし、httplibに対応するrequestsのように超便利モジュールは見つからなかった。もっと人間的なメールモジュールはないものか。

初めてのPython 第3版

初めてのPython 第3版


そしてメールを受信するコードを書いてみたのでサンプルを記事下部に記載しておく。メールを扱うコードはほぼ初めてなので誤りなどがあればコメントをいただけるとありがたい。

自前でコードを書くとデコード処理が毎回必要になったりで少々手間がかかる。これをまとめたクラスを作ればいいんだろうけど、Emailの仕様を把握していない私には少々難しい。誰か作ってくれないかな。


#!/usr/bin/python
# coding: UTF-8

import poplib
import email
import time

cfg = {
    "pop_server": 'YOUR_POP_SERVER',
    "user_name": 'YOUR_POP_SERVER_ACCOUNT',
    "password": 'YOUR_POP_SERVER_PASSWORD',
}


def receive_mail( cfg):
    def parse_message( message_string):
        def parse_date( message):
            message_date = email.utils.parsedate( message.get( "date"))
            return time.strftime( "%Y/%m/%d-%H:%M:%S", message_date)

        def parse_subject( message):
            message_subject = email.Header.decode_header( message.get( "subject"))
            return unicode( email.header.make_header( message_subject)).encode( "utf-8")

        def parse_body( message, charset):
            message_body = message.get_payload( decode=True)
            return unicode( message_body, charset, "ignore").encode( "utf-8").replace( "\n", "")

        def parse_from_addr( message):
            message_from_addr = email.Header.decode_header( message.get( "from"))
            return unicode( email.header.make_header( message_from_addr)).encode( "utf-8")

        def parse_to_addr( message):
            message_to_addr = email.Header.decode_header( message.get( "to"))
            return unicode( email.header.make_header( message_to_addr)).encode( "utf-8")

        message = email.message_from_string( message_string)
        message_charset = message.get_param( "charset")
        message_date = parse_date( message)
        message_subject = parse_subject( message)
        message_body = parse_body( message, message_charset)
        message_from_addr = parse_from_addr( message)
        message_to_addr = parse_to_addr( message)

        return {
            "date": message_date,
            "subject": message_subject,
            "body": message_body,
            "from_addr": message_from_addr,
            "to_addr": message_to_addr,
        }

    pop = poplib.POP3( cfg["pop_server"])
    pop.user( cfg["user_name"])
    pop.pass_( cfg["password"])

    messages = []
    for mail_num in range( 1, len( pop.list()[1]) + 1):
        message_string = "\n".join( pop.retr( mail_num)[1])
        messages.append( parse_message( message_string))

    pop.quit()

    for message in messages:
        print message["date"], message["subject"]


receive_mail( cfg)

Pythonスタートブック

Pythonスタートブック

初めてのPython 第3版

初めてのPython 第3版

パーフェクトPython (PERFECT SERIES 5)

パーフェクトPython (PERFECT SERIES 5)

エキスパートPythonプログラミング

エキスパートPythonプログラミング