Python实战技巧(10)Python解析邮件

Python实战技巧(1)Python字典类型数据如何递归地通过点‘.’的方式访问

Python实战技巧(2)Python的pdb调试代码方法详解

Python实战技巧(3)多版本兼容安装部署(py27,py34,py35,py36,py37,py38,py39)

Python实战技巧(4)正式在pypi网站发布包的流程详解

Python实战技巧(5)Python版本兼容性测试工具tox实战详解

Python实战技巧(6)Miniconda+Pipenv安装部署开发环境实战详解

Python实战技巧(7)Pycharm如何远程调试远程执行

Python实战技巧(8)Python调用C语言

Python实战技巧(9)Python发送邮件

Python实战技巧(10)Python解析邮件

Python实战技巧(11)使用python收发邮件时需要的邮箱授权码如何获取

Python实战技巧(12)一个非常好用收发邮件、解析邮件的库caterpillar_mail

(1)使用python编写如下的读取并解析邮件的类库
import re
import poplib
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr


class Email(object):
    def __init__(self):
        self.__subject = ""
        self.__from_addr = ""
        self.__from_name = ""
        self.__to_name = ""
        self.__to_addr = ""
        self.__context = ""
        self.__html = ""
        self.__date = ""

    @property
    def subject(self):
        return self.__subject

    @subject.setter
    def subject(self, subj):
        self.__subject = subj

    @property
    def from_addr(self):
        return self.__from_addr

    @from_addr.setter
    def from_addr(self, from_addr):
        self.__from_addr = from_addr

    @property
    def from_name(self):
        return self.__from_name

    @from_name.setter
    def from_name(self, from_name):
        self.__from_name = from_name

    @property
    def context(self):
        return self.__context

    @context.setter
    def context(self, ctx):
        self.__context = ctx

    @property
    def to_name(self):
        return self.__to_name

    @to_name.setter
    def to_name(self, to_name):
        self.__to_name = to_name

    @property
    def to_addr(self):
        return self.__to_addr

    @to_addr.setter
    def to_addr(self, to_addr):
        self.__to_addr = to_addr

    @property
    def date(self):
        return self.__date

    @date.setter
    def date(self, date):
        self.__date = date


class ReadEmail(object):
    def __init__(self, mail_server):
        self.__pop_server = mail_server
        self.__username = ""
        self.__password = ""
        self.__pop = None

    def get_latest_n_email(self, n=1, subject="", from_addr="", from_name=""):
        resp, mails, octets = self.__pop.list()
        index = len(mails)
        results = []
        count = 0
        for i in range(index, 0, -1):
            resp, lines, octets = self.__pop.retr(i)
            msg_content = b'\r\n'.join(lines).decode('utf-8')
            msg_obj = Parser().parsestr(msg_content)
            obj = Email()
            email_subject = self.__decode_header_msg(msg_obj["subject"])
            if subject.strip() and subject.strip() != email_subject and not re.search(subject.strip(), email_subject):
                continue
            obj.subject = email_subject
            email_from_name, email_from_addr = parseaddr(msg_obj["From"])
            email_from_name = self.__decode_header_msg(email_from_name)
            email_from_addr = self.__decode_header_msg(email_from_addr)
            if from_name.strip() and from_name.strip() != email_from_name and not re.search(from_name, email_from_name):
                continue
            if from_addr.strip() and from_addr.strip() != email_from_addr and not re.search(from_addr, email_from_addr):
                continue
            obj.from_name = email_from_name
            obj.from_addr = email_from_addr
            email_to_name, email_to_addr = parseaddr(msg_obj["To"])
            email_to_name = self.__decode_header_msg(email_to_name)
            email_to_addr = self.__decode_header_msg(email_to_addr)
            obj.to_name = email_to_name
            obj.to_addr = email_to_addr
            email_date = self.__decode_header_msg(msg_obj["Date"])
            obj.date = email_date

            context = []
            if msg_obj.is_multipart():
                for part in msg_obj.get_payload():
                    ctx = self.__decode_body(part)
                    if ctx:
                        context.append(ctx)
            else:
                ctx = self.__decode_body(msg_obj)
                if ctx:
                    context.append(ctx)
            if context:
                obj.context = "\n".join(context)

            count += 1
            results.append(obj)
            if count >= n:
                return results

        return results

    def login(self, username, password):
        self.__username = username
        self.__password = password
        self.__pop = poplib.POP3(self.__pop_server)
        self.__pop.set_debuglevel(1)
        self.__pop.user(username)
        self.__pop.pass_(password)

    def __decode_header_msg(self, header):
        value, charset = decode_header(header)[0]
        if charset:
            value = value.decode(charset)
        return value

    def __decode_body(self, part):
        content_type = part.get_content_type()
        txt = ""
        if content_type == "text/plain" or content_type == 'text/html':
            content = part.get_payload(decode=True)
            charset = part.get_charset()
            if charset is None:
                content_type_get = part.get('Content-Type', '').lower()
                position = content_type_get.find('charset=')
                if position >= 0:
                    charset = content_type_get[position + 8:].strip()
                    if charset:
                        txt = content.decode(charset)
        return txt
(2)直接使用上述封装库
# 使用pop邮箱服务器实例化一个对象,如下为163的pop邮箱服务器
read_email = ReadEmail("pop.163.com")
# 登录邮箱,密码使用授权码,需要到邮箱设置里点击授权,并将授权码拷贝至此
read_email.login("[email protected]", "LRRDUVxxxxHNYHEMLK")
# 获取emails对象列表,按照时间顺序倒序获取,同时可以设置过滤条件,过滤条件可以通过邮件标题,发件人名,发件人邮箱过滤,支持正则表达式过滤,返回结果是一个列表,如果没有满足条件的为空列表,如果n设置多个,则返回满足条件的n封邮件,每一封邮件即为一个对象,通过对象属性可以获取到邮件的发送人、发送人邮箱,收件人,收件人邮箱,时间,邮件标题,邮件文本内容,还可以获取回复邮件html格式的邮件内容,此时的属性即为html
# 如下为获取最新的,邮件标题中有‘测试’字样的一封邮件
emails = read_email.get_latest_n_email(n=1, subject="测试")
for obj in emails:
    print(obj.from_name)
    print(obj.from_addr)
    print(obj.to_name)
    print(obj.to_addr)
    print(obj.date)
    print(obj.subject)
    print(obj.context)

执行结果如下:
在这里插入图片描述
打开邮件如下,内容一致
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/redrose2100/article/details/121358062