3.POP3收取邮件
1.简介
POP是指邮局协议,目的是让用户可以访问邮箱服务器中的邮件,允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收电子邮件的
2.函数
python提供了poplib模块来支持pop3 收取邮件的过程
连接pop3服务器 (poplib.POP3.init) 发送用户名和密码进行验证 (poplib.POP3.user poplib.POP3.pass_) 获取邮箱中信件信息 (poplib.POP3.stat) 收取邮件 (poplib.POP3.retr) 删除邮件 (poplib.POP3.dele) 退出 (poplib.POP3.quit)
1.函数方法
方法 描述 POP3(server) 实例化POP3对象,server是pop服务器地址 user(username) 发送用户名到服务器,等待服务器返回消息 pass_(password) 发送密码 stat() 返回邮箱的状态,返回2元组(消息的数量,消息的总字节数目)–>邮件总数,总字节数 list([msgnum]) stat()的扩展,返回一个3元组(返回信息,消息列表,消息的大小),如果指定msgnum,就只返回指定消息的数据 —返回邮件数量和每个邮件的大小 retr(msgnum) 获取详细的msgnum,设置为已读,返回3元组(返回信息, 消息msgnum的所以内容, 消息的字节数),如果指定msgnum,就只返回指定消息的数据—返回由参数标识的邮件的全部文本 dele(msgnum) 将指定消息标记为删除 quit() 登出,保存修改,解锁邮箱,结束连接,退出 top() 服务器返回由参数标识的邮件前n行内容,n必须是整数 noop() 服务器返回一个肯定的相应 uidl 返回邮件的唯一标识符,pop3回话的每个标识符都是唯一的 apop(name,digest) digest是md5消息摘要
2.接收邮件
from poplib import POP3
#pop3服务器地址
host = 'pop3.163.com'
#用户名
username = 'xxx@163.com'
#密码
password = 'xxx'
#创建一个pop3对象,这个时候已经连接上服务器了
pp = POP3(host)
#设置调试模式
pp.set_debuglevel(1)
#向服务器发送用户名
pp.user(username)
#向服务器发送密码
pp.pass_(password)
#获取服务器上信件信息,返回时一个列表,第一项是一共有多少邮件,第二项是有多少字节
ret = pp.stat()
print(ret)
# 需要取出所有信件的头部,信件id是从1开始的
for i in range(1,ret[0]+1):
#去除信件头部,注意:top指定的行数是以信件头为基数的,也就是说当取0行
#其实是返回头部信息,取一行其实是返回头部信息之外再多1行
"""
POP3.top(which, howmuch)
Retrieves the message header plus howmuch lines of the message after the header of message number which. Result is in form (response, ['line', ...], octets).
The POP3 TOP command this method uses, unlike the RETR command, doesn’t set the message’s seen flag; unfortunately, TOP is poorly specified in the RFCs and is frequently broken in off-brand servers. Test this method by hand against the POP3 servers you will use before trusting it.
which:表示的是第几封信
howmuch: 指的是头部以后的第几行
"""
mlist = pp.top(i,0)
print('line:' ,len(mlist[1]))
#取出第一份邮件的头部
mlist = pp.top(1,0)
print('line0:') + str(len(mlist[0])) + 'line1:' + str(len(mlist[1]))
print(mlist[0]) #这份邮件的状态。邮件总字节数
print(mlist[1]) #邮件头内容
print(mlist[2]) #邮件头字节数
print(mlist)
#列出服务器上邮件信息,这个会对没一封邮件都输出id和大小, stat输出的是总的统计信息
ret = pp.list()
print(ret)
# 取第一封邮件完整信息,在返回值里,是按行存储在down[1]的列表里的。down[0]是返回的状态信息
"""
POP3.retr(which)
Retrieve whole message number which, and set its seen flag. Result is in form (response, ['line', ...], octets).
"""
down = pp.retr(1)
print('lines:', len(down))
#输出邮件,按行存在down[1]中,打印出每一行
for line in down[1]:
print(line)
#退出
pp.quit()如果需要安全邮件,则是对pop3做了ssl加密,这样要使用POP3_SSL类
pp = poplib.POP3_SSL(host,port=x)
3.收取邮件并使用smtp解析
解析邮件很容易
import email
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
import poplib
# pop3服务器地址
host = 'pop3.163.com'
#用户名
username = 'xxx@163.com'
#密码
password = 'xxx'
#创建一个pop3对象,这个时候已经连接上服务器
server = poplib.POP3(host)
# 设置调试模式
server.set_debuglevel(1)
# 登录
server.user(username)
server.pass_(password)
#stat()返回二元组(邮件总数,邮件总字节数)
print('Messages: %s. Size: %s' % server.stat())
# list()返回3元组(消息状态,[每个邮件编号和大小],消息的字节数)
resp, mails, octets = server.list()
# 获取最新一封邮件, 注意索引号从1开始:
resp, lines, octets = server.retr(len(mails))
# 解析邮件
msg = Parser().parsestr('rn'.join(lines))
# 打印邮件内容:
print_info(msg)
# 慎重:将直接从服务器删除邮件:
# server.dele(len(mails))
# 关闭连接:
server.quit()但是Message对象本省可能是一个MIMEMultipart对象,即包含其他MIMEBase对象,嵌套可能还不止一层。所以我们要递归的打印出Message对象的层次结构:
import poplib
import email
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
def guess_charset(msg):
charset = msg.get_charset()
if charset is None:
content_type = msg.get('Content-Type', '').lower()
pos = content_type.find('charset=')
if pos >= 0:
charset = content_type[pos + 8:].strip()
return charset
def decode_str(s):
value, charset = decode_header(s)[0]
if charset:
value = value.decode(charset)
return value
#-------------------------------------------------------
#递归的打印出message对象的层次结构(可能不止一层)
#
#
#
#
def print_info(msg, indent=0): #indent用于缩进显示
if indent == 0:
#邮件的From,To,Subject存在于根对象上
for header in ['From', 'To', 'Subject']:
value = msg.get(header, '')
if value:
if header=='Subject':
#需要解码Subject字符串
value = decode_str(value)
else:
#需要解码Email地址
hdr, addr = parseaddr(value)
name = decode_str(hdr)
value = u'%s <%s>' % (name, addr)
print('%s%s: %s' % (' ' * indent, header, value))
if (msg.is_multipart()):
#如果邮件对象是一个MIMEMultipart
#get_payload()返回一个list,包含所有的子对象
parts = msg.get_payload()
for n, part in enumerate(parts):
print('%spart %s' % (' ' * indent, n))
print('%s--------------------' % (' ' * indent))
#递归打印每一个子对象
print_info(part, indent + 1)
else:
#邮件对象不是一个MIMEMultipart
# 就根据content_type判断
content_type = msg.get_content_type()
if content_type=='text/plain' or content_type=='text/html':
#纯文本或者html
content = msg.get_payload(decode=True)
#检查文本编码
charset = guess_charset(msg)
if charset:
content = content.decode(charset)
print('%sText: %s' % (' ' * indent, content + '...'))
else:
#不是文本,作为附件处理
print('%sAttachment: %s' % (' ' * indent, content_type))
– END –
原文始发于微信公众号(Flask学习笔记):Flask Mail(2)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/36463.html