背景
由于工作需要,经常要批量发送邮件,最开始的解决方法是通过Excel的VBA宏+outlook进行发送,但由于平时更多的使用Foxmail,而VBA调用Foxmail的办法至今都没有很好的解决(汗…)并且,很多环境中excel的vba与outlook的环境并不是每台机子都具备,所以萌生了使用Python打包一个邮件批量发送的小程序。
程序功能:
收件人、抄送人、主题、正文以及附件均通过Excel控制,只需要制作好Excel文件,即可批量发送;
使用方法:
- 将主程序与“邮件地址.xlsx"放在同一个文件夹下
- 发送前要核对邮件地址.xlsx中的数据准确性,且不要改动列的顺序。
- 发送完成后,会在当前目录下生成log.txt的文件,记录发送的结果
- 可通过pyinstaller方法,将Python文件进行打包,方便多种环境(Windows)使用。
邮件地址.xlsx的格式如下:
源码如下:
import os
import smtplib
import datetime
from email import encoders
from email.header import Header # 用来设置邮件头和邮件主题
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import pandas as pd
def addAttch(attach_file):
att = MIMEBase('application', 'octet-stream') # 这两个参数不知道啥意思,二进制流文件
att.set_payload(open(attach_file, 'rb').read())
# att.add_header('Content-Disposition', 'attachment', filename=(attach_file.split("\\")[-1]))
att.add_header('Content-Disposition', 'attachment', filename=('gbk', '', attach_file.split("\\")[-1]))
encoders.encode_base64(att)
return att
print("使用前请再次确认邮件地址.xlsx文件中的各项数据正确,并仔细阅读提示!!!!")
nowtime = datetime.datetime.strftime(datetime.datetime.now(),'%Y-%m-%d %H:%M:%S')
# 发件人
sender = 'XXX@chinatelecom.cn'
# 所使用的用来发送邮件的SMTP服务器
smtpServer = 'smtp.chinatelecom.cn'
# 发送邮箱的用户名和密码
username = 'XXX@chinatelecom.cn'
password = input("请输入邮箱密码")
nowpath = os.getcwd()
df = pd.read_excel(nowpath+"/邮件地址.xlsx")
#print(df)
# 读取项目名称列,不要列名
df = df.fillna(value="")
df_li = df.values.tolist()
try:
smtp = smtplib.SMTP_SSL(smtpServer,465) # ssl安全连接,端口号465
#smtp = smtplib.SMTP()
#smtp.connect(smtpserver)
#smtp.connect(smtpServer,465) # 连接发送邮件的服务器
smtp.login(username, password) # 登录服务器
for df_li in df_li:
message = MIMEMultipart()
message.attach(MIMEText(df_li[3], 'plain', 'utf-8')) # 邮件正文
message['From'] = sender # 邮件上显示的发件人
message['To'] = df_li[0] # 收件人
message['cc'] = df_li[1] # 抄送人
message['Subject'] = Header(df_li[2], 'utf-8') # 邮件主题
if os.path.exists(df_li[4]):
message.attach(addAttch(df_li[4])) #添加附件
else:
print("发送给"+df_li[0]+"的邮件由于没有附件,没有发送")
f = open('.\\log.txt', "a+")
f.write(nowtime+"*********发送给"+df_li[0]+"的邮件由于没有附件,没有发送\r\n")
f.close()
continue
smtp.sendmail(sender, message['To'], message.as_string()) # 填入邮件的相关信息并发送
print("发送给"+df_li[0]+"的邮件发送成功!!!")
f = open('.\\log.txt', "a+")
f.write(nowtime + "***********发送给"+df_li[0]+"的邮件发送成功!!!\r\n")
f.close()
smtp.quit()
except smtplib.SMTPException:
print("邮件服务器连接错误(请检查用户名与密码),邮件发送失败")
其他反思
- 最开始测试的使用的163邮箱,使用smtplib.SMTP()即可正确连接smtp服务器,但后来使用企业邮箱进行发送的时候,由于使用了SSL协议,所以修改为smtplib.SMTP_SSL(smtpServer,465) ,根据企业邮箱的说明配置端口号。
- 通过pyinstaller方法进行打包程序以后,界面会一闪而逝,无法判断所以又添加了写入log的功能,需要以"a+"权限打开log.txt,感觉效率有些低下,试图寻找更好的方法。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
- 试图通过os.system(‘pause’)方法构造任意键继续的效果,但是显示乱码,打包后的程序无法正确显示。