使用Python进行邮件的批量发送(从Excel读取收件人、主题、正文、附件地址等)

背景

由于工作需要,经常要批量发送邮件,最开始的解决方法是通过Excel的VBA宏+outlook进行发送,但由于平时更多的使用Foxmail,而VBA调用Foxmail的办法至今都没有很好的解决(汗…)并且,很多环境中excel的vba与outlook的环境并不是每台机子都具备,所以萌生了使用Python打包一个邮件批量发送的小程序。

程序功能:

收件人、抄送人、主题、正文以及附件均通过Excel控制,只需要制作好Excel文件,即可批量发送;

使用方法:

  1. 将主程序与“邮件地址.xlsx"放在同一个文件夹下
  2. 发送前要核对邮件地址.xlsx中的数据准确性,且不要改动列的顺序。
  3. 发送完成后,会在当前目录下生成log.txt的文件,记录发送的结果
  4. 可通过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 = '[email protected]'
# 所使用的用来发送邮件的SMTP服务器
smtpServer = 'smtp.chinatelecom.cn'
# 发送邮箱的用户名和密码
username = '[email protected]'
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("邮件服务器连接错误(请检查用户名与密码),邮件发送失败")

其他反思

  1. 最开始测试的使用的163邮箱,使用smtplib.SMTP()即可正确连接smtp服务器,但后来使用企业邮箱进行发送的时候,由于使用了SSL协议,所以修改为smtplib.SMTP_SSL(smtpServer,465) ,根据企业邮箱的说明配置端口号。
  2. 通过pyinstaller方法进行打包程序以后,界面会一闪而逝,无法判断所以又添加了写入log的功能,需要以"a+"权限打开log.txt,感觉效率有些低下,试图寻找更好的方法。
a+	打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
  1. 试图通过os.system(‘pause’)方法构造任意键继续的效果,但是显示乱码,打包后的程序无法正确显示。

你可能感兴趣的:(Python)