Python实现自动写邮件
上星期接到任务要完成一个自动写邮件的脚本,基本功能是每两小时执行一次程序跑出统计表格,并将统计表格的summary发送到领导的邮箱。由于公司是做数字货币的,每两小时实时监测策略交易情况较为必要。下面来实现自动写邮件的功能部分
准备工作
本文将以腾讯企业邮箱为例,利用python编写自动写邮件程序。将用到以下库和模块,其中pandas用来演示用邮件利用html语言发送数据框:
import smtplib
from email.mime.text import MIMEText
from email import encoders
from email.mime.multipart import MIMEMultipart
from email.utils import formataddr
import pandas as pd
要使用smtp服务,需要登陆邮箱并进行设置。登陆邮箱后在设置-客户端设置-开启SMTP服务。
发送邮件通常有发件人(名字),收件人(名字),标题,正文,图片,附件。下面将演示如何一步步发送带图片,附件的邮件。
初始化
首先在函数里定义发件人收件人,标题。其中若收件人为多人,需要注意一下,初始定义为以’,’或’;’连接的字符串,而在sendmail函数里需要利用split进行分割传入一个列表参数,具体见代码
def mail():sender = 'XXXXXX@163.com' #发件人password = 'XXX' #密码receiver = 'XXXX@qq.com,YYYY@163.com' #多个收件人subject = '测试邮件' #标题msg = MIMEMultipart('mixed') #初始化定义,mixed为含多种功能的邮件msg['From'] = sendermsg['To'] = receivermsg['Subject'] = subject
下面我们通过定义添加附件的函数,添加正文的函数,添加图片的函数来完善功能,只需将msg作为参数传入即可
添加正文
添加正文有两种方式,一种是通过html语言,一种是直接传入字符串。而作为监控邮件,通常需要看的是一张表格中的数据,这时利用html调整格式较为美观且方便。这里将演示读入数据框df后如何发送
def create_df():'''随意定义一个数据框作测试,此函数可更改为pd.read_csv来读取想要发送的数据'''df = pd.DataFrame({'a':[1,2,3,4],'b':[2,3,4,5]})return dfdef attach_text(msg):df = create_df()col = df.columnsd = ''for i in range(df.shape[0]):d = d + """<tr><td width="80">""" + str(df.iloc[i][0]) + """</td><td width="80">""" + str(df.iloc[i][1]) + """</td></tr>"""html = """/<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><body><div id="container"><strong>测试表格:<div id="content"><table width="30%" border="2" bordercolor="black" cellspacing="0" cellpadding="0"><tr><td width="80"><strong>a</strong></td><td width="80"><strong>b</strong></td></tr> + d + """</table></div></div></div></body></html>"""%(df.columnscontext = MIMEText(html,_subtype='html', _charset='utf-8')msg.attach(context)print('添加正文表格完成')
添加附件
def attach_enclosure(msg):file = 'C:/Users/19470/Desktop/test.xlsx' #发送附件的文件路径attach = MIMEText(open(file, 'rb').read(), 'base64', 'utf-8')attach['Content-type'] = 'application/octet-stream'attach_name = "attachment;filename='test_enclosure'"attach['Content-Disposition'] = attach_namemsg.attach(attach)print('添加附件完成')
添加图片
要把图片嵌入到邮件正文中,我们只需按照发送附件的方式,先把邮件作为附件添加进去,然后,在HTML中通过引用src=”cid:0”就可以把附件作为图片嵌入了。如果有多个图片,给它们依次编号,然后引用不同的cid:x即可。
这里不再演示。
最后步骤
假设我们需要发送包含附件,图片以及正文的邮件,在mail函数中完善为一下代码
def mail():sender = 'XXXXXX@163.com' #发件人password = 'XXX' #密码receiver = 'XXXX@qq.com,YYYY@163.com' #多个收件人subject = '测试邮件' #标题msg = MIMEMultipart('mixed') #初始化定义,mixed为含多种功能的邮件msg['From'] = sendermsg['To'] = receivermsg['Subject'] = subjectmsg = MIMEMultipart('mixed')attach_enclosure(msg) #添加附件attach_text(msg) #添加正文smtp = smtplib.SMTP() #建立smtp对象smtp.connect('smtp.exmail.qq.com') #可在邮箱客户端查看,smtp服务地址smtp.set_debuglevel(1) #输出程序执行logsmtp.login(sender, password) #登陆smtp.sendmail(sender, receiver.split(','), msg.as_string()) #发送邮件,需要将收件人split成列表print('%s 发送成功'%subject)smtp.quit()
总结
最后效果如图
自动发邮件在监控系统运营情况时较为有效,通过datetime模块设置自动发邮件的时间,再定时执行相关文件输出表格,最后再发送邮件,可以在非上班时间实时监测系统运营情况。