打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用python3处理邮件正文及附件
用python接收邮件的功能非常的常见,我也研究了好久,参考了廖雪峰大大的相关教程和网上的一些资源才大概了解了相应的功能。其中好多代码是直接参考(copy)别人的,中文处理方面真的是折磨了我好久。
日常生活中使用QQ邮箱的频率很高,我在这里使用的也是QQ邮箱,像以前的话,QQ邮箱的pop3登录可以直接使用新密码就可以直接登录了,但现在我发现直接使用新设置的密码会报错。
poplib.error_proto: b'-ERR Please using authorized code to login.
因此我只能使用短信的方式获取验证码。
image.png
然后使用之后的授权码当做密码就不会再报错了。
首先是登录邮箱
import poplibemail='392361639@qq.com'password='授权码'server=poplib.POP3_SSL('pop.qq.com')server.user(email)server.pass_(password)resp, mails, octets = server.list()index = len(mails)#邮件的总数#server.dele(index) 删除邮件 dele可以用于删除制定位置的邮件resp, lines, octets = server.retr(index)#可以取出最新的邮件的信息msg_content = b'\r\n'.join(lines).decode('utf-8','ignore') #将邮件组合到一起,生成邮件信息print(msg_content)
msg_content大致内容.png
可以看到打印出来的msg_content文件信息大致是这样的,里面包含了邮件的头文件,如Date,Subject,From,TO等信息。接下来要取出邮件头部相关的信息。上图的头部信息并没有出现乱码,但有的邮件就会如下图所示
image.png
from email.parser import Parserfrom email.header import decode_headerfrom email.utils import parseaddr#专门处理地址的模块#email中专门处理邮件内容的模块msg = Parser().parsestr(msg_content)#通过msg.get('From')等方法可以获取头部,但会出现编码不对#通过decode,将Subject其变为中文def decode_str(s): value, charset = decode_header(s)[0] if charset: value = value.decode(charset) return valuedef get_header(msg): for header in ['From', 'To', 'Subject']: value = msg.get(header, '') if value: #文章的标题有专门的处理方法 if header == 'Subject': value = decode_str(value) elif header in ['From','To']: #地址也有专门的处理方法 hdr, addr = parseaddr(value) value = decode_str(addr) print(header + ':' + value)
头部信息取出后接着去正文内容,由于我平时的需求主要为文本信息或者附件,针对指定邮件获取信息,或者是取出附件,对一些广告邮件就不需要处理(我也不知道如何去处理)
邮件的正文部分处理
#邮件正文部分#取附件#邮件的正文部分在生成器中,msg.walk()#如果存在附件,则可以通过.get_filename()的方式获取文件名称def get_file(msg): for part in msg.walk(): filename=part.get_filename() if filename!=None:#如果存在附件 filename = decode_str(filename)#获取的文件是乱码名称,通过之前定义的函数解码 data = part.get_payload(decode = True)#取出文件正文内容 #此处可以自己定义文件保存位置 path=filename f = open(path, 'wb') f.write(data) f.close() print(filename,'download')#接下来取正文信息#获取邮件的字符编码,首先在message中寻找编码,如果没有,就在header的Content-Type中寻找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 charsetdef get_content(msg): for part in msg.walk(): content_type = part.get_content_type() charset = guess_charset(part) #如果有附件,则直接跳过 if part.get_filename()!=None: continue email_content_type = '' content = '' if content_type == 'text/plain': email_content_type = 'text' elif content_type == 'text/html': print('html 格式 跳过') continue #不要html格式的邮件 email_content_type = 'html' if charset: try: content = part.get_payload(decode=True).decode(charset) #这里遇到了几种由广告等不满足需求的邮件遇到的错误,直接跳过了 except AttributeError: print('type error') except LookupError: print("unknown encoding: utf-8") if email_content_type =='': continue #如果内容为空,也跳过 print(email_content_type + ' ----- ' + content) #邮件的正文内容就在content中
邮件正文结果
下面附上完整代码
import poplib#解析邮件from email.parser import Parserfrom email.header import decode_headerfrom email.utils import parseaddr#解析消息头中的字符串#没有这个函数,print出来的会使乱码的头部信息。如'=?gb18030?B?yrXWpL3hufsueGxz?='这种#通过decode,将其变为中文def decode_str(s): value, charset = decode_header(s)[0] if charset: value = value.decode(charset) return value#解码邮件信息分为两个步骤,第一个是取出头部信息#首先取头部信息#主要取出['From','To','Subject']'''From: "=?gb18030?B?anVzdHpjYw==?=" <justonezcc@sina.com>To: "=?gb18030?B?ztLX1Ly6tcTTys/k?=" <392361639@qq.com>Subject: =?gb18030?B?dGV4dMTjusM=?='''#如上述样式,均需要解码def get_header(msg): for header in ['From', 'To', 'Subject']: value = msg.get(header, '') if value: #文章的标题有专门的处理方法 if header == 'Subject': value = decode_str(value) elif header in ['From','To']: #地址也有专门的处理方法 hdr, addr = parseaddr(value) name = decode_str(addr) #value = name + ' < ' + addr + ' > ' value=name print(header + ':' + value)#头部信息已取出#获取邮件的字符编码,首先在message中寻找编码,如果没有,就在header的Content-Type中寻找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#邮件正文部分#取附件#邮件的正文部分在生成器中,msg.walk()#如果存在附件,则可以通过.get_filename()的方式获取文件名称def get_file(msg): for part in msg.walk(): filename=part.get_filename() if filename!=None:#如果存在附件 filename = decode_str(filename)#获取的文件是乱码名称,通过一开始定义的函数解码 data = part.get_payload(decode = True)#取出文件正文内容 #此处可以自己定义文件保存位置 path=filename f = open(path, 'wb') f.write(data) f.close() print(filename,'download')def get_content(msg): for part in msg.walk(): content_type = part.get_content_type() charset = guess_charset(part) #如果有附件,则直接跳过 if part.get_filename()!=None: continue email_content_type = '' content = '' if content_type == 'text/plain': email_content_type = 'text' elif content_type == 'text/html': print('html 格式 跳过') continue #不要html格式的邮件 email_content_type = 'html' if charset: try: content = part.get_payload(decode=True).decode(charset) except AttributeError: print('type error') except LookupError: print("unknown encoding: utf-8") if email_content_type =='': continue #如果内容为空,也跳过 print(email_content_type + ' ----- ' + content)#get_file(msg)if __name__ == '__main__': email='392361639@qq.com' password='ngq*******rznbici' server=poplib.POP3_SSL('pop.qq.com') server.user(email) server.pass_(password) #登录的过程 resp, mails, octets = server.list() index = len(mails)#邮件的总数 #此处的循环是取最近的几封邮件 for i in range(index-2,index+1): resp, lines, octets = server.retr(i)#取邮件 msg_content = b'\r\n'.join(lines).decode('utf-8','ignore') msg = Parser().parsestr(msg_content) #server.dele(index) 删除邮件 get_header(msg) get_file(msg) get_content(msg) server.quit()
下面是发送正文及附件,相对读取邮件信息,发送邮件要比读取要简单很多
import smtplibfrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextimport os sender = 'justonezcc@sina.com'receiver = '392361639@qq.com'subject = 'python email test'smtpserver = 'smtp.sina.com'password = '***'from email import encodersmsgRoot = MIMEMultipart('alternative')msgRoot['Subject'] = subjectmsgRoot['From'] = sendermsgRoot['To']=receiver#发送正文content='你好,这是一封测试邮件'cont=MIMEText(content,'plain','utf-8')msgRoot.attach(cont)#发送附件file_name='实证结果.xls'#要发送文件的文字row_path=os.getcwd()#或者其他路径path=os.path.join(row_path,file_name)att = MIMEText(open(path, 'rb').read(), 'base64', 'gb2312')att["Content-Type"] = 'application/octet-stream'att.add_header('Content-Disposition', 'attachment', filename=('gb2312', '', file_name)) msgRoot.attach(att)smtp = smtplib.SMTP()smtp.connect(smtpserver)smtp.login(sender, password)smtp.sendmail(sender, receiver, msgRoot.as_string())smtp.quit()
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
POP3收取邮件
python发送邮件接收邮件示例分享
python如何实现远程控制电脑(结合微信)
python 发送邮件 乱码解决
使用python自动发放员工工资条到个人邮箱
Python 进阶(三):邮件的发送与收取
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服