下面代码实现的是接收QQ邮箱的邮件。如果用其他邮箱只需要把邮箱地址,口令还有POP3服务器地址修改就好了。
from email.parser import Parser
from email.header import decode_header,Header
from email.utils import parseaddr
import poplib
# 输入邮件地址, 口令和POP3服务器地址:
email = 'xxxxxxxxxx@qq.com'
password = 'xxxxx' # 这个密码不是邮箱登录密码,是pop3服务密码
pop3_server = 'pop.qq.com'
def decode_str(s):
value, charset = decode_header(s)[0]
if charset:
value = value.decode(charset)
return value
def print_info(msg):
# 输出发件人,收件人,邮件主题信息
for header in ['From', 'To', 'Subject']:
value = msg.get(header, '')
if value:
if header == 'Subject':
value = decode_str(value) # 将主题名称解密
else:
hdr, addr = parseaddr(value)
name = decode_str(hdr)
value = u'%s <%s>' % (name, addr)
print('%s: %s' % (header, value))
# 获取邮件主体信息
attachment_files = []
for part in msg.walk():
file_name = part.get_filename() # 获取附件名称类型
contentType = part.get_content_type() #获取数据类型
mycode = part.get_content_charset() #获取编码格式
if file_name:
h = Header(file_name)
dh = decode_header(h) # 对附件名称进行解码
filename = dh[0][0]
if dh[0][1]:
filename = decode_str(str(filename, dh[0][1])) # 将附件名称可读化
attachment_files.append(filename)
data = part.get_payload(decode=True) # 下载附件
with open(filename, 'wb') as f: # 在当前目录下创建文件,注意二进制文件需要用wb模式打开
#with open('指定目录路径'+filename, 'wb') as f: 也可以指定下载目录
f.write(data) # 保存附件
print(f'附件 {filename} 已下载完成')
elif contentType == 'text/plain': #or contentType == 'text/html':
# 输出正文 也可以写入文件
data = part.get_payload(decode=True)
content = data.decode(mycode)
print('正文:',content)
print('附件文件名列表',attachment_files)
# 连接到POP3服务器:
server = poplib.POP3_SSL(pop3_server, 995)
# 可以打开或关闭调试信息:
server.set_debuglevel(1)
# 可选:打印POP3服务器的欢迎文字:
print(server.getwelcome().decode('utf-8'))
# 身份认证:
server.user(email)
server.pass_(password)
# stat()返回邮件数量和占用空间:
print('Messages: %s. Size: %s' % server.stat())
# list()返回所有邮件的编号:
resp, mails, octets = server.list()
# 可以查看返回的列表类似[b'1 82923', b'2 2184', ...]
print(mails)
# 由于pop3协议不支持对已读未读邮件的标记,因此,要判断一封pop邮箱中的邮件是否是新邮件必须与邮件客户端联合起来才能做到。
index = len(mails)
print('未读邮件的数量',index)
# 获取最新一封邮件, 注意索引号从1开始,最后一个索引代表的是最新接收的邮件:
# 可以写个循环,获取所有邮件的内容 for i in range(1,index+1)
resp, lines, octets = server.retr(index)
# lines存储了邮件的原始文本的每一行,
# 可以获得整个邮件的原始文本:
msg_content = b'\r\n'.join(lines).decode('utf-8')
# 稍后解析出邮件:
msg = Parser().parsestr(msg_content)
#获取邮件内容
print_info(msg)
# 可以根据邮件索引号直接从服务器删除邮件:
# server.dele(2)
# 关闭连接:
server.quit()
如果有什么问题,欢迎指正。
参考的代码原文链接在这
https://blog.csdn.net/liumengcheng/article/details/44307565
https://blog.csdn.net/weixin_43751840/article/details/89156535