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)
执行结果如下:
打开邮件如下,内容一致