1. 情境问题
康康是一名销售经理,每到新产品上线的时候,他一天需要发送上千封关于新产品介绍的邮件给潜在的用户。
因为每个邮箱账号一天发送邮件的数量
和单次群发邮件的数量
都有上限,所以他就需要每个发件邮箱账号发送多次,并切换多个发件邮箱账号才能完成邮件群发工作。
不同的发件邮箱账号的限制不同,为了便于理解与实操,本案例假设康康一天需要发送 9 封邮件,一个发件邮箱账号一天最多发送 6 封,单次群发邮件最多 3 封,图片示例以 qq 邮箱为例。
单次发送成功结果如下图:
实现这个结果,他首先需要添加收件人邮箱,再填写正文文本
、主题
以及上传附件【新产品介绍.pdf】,最后点击发送。
2. 问题分析
工作目标
通过切换多个发件邮箱账号,每个发件邮箱账号发送多次,把固定的邮件内容发送到【客户名单.xlsx】工作簿上的所有客户邮箱账号。
平时他都是手动操作完成,具体的步骤是这样的:
手动操作
运用 Python 代码帮助他实现工作目标 👇:
通过切换多个发件邮箱账号,每个发件邮箱账号发送多次,把固定的邮件内容发送到【客户名单.xlsx】工作簿上的所有客户邮箱账号。
2.1 取余
即取余数,就是两个数相除,取出不能整除的多出来的那部分,使用%
运算符。
例如老师要把 11 个苹果平均分给 5 个小朋友,先给每个小朋友分 2 个,总共分了 10 个,还剩多余的 1 个无法分配,这多出来的 1 个就是余数。
总的来说,取余
的使用是这样的,你需要注意:
2.2 取整
这里指向下取整,即两个数相除的结果不为整数,取小于计算结果的整数,使用//
运算符。
例如生产 1 辆自行车需要 2 个车轮,现有 5 个车轮,5 除以 2 算出可以生产 2.5 辆自行车,但实际上自行车必须具备完整的 2 个车轮,生产的自行车数量只能取小于 2.5 的整数 2,这就是向下取整
。
总的来说,取整
的使用是这样的,你需要注意:
代码实现:
# 案例 10:群发推广邮件
from openpyxl import load_workbook
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 设置邮箱服务器,端口
smtp = smtplib.SMTP_SSL('smtp.qq.com', 465)
# 设置正文内容
content = '''
您好!
附件中为天变公司新产品的介绍,您注意查阅,有什么问题请随时联系!
'''
email_content = MIMEText(content, 'plain', 'utf-8')
# 读取附件【新产品介绍.pdf】文件数据
with open('../工作/新产品介绍.pdf', 'rb') as f:
file_data = f.read()
# 设置内容类型为附件
attachment = MIMEText(file_data, 'base64', 'utf-8')
# 设置附件标题以及文件类型
attachment.add_header('Content-Disposition',
'attachment', filename='新产品介绍.pdf')
# 创建发件邮箱账号列表
mail_list = [
{'email': 'xxx@qq.com', 'token': 'xxx'},
{'email': 'xxx@qq.com', 'token': 'xxx'},
]
# 获取【客户名单】工作表
wb = load_workbook('../工作/客户名单.xlsx')
sheet = wb.active
# 创建客户邮箱账号列表
costumer_list = []
# 遍历【客户名单】工作表中数据
for row in sheet.iter_rows(min_row=2, values_only=True):
# 将数据写入客户邮箱账号列表中
costumer_list.append(row[3])
# 获取客户邮箱账号数量
costumer_num = sheet.max_row - 1
# 判断客户邮箱账号数量除以6余数是否大于0
if costumer_num % 6 > 0:
# 如果判断大于0,发件邮箱账号个数等于客户邮箱账号数量整除6的值加1
account_num = (costumer_num // 6) + 1
else:
# 否则,发件邮箱账号个数等于客户邮箱账号数量整除6的值
account_num = costumer_num // 6
# 循环发件邮箱账号个数
for mail_count in range(account_num):
# 取出发件邮箱账号的邮箱和授权码
email = mail_list[mail_count]['email']
token = mail_list[mail_count]['token']
# 从客户邮箱账号列表中取出单个发件邮箱账号需要发送的客户邮箱账号
receiver_list = costumer_list[mail_count * 6: (mail_count + 1) * 6]
# 判断单个发件邮箱账号需要发送的客户邮箱账号数量除以3余数是否大于0
if len(receiver_list) % 3 > 0:
# 如果判断大于0,单个发件邮箱账号需要发送的次数等于单个发件邮箱账号需要发送的客户邮箱账号数量整除3的值加1
send_times = (len(receiver_list) // 3) + 1
else:
# 否则,单个发件邮箱账号需要发送的次数等于单个发件邮箱账号需要发送的客户邮箱账号数量整除3的值
send_times = len(receiver_list) // 3
# 循环单个发件邮箱账号需要发送的次数
for i in range(send_times):
# 取出单次发送的客户邮箱账号
receivers = receiver_list[i * 3:(i + 1) * 3]
# 登录发件邮箱账号
smtp.login(email, token)
# 设置邮件内容
msg = MIMEMultipart()
# 设置发送人、收件人、邮件主题
msg['From'] = email
msg['To'] = '尊敬的客户'
msg['Subject'] = '新产品介绍'
# 将正文内容添加到邮件内容里
msg.attach(email_content)
# 将附件添加到邮件内容里
msg.attach(attachment)
# 发送邮件
smtp.sendmail(email, receivers, msg.as_string())
# 关闭邮箱服务
smtp.quit()
注意:代码中的email是我们的发件邮箱,token后对应的是发件邮箱的授权码。
运行结果:
本案例假设康康一天需要发送 9 封邮件,一个发件邮箱账号一天最多发送 6 封,单次群发邮件最多 3 封。
但是,在实际场景中需要发送的邮件数可能是上千封,发件邮箱账号的限制也不同。
例如,一个发件邮箱账号一天最多发送 500 封,单次群发最多 100 封,这就需要你去取修改代码中对应位置的数字。