对于工作中,如果每日需要发送具有规律性的邮件,采用python自动发送可以节约很多时间,提高效率。本文主要以腾讯企业邮箱为例,介绍python自动发送邮件(含附件)的功能。为保护隐私,代码中的邮箱及授权码已替换,测试使用时更换为实际邮箱和授权码即可。
1. 获取授权码
授权码类似于密码,每家邮箱几乎都有,本文以腾讯企业邮箱为例,对应授权码在设置-账户设置的目录下,对应开通协议后即可过的授权码。
2. 源代码
本章节主要介绍不含附件,即纯文本的邮件发送,主要的步骤如下:
1. 传入邮箱账号和密码,进行登录
2. 传入邮件标题和内容,以及附件(没有可以不写)
3. 传入收件人邮箱,发送邮件
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.mime.application import MIMEApplication
import os
import datetimeclass Send_Eamil(object):def __init__(self, mailbox, pwd, addressee, title, text, attachments=None):self.email_host = "smtp.exmail.qq.com" # 发送邮件的服务器,此处以腾讯企业邮箱为例self.email_user = mailbox # 发送者的邮箱self.email_pwd = pwd # 授权码self.email_port = 465 # 服务器SSL端口号,默认是465self.addressee = addressee # 收件人邮箱,格式为列表self.title = title # 邮件标题self.text = text # 邮件正文内容self.attachments = attachments # 附件,格式为列表,对应添加绝对路径的文件名returndef log_in(self):# 登录邮箱,并检验是否成功smtpSSL = smtplib.SMTP_SSL(self.email_host, self.email_port) # 创建SSL对象loginRes = smtpSSL.login(self.email_user, self.email_pwd) # 输入账号和授权码,进行登录log_code = loginRes[0] # 登录对应返回的编码,235表示成功if log_code == 235:print('登录邮箱成功!')return smtpSSLelse:print('登录邮箱失败,报错编码:', log_code)os._exit(0)def write_email(self):# 创建邮件,并写入信息mail = MIMEMultipart() # 创建邮件mail['From'] = Header(self.email_user, 'utf-8') # 发件人mail['To'] = Header(",".join(self.addressee), 'utf-8') # 收件人列表mail['Subject'] = Header(self.title, 'utf-8') # 邮件标题mail.attach(MIMEText(self.text, 'plain', 'utf-8')) # 邮件正文内容# 添加附件,若没有则不添加if self.attachments == None:passelse:# 循环读取附件并添加for num in range(len(self.attachments)):document = self.attachments[num]try:document_name = document.split('/')[-1] # 剔除绝对路径后的文件名except:document_name = '附件' + str(num + 1) + documentone_doc = MIMEApplication(open(document, 'rb').read()) # 读取附件one_doc['Content-Type'] = 'application/octet-stream' # 设置格式# 添加附件标题one_doc.add_header('Content-Disposition', 'attachment', filename=document_name)mail.attach(one_doc)return maildef send(self):# 发送邮件mail = Send_Eamil.write_email(self)smtpSSL = Send_Eamil.log_in(self)try:smtpSSL.sendmail(self.email_user, self.addressee, mail.as_string())print('邮件发送成功')except Exception as e:print('邮件发送失败,报错为:',e)if __name__ == '__main__':today = datetime.date.today().strftime("%Y%m%d")title = today+'业绩报告'text = today + 'xxx产品涨跌幅为:{},xx指数涨跌幅为:{},跑赢指数:{}'.format('1%','0.5%','0.5%')mailbox = "send.cn"pwd = "password"addressee = ["adr.cn"]Send_Eamil(mailbox, pwd, addressee, title, text).send()
对应测试的结果如下:
3. 功能优化
在需要增加附件的情况下,可以将所需要的附件都放在一个文件夹中,自动读取,然后加入邮件中发送。
构建函数,读取上述文件夹下的文件,并保存为列表,其中的文件格式为‘绝对路径+文件名’ ,例如:‘D/桌面/附件/表格.xlsx’。函数的代码如下:
def get_attachments(file_Path):# 获取附件attachment_list = []for i, j, doc_list in os.walk(file_Path):for doc in doc_list:attachment_list.append(file_path + doc)return attachment_listif __name__ == '__main__':file_path = 'C:/xx/xxx/Desktop/附件/'attachments = get_attachments(file_path)today = datetime.date.today().strftime("%Y%m%d")title = today + '业绩报告'text = today + 'xxx产品涨跌幅为:{},xx指数涨跌幅为:{},跑赢指数:{}'.format('1%', '0.5%', '0.5%')mailbox = "send.cn"pwd = "password"addressee = ["adr.cn", "adr1.cn"]Send_Eamil(mailbox, pwd, addressee, title, text, attachments).send()
发送后的结果为:
4. 完全自动化
发送邮件的问题解决了,但是每次发送时,都需要run一次代码。为了避免忘记,可以采取定时任务+启动脚本的方式,来自动发送邮件,这种情况下,只需要每日更新一下发送的内容即可(如果内容是固定格式,可以考虑使用自动生成的思路)。
启动脚本的创建:新建一个txt文本,输入一下内容,再将脚本名称后缀改为“.bat”即可。
关于脚本的创建和定时任务网上资料非常多,这里也就不再进一步叙述。