wenblogs

Python邮件支持-poplib模块收取邮件

  POP3协议也属于请求-响应式交互协议,当客户端连接到服务器后,客户端向POP服务器发送请求,而POP服务器则对客户端生成响应数据,客户端可通过响应数据下载得到邮件内容。

  当下载完成后,邮件客户端可以删除或修改任意邮件,而无需与电子邮件服务器进行进一步交互。

使用poplib收取邮件可分为两步:

  1. 使用poplib.POP3或poplib.POP3_SSL按POP3协议从服务器端下载邮件

  2. 使用email.parse.Parse或email.parser.BytesParser解析邮件内容得到EmailMessage对象

 

  本程序代码比较详细,代码量比较多,所以为了美观折叠起来

# coding: utf-8
import poplib, os.path, mimetypes
from email.parser import BytesParser, Parser
from email.policy import default

# 输入邮件地址, 口令和POP3服务器地址:
email = 'wen_071@163.com'
password = 'OZWKUVFBNWZBEMJR'
pop3_server = 'pop.163.com'

# 连接到POP 3服务器:
#conn = poplib.POP3(pop3_server, 110)
conn = poplib.POP3_SSL(pop3_server, 995)
# 可以打开或关闭调试信息:
conn.set_debuglevel(1)
# 可选:打印POP 3服务器的欢迎文字:
print(conn.getwelcome().decode('utf-8'))

# 输入用户名、密码信息    身份认证
# 相当于发送POP 3的user命令
conn.user(email)
# 相当于发送POP 3的pass命令
conn.pass_(password)

# 获取邮件统计信息,相当于发送POP 3的stat命令
message_num, total_size = conn.stat()
print('邮件数: %s. 总大小: %s' % (message_num, total_size))#server.stat()
# 获取服务器上的邮件列表,相当于发送POP 3的list命令
# resp保存服务器的响应码
# mails列表保存每封邮件的编号、大小
resp, mails, octets = conn.list()
print(resp, mails)
# 获取指定邮件的内容(此处传入总长度,也就是获取最后一封邮件)
# 相当于发送POP 3的retr命令
# resp保存服务器的响应码
# data保存该邮件的内容
resp, data, octets = conn.retr(len(mails))
# 将data的所有数据(原本是一个字节列表)拼接在一起
msg_data = b'\r\n'.join(data)
# 将字符串内容解析成邮件,此处一定要指定policy=default
msg = BytesParser(policy=default).parsebytes(msg_data)       #
print(type(msg))
print('发件人:' + msg['from'])
print('收件人:' + msg['to'])
print('主题:' + msg['subject'])
print('第一个收件人名字:' + msg['to'].addresses[0].username)
print('第一个发件人名字:' + msg['from'].addresses[0].username)
for part in msg.walk():
    counter = 1
    # 如果maintype是multipart,说明是容器(用于包含正文、附件等)
    if part.get_content_maintype() == 'multipart' :
        continue
    # 如果maintype是text,说明是邮件正文部分
    elif part.get_content_maintype() == 'text':
        print(part.get_content())
    # 处理附件
    else :
        # 获取附件的文件名
        filename = part.get_filename()
        # 如果没有文件名,程序要负责为附件生成文件名
        if not filename:
            # 根据附件的contnet_type来推测它的后缀名
            ext = mimetypes.guess_extension(part.get_content_type())
            # 如果推测不出后缀名
            if not ext:
                # 使用.bin作为后缀名
                ext = '.bin'
            # 程序为附件来生成文件名
            filename = 'part-%03d%s' % (counter, ext)
        counter += 1
        # 将附件写入的本地文件
        with open(os.path.join('.', filename), 'wb') as fp:
            fp.write(part.get_payload(decode=True))
# 退出服务器,相当于发送POP 3的quit命令
conn.quit()
View Code

 

程序运行之前,我用qq邮箱给163邮箱发了一封邮件,如图:

 

接下来运行代码

代码运行的结果如下

+OK Welcome to coremail Mail Pop3 Server (163coms[10774b260cc7a37d26d71b52404dcf5cs])
*cmd* 'USER wen_071@163.com'
*cmd* 'PASS OZWKUVFBNWZBEMJR'
*cmd* 'STAT'
*stat* [b'+OK', b'38', b'4694601']
邮件数: 38. 总大小: 4694601
*cmd* 'LIST'
b'+OK 38 4694601' [b'1 7220', b'2 13065', b'3 2446', b'4 3170', b'5 104644', b'6 38881', b'7 2870', b'8 2461', b'9 3154', b'10 2511', b'11 2493', b'12 10583', b'13 32076', b'14 32079', b'15 32103', b'16 32085', b'17 32087', b'18 18450', b'19 4576', b'20 5104', b'21 16014', b'22 22672', b'23 16322', b'24 4008801', b'25 13127', b'26 9956', b'27 24152', b'28 11036', b'29 8441', b'30 5602', b'31 12009', b'32 4267', b'33 7459', b'34 8892', b'35 46744', b'36 48615', b'37 45015', b'38 3419']
*cmd* 'RETR 38'
<class 'email.message.EmailMessage'>
发件人:温~~ <1178268862@qq.com>
收件人:wen_071 <wen_071@163.com>
主题:这是一封用于测试poplib模块的邮件
第一个收件人名字:wen_071
第一个发件人名字:1178268862
这句话开始就是内容了,说完这句话就结束了,感谢您的阅读!
这句话开始就是内容了,<div>说完这句话就结束了,感谢您的阅读!</div>
*cmd* 'QUIT'

Process finished with exit code 0

 

代码部分详解:

# 连接到POP 3服务器:
#conn = poplib.POP3(pop3_server, 110)
conn = poplib.POP3_SSL(pop3_server, 995)

与smtplib相同,poplib模块也提供了poplib.POP3和poplib.POP3_SSL两个类,分别基于连接普通的POP服务器和基于SSL的POP服务器,各自端口不相同

posted on 2021-02-27 00:56  wenblogs  阅读(327)  评论(0编辑  收藏  举报

导航