邮件的接收和发送是日常工作必备的内容,前一段时间我需要进行工作交接,从上万分邮件中找到和某些关键词相关的邮件,并以附件的形式发送给不同的人,一共有600多个这样的关键词,如果要手动执行,我需要手动执行600多次,这简直让人无法接收。因此为了自动化该过程,我学习了python3如何接收和发送邮件的过程,并试着完成该项目交接。中间遇到了各种各样的问题,由于同时我还要处理新的工作,只能利用业余时间来一一解决,例如由于网络问题导致的搜索中断,多次请求重试依然失败等情况,等完全处理完该任务已经是过了整整一周的时间!讲真的,这时间我手动搜索都该弄完了,但是,在我最终用该方法完成这个任务之后,我觉得下次如果再有用相似的工作,我可以很快就完成了,这种感觉可以用“我进化了!”来形容。但是如果我选择手动执行,那么下次再发送600封邮件的话,我依然需要和这次差不多长的时间来完成,更何况,我就很享受这种翻山越岭后瞬间的满足感与成就感呢,通过努力战胜枯燥的重复,这种感觉就很不一样呢。这么一想,我终于释然了。接下来记录从本项目中学习到的一些东西。
首先是需要开通邮箱的imap和smtp功能,即接收邮件和发送邮件的协议,我这里使用的是腾讯企业邮箱,在设置中勾选对应功能即可。
#configure receive_host = 'imap.exmail.qq.com' receive_port = 993 send_host = 'smtp.exmail.qq.com' send_port = 465 user = 'your@email.com' password = 'your_email_password'接下来是导入我们需要用到的一些模块,以下都是built-in的模块,imaplib用于接收邮件,smtplib用于发送邮件,email用于解析邮件。
import imaplib import email import smtplib import chardet from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication不管是接收还是发送邮件,首先都要先登陆邮箱服务器,这里impalib提供了两种登陆方式,分别对应IMPA4和IMPA4_SSL两个函数,我这里需要使用SSL的方式,这个可以在邮件的设置里面看到应该用哪个,或者你也不知道就用try...except... 的方式来实现就可以了。
#login email client client = imaplib.IMAP4_SSL(receive_host,receive_port) client.login(user,password)接下里显示所有的邮件箱,这里python3可以通过一下的转换编码的方式来显示中文命名的收信箱,但在选择收信箱的时候还是要用client.list()中的名字。
#show all inbox for i in client.list()[1]: chinese_name = i.decode('utf-8').split(' "/" ')[1].replace('&','+').encode('utf-8').decode('utf-7') tag = i.decode('utf-8').split(' "/" ')[1] print('%s : %s' % (tag,chinese_name))接下里就是选择收信箱并获取里面的邮件了,client.select()默认会选择INBOX也就是邮箱中默认就有的收信箱,你也可以选择其他的收信箱,然后我们可以通过client.search()来选择其中的部分或者全部的邮箱,这里选择全部的邮件。
#select a inbox inbox_info = client.select('INBOX') type,data = client.search(None,'ALL') total_emails = len(data[0].split())接下来是下载邮件并解析邮件
for num in data[0].split(): typ, data = M.fetch(num, '(RFC822)') print('Message %s\n%s\n' % (num, data[0][1])) if data and data != [None]: encoding = chardet.detect(data[0][1]) msg = email.message_from_string(data[0][1].decode(encoding['encoding'])) text,enc = email.header.decode_header(msg['subject'])[0] subject = text.decode(enc) if enc else text最后我们可以保存下载的邮件
with open(ofile,'wb') as odata: odata.write(data[0][1])也可以添加附件,但是附件不能超过50M
with open(f,'rb') as indata: part = MIMEApplication(indata.read()) part.add_header('Content-Disposition', 'attachment', filename=f) msg.attach(part)最后我们就可以发送邮件了
all_recipients = recipients + cc smtp_obj.sendmail(msg['from'],all_recipients,str(msg))