自动邮件发送(群发,加密等)
Posted 小蜗牛爱远行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自动邮件发送(群发,加密等)相关的知识,希望对你有一定的参考价值。
- 使用Python自动发送邮件(群发,加密等)
# coding: utf-8
import tkinter as tk
from tkinter import filedialog
from datetime import datetime
import pandas as pd
import numpy as np
# import matplotlib.pyplot as plt
import os, calendar, time, copy, openpyxl, re, datetime
from openpyxl import load_workbook
import win32com.client, hashlib, logging, smtplib
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
# email 用于构建邮件内容
from email.header import Header
# 发送附件
from email.mime.application import MIMEApplication
# 发送多个部分
from email.mime.multipart import MIMEMultipart
# 专门发送文本的!MIMEText
from email.mime.text import MIMEText
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s line:%(lineno)d %(levelname)s : %(message)s',
datefmt=' %Y-%m-%d %H:%M:%S',
filename='邮件发送程序报错日志.log',
filemode='w')
todayDate = datetime.datetime.now().strftime("%Y-%m-%d")
str_email = input('请输入发件人邮箱:')
password = input('请输入发件人邮箱密码:')
sheet_name = input('请输入发送内容的类型(例如:排班考勤,社保公积金,等等):')
class Config():
def __init__(self):
# 发信方的信息:发信邮箱,QQ 邮箱授权码
self.from_addr = '%s' % str_email
self.password = '%s' % password
# 发信服务器
self.smtp_server = 'smtp.exmail.qq.com'
self.port = 465
email_conf = Config()
wd = tk.Tk()
wd.withdraw()
print('请选择需要拆分的数据')
data_path = filedialog.askopenfilename()
print('请选择需要发送邮件的名单表')
send_path = filedialog.askopenfilename()
pd_info = pd.read_excel(data_path, header=0)
title_names = [i for i in pd_info.columns.values]
all_index = list(set(i for i in pd_info[u'拆分项']))
if u'工号\\n(必填项)' in title_names:
pd_data = pd.read_excel(data_path, index_col=1, header=1, converters=u'工号\\n(必填项)': str)
pd_data = pd_data.fillna(value='')
pd_data.set_index(u'拆分项', drop=True, append=False, inplace=True)
elif u'员工编码' in title_names:
pd_data = pd.read_excel(data_path, index_col=1, header=1, converters=u'员工编码': str)
pd_data = pd_data.fillna(value='')
pd_data.set_index(u'拆分项', drop=True, append=False, inplace=True)
elif u'工号' in title_names:
pd_data = pd.read_excel(data_path, index_col=1, header=1, converters=u'工号': str)
pd_data = pd_data.fillna(value='')
pd_data.set_index(u'拆分项', drop=True, append=False, inplace=True)
elif u'证件号' in title_names:
pd_data = pd.read_excel(data_path, index_col=1, header=1, converters=u'证件号': str)
pd_data = pd_data.fillna(value='')
pd_data.set_index(u'拆分项', drop=True, append=False, inplace=True)
else:
pd_data = pd.read_excel(data_path, header=0)
pd_data = pd_data.fillna(value='')
# pd_data.set_index(u'拆分项', drop=True, append=False, inplace=True)
try:
pd_emails = pd.read_excel(send_path, sheet_name=u'邮箱配置', converters=u'邮件加密密码': str)
pd_emails = pd_emails.fillna(value='')
# pd_emails.set_index(u'拆分项', drop=True, append=False, inplace=True)
except:
logging.info('读取邮件发送表中邮箱配置表失败')
try:
pd_msg = pd.read_excel(send_path, sheet_name=u'邮件正文配置')
pd_msg = pd_msg.fillna(value='')
# pd_msg.set_index(u'拆分项', drop=True, append=False, inplace=True)
except:
logging.info('读取邮件发送表中邮箱配置表失败')
# excel加密或更换密码
def pwd_xlsx(old_filename, new_filename, pwd_str, pw_str=''):
'''
:param old_filename: 需要加密Excel, 绝对路径
:param new_filename: 加密后的Excel,绝对路径
:param pwd_str: 加密密码
:param pw_str: 打开文件密码,默认无密码
:return:无
'''
xcl = win32com.client.Dispatch("Excel.Application")
# pw_str为打开密码, 若无 访问密码, 则设为 ''
wb = xcl.Workbooks.Open(old_filename, False, False, None, pw_str)
xcl.DisplayAlerts = False
# 保存时可设置访问密码.
wb.SaveAs(new_filename, None, pwd_str, '')
xcl.Quit()
os.remove(old_filename)
# 邮件加密
def general_excel(data, department, sheet_name, pwd):
excel_path = os.path.join(os.getcwd(), '%s.xlsx' % department)
pwd_excel = os.path.join(os.getcwd(), '%s.xlsx' % (department + sheet_name + todayDate))
writer = pd.ExcelWriter(excel_path)
data.to_excel(writer, '%s' % sheet_name, index=False)
writer.save()
pwd_xlsx(excel_path, pwd_excel, pwd)
try:
os.remove(excel_path)
except Exception as e:
logging.info(e)
return pwd_excel
def send_email(address: list, cc_addr: list, pwd_excel: list, msg:str, pwd:str):
logging.info(" send_email working......")
# 邮件标题title
title = "%s" % sheet_name
# 邮件正文内容
text = "%s" % msg + '\\n' + "您的附件密码为:" + pwd
# # 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码
# msg = MIMEText(msg, 'plain', 'utf-8')
# 构建邮件体
msg = MIMEMultipart()
msg['From'] = email_conf.from_addr
msg['To'] = ','.join(address)
msg['Cc'] = ','.join(cc_addr)
msg['Subject'] = Header(title, 'utf-8')
# 构建正文
part_text = MIMEText(text)
msg.attach(part_text)
if len(pwd_excel) > 0:
for i in pwd_excel:
# 构建邮件附件
part_attach = MIMEApplication(open(i, 'rb').read()) # 打开附件
filename = i.split("\\\\")[-1]
part_attach.add_header('Content-Disposition', 'attachment', filename=filename) # 为附件命名
msg.attach(part_attach) # 添加附件
time.sleep(2)
# 开启发信服务,这里使用的是加密传输
# server = smtplib.SMTP_SSL()
server = smtplib.SMTP_SSL(host=email_conf.smtp_server)
server.connect(email_conf.smtp_server, email_conf.port)
try:
# 登录发信邮箱5
server.login(email_conf.from_addr, email_conf.password)
# 发送邮件
server.sendmail(email_conf.from_addr, address + cc_addr, msg.as_string())
logging.info("邮件发送成功,发件人:%s 收件人:%s " % (email_conf.from_addr, address + cc_addr))
print("邮件发送成功,发件人:%s 收件人:%s " % (email_conf.from_addr, address + cc_addr))
except Exception as err:
logging.info("邮件发送失败:%s" % (err))
exit()
finally:
# 关闭服务器
server.quit()
for path in pwd_excel:
os.remove(path)
def get_emails(emails):
if len(emails) > 5:
new_emails = emails.replace(';', ',').replace(';', ',').replace('。', ',').replace(',', ',')
email_list = new_emails.split(',')
lt_emails = [i for i in email_list if len(i) > 15]
return lt_emails
else:
lt_emails = []
return lt_emails
def get_index(index):
if len(index) >= 13:
new_index = index.replace(';', ',').replace(';', ',').replace('。', ',').replace(',', ',')
index_list = new_index.split(',')
lt_index = [i for i in index_list if len(i) >= 1]
return lt_index
else:
lt_index = []
return lt_index
def get_name(names):
if len(names) >= 3:
new_index = names.replace(';', ',').replace(';', ',').replace('。', ',').replace(',', ',').replace('、', ',')
index_list = new_index.split(',')
lt_name = [i for i in index_list if len(i) >= 1]
return lt_name
else:
lt_name = []
return lt_name
for item in all_index:
try:
pwd_excel = []
lt_emails = []
lt_cc_emails = []
item_data = pd_data[pd_data[u'拆分项'] == item]
item_email = pd_emails[pd_emails[u'拆分项'] == item]
pwd = pd_emails[pd_emails[u'拆分项'] == item].iat[0, 3]
msg = pd_msg[pd_msg[u'拆分项'] == item].iat[0, 1]
for i, row in item_email.iterrows():
try:
emails = row[u'收件人邮箱']
cc_emails = row[u'抄送人邮箱']
sd_emails = get_emails(emails)
sd_cc_emails = get_emails(cc_emails)
if sd_emails:
for em in sd_emails:
if em not in lt_emails:
lt_emails.append(em)
if sd_cc_emails:
for cc in sd_cc_emails:
if cc not in lt_cc_emails:
lt_cc_emails.append(cc)
except Exception as e:
logging.info(e)
pwd_file = general_excel(item_data, str(item), u'%s' % sheet_name, pwd)
pwd_excel.append(pwd_file)
if len(pwd_excel) > 0:
send_email(lt_emails, lt_cc_emails, pwd_excel, msg, pwd)
else:
pass
except Exception as e:
logging.info(e)
# break
以上是关于自动邮件发送(群发,加密等)的主要内容,如果未能解决你的问题,请参考以下文章