1. 前言

1.1 应朋友要求,写一个群发邮件的脚本,用来实现往每个人的邮箱里边发送自己的工资条

2. 数据格式,最后一列是邮箱地址

3. 脚本实现的功能

3.1 自定义邮件标题

3.2 记录发送成功或失败的个数,防止发送失败

4. 代码实现

# -*- coding: utf-8 -*-
# @Time : 2021/3/26 10:11
# @Author : liyf--95/02/02
# @File : send_email.py
# @Software: PyCharmimport xlrd
import time
import re
from email.mime.text import MIMEText
from smtplib import SMTP_SSLfrom loguru import logger# qq邮箱smtp服务器
host_server = 'smtp.qq.com'
# sender_qq为发件人的qq号码
sender_qq = '123456@qq.com'
# 第三方客户端登录时需要的授权码,不是qq密码
pwd = 'xxxxxxxxxxxxx'
# 发件人的邮箱
sender_qq_mail = '123456@qq.com'
# 获取当前月份
batch = time.strftime("%Y-%m", time.localtime())suffix = time.strftime("%Y%m", time.localtime())
# ssl登录
smtp = SMTP_SSL(host_server)
# set_debuglevel()是用来调试的。参数值为1表示开启调试模式,参数值为0关闭调试模式,
smtp.set_debuglevel(0)
smtp.ehlo(host_server)
smtp.login(sender_qq, pwd)def get_success_error_counts():"""用来读取日志文件中的数据,并转成列表形式,方便调用该函数处理列表中的数据,用来做去重处理:return: 列表"""success_email_list = []try:with open(f'success_log_{suffix}.txt', 'r', encoding='utf8') as f:results = f.readlines()for res in results:success_email_list.append(res.strip())except Exception:logger.error(f'success_log_{suffix}.txt 文件不存在,初始化列表为0!')success_email_list = success_email_listerror_list = []try:with open(f'error_log_{suffix}.txt', 'r', encoding='utf8') as f:results = f.readlines()for res in results:restr = res.strip()email = re.findall(re.compile(r"email': '(.*?)', '", re.S), restr)[0]error_list.append(email)except Exception:error_list = error_listreturn success_email_list, error_listdef read_excel(subject):"""读取excel数据:param subject: 自定义的邮件标题:return:"""workbook = xlrd.open_workbook('工资条2.xlsx')worksheet = workbook.sheet_by_index(0)nrows = worksheet.nrows# 定义一个空列表,用来存放每一个员工的数据,包括表头total_list = []for i in range(nrows):data_list = worksheet.row_values(i)if data_list[0] == '':passelse:total_list.append(data_list)logger.info(f'数据读取完毕,共有 {len(total_list) - 1} 位同事')logger.info('------------------------------------------------------------')time.sleep(2)for k, v in enumerate(total_list[1:]):msg_content = ''for i, j in enumerate(v):if total_list[0][i] == '邮箱':passelse:# 有一些列的数据为空,处理数据val = '无' if str(v[i]).strip() == '' else v[i]msg = f'#     {total_list[0][i]}:{val}\n'msg_content += msgname = v[0]email_addr = v[-1]success, error = get_success_error_counts()logger.info(f'正在向第 {k + 1}/{len(total_list) - 1} 位同事 {name} 发送邮件,请稍等...')if len(success) == 0:# 说明日志中没有数据,即还没有发送成功的例子# 开始发送数据email_content = f'尊敬的 {name} 同事,您好,您的 {batch} 月份工资单信息如下:\n{msg_content}#     发送时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}'send_email_to_member(email_addr, email_content, name, subject)logger.info(f'已发送至邮箱:{email_addr},接收人:{name}')else:# 已经有发送成功的例子,并已存入success_log.txt文件中email_list = []  # 用来存放success_log.txt文件中的邮箱地址,用来去重for data in success:email_list.append(str(data).split('---->')[-1])if email_addr in email_list:# 如果需要发送邮件的邮箱地址在success_log.txt文件中,则说明该邮箱已经发送过,无需重复发送logger.warning(f'{name} 同事:{email_addr} 已经发送过了,无需重复发送邮件!!')passelse:# 正常发送邮件email_content = f'尊敬的 {name} 同事,你好,您的 {batch} 月份工资单信息如下:\n{msg_content}#     发送时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}'send_email_to_member(email_addr, email_content, name, subject)logger.info(f'已发送至邮箱:{email_addr},接收人:{name}')logger.info('------------------------------------------------------------')logger.info(f'脚本运行结束!等待5分钟后自动关闭窗口(或者手动点击窗口右上角关闭)!!!')logger.info('运行结果:')logger.info(f'{len(total_list) - 1} 位同事已全部发送完毕')success, error = get_success_error_counts()logger.info(f'Successd:{len(success)},Failed:{len(error)}')time.sleep(300)def send_email_to_member(email_addr, email_content, name, subject):"""发送邮件:param email_addr: 收件人邮箱地址:param email_content: 需要发送的正文内容:param name: 收件人姓名:return:"""msg = MIMEText(email_content, "plain", 'utf-8')msg["Subject"] = subject  # 邮件标题msg["From"] = sender_qq_mail  # 发件人msg["To"] = email_addr  # 收件人邮箱try:smtp.sendmail(sender_qq_mail, email_addr, msg.as_string())smtp.quit()msg = f'{name} 发送成功,时间: {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}---->{email_addr}'with open(f'success_log_{suffix}.txt', 'a', encoding='utf8') as f:f.write(msg)f.write('\n')f.close()time.sleep(0.5)except Exception as e:logger.error(f'发送失败--->{name}\n原因:{e}')item = {}item['name'] = nameitem['email'] = email_addritem['error_reason'] = eitem['date'] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())with open(f'error_log_{suffix}.txt', 'a', encoding='utf8') as f:f.write(str(item))f.write('\n')f.close()if __name__ == '__main__':subject = input('请输入自定义邮件标题:')logger.info(f'自定义邮件标题为:{subject}')read_excel(subject)

5. 逻辑梳理

5.1 该脚本的使用qq邮箱发送,其中获取授权码可以 点击这里参考博客

5.2 注意事项

5.2.1 excel名称必须为 `工资条2.xlsx`

5.2.2 `邮箱` 列必须为最后一列,`姓名` 列必须在第一列,因为代码中 `name=v[0], email_addr=v[-1]` 是固定的。可以自己做适当修改

5.2.3 表头名称可以随意改动,列数也可以随意增减,但要保证 `邮箱` 和 `姓名` 列存在

6. success_log_202103.txt 和 error_log_202103.txt 的作用

6.1 success_log_202103.txt

6.1.1 用来记录发送成功的数据

6.1.2 发送邮件之前,会先读取该txt文件,并判断要发送的email地址是否在txt里边,如果存在,则不发送,防止重复发送

6.2 error_log_202103.txt

6.2.1 一般情况下,没有这个文件,但是由于一些不可控因素,比如邮箱地址不存在或者断网等,会导致发送邮件失败

6.2.2 发送失败之后会把当前发送的数据记录下来,就会生成这个文件

6.2.3 如果该文件有数据,则首先检查是否是邮箱不正确导致的,如果不是,重新运行exe文件

7. 测试

7.1 使用 `pyinstaller -F send_email.py` 打包 py 文件为 exe 可执行文件

7.2 运行截图

7.3 邮件内容

python群发邮件相关推荐

  1. Python案例笔记 | 用python群发邮件

    基于Python3版本的学习. 学习知识来源:风变编程 要用python群发邮件,需用到两个python的内置模块. smtplib模块 是用来发送邮件用的. email模块 是用来构建邮件内容的. ...

  2. python群发邮件_python smtp 群发邮件

    最近工作中遇到使用脚本处理问题并发送结果邮件,使用python的smtp模块很简单的完成了实现.今天遇到一个问题,根据脚本的测试结果需要群发邮件,但是发送邮件的py文件只有首个地址收到了邮件.仔细排查 ...

  3. python群发邮件并将excel附件添加到正文

    本文几个目的: 1.使用smtp库群发邮件 2.添加邮件的附件 3.将Excel附件添加到正文中 """ to_addr表示群发集,使用形如('abc.163.com,a ...

  4. Python群发邮件,根据excel内容。

    Python读取excel表中的工资内容,实现工资群发邮件. 前言 目的:读取excel数据中的每个人工资情况,根据每个人的邮箱,实现群发邮件的功能. 参考:廖雪峰 一.准备工作(QQ邮箱为例) 1. ...

  5. python群发邮件1000人-python读取excel群发邮件(一)

    编写背景: ========================= 目前公司的福利饭补是是人力邮件发送的,每个人需要手动对应的发一遍相应的数据,没研究过outlook是否有读取excel群发邮件的功能,看 ...

  6. python群发邮件 不进垃圾箱_实战邮箱群发2000封邮件不进垃圾箱

    作为站长,邮件营销推广是一个比较好的推广工具,而且也是一个相对传统的营销工具,但是并没有过时.运用得好,效果还是很不错得,而且成本相对来说也很非常低的,很适合草根站长前期的推广. 但是我们平时在操作邮 ...

  7. 用Python群发邮件

    我们需要将[小组销量排名表.xlsx]通过邮件发送给[组长邮箱.xlsx]中的各个组长. 这里会学一个新的知识点--str.join(),通过它实现群发邮件的功能. 2 群发邮件 from openp ...

  8. python 群发邮件数量限制_群发邮件-python学习30

    群发邮件 以下是群发邮件的三种思路: 群发邮件 一,是将收件人信箱的变量设置成一个可以装多个内容的列表: 直接运行程序的话,这里就会发生错误:AttributeError: 'list' object ...

  9. 用python群发邮件_使用Python实现电子邮件群发功能

    原标题:使用Python实现电子邮件群发功能 在某些应用中,可能会需要由管理员给所有用法群发电子邮件,或者类似的应用.本文代码使用Python详细模拟了这个过程. importemail fromem ...

  10. python群发邮件 不进垃圾箱_实战干货:邮箱群发2000封邮件如何做到不进垃圾箱...

    原标题:实战干货:邮箱群发2000封邮件如何做到不进垃圾箱 重点导读 很多人认为邮件营销是非常古老的网络营销手段,已经没有多少人在用了.但是有时候招不用新,管用就好. 我们平时在操作邮件群发的时候,大 ...

最新文章

  1. 多个数字数组_七个问题帮助初学者深入理解Java数组
  2. 利用ioctl获取本机指定设备的MAC地址
  3. 中断请求request_irq
  4. java对象怎么创建_java对象是怎么创建出来的
  5. Spring MVC+Spring+Mybatis+MySQL(IDEA)入门框架搭建
  6. gnome桌面环境 kde桌面环境的区别
  7. java斗地主怎么出牌_斗地主滑动选牌出牌(Cocos Creator)
  8. chrome devTool
  9. 如何高效率的学习Web前端,个人经验分享
  10. Java程序员面试学习资料汇总
  11. 筋斗云接口编程 / 常用操作(二)
  12. 解决Office 2003 Word无法正常启动
  13. Drf从入门到精通一(API接口、Postman、Restful规范、序列化、快速使用drf、CBV源码分析)
  14. 快学Python:函数的使用
  15. arm汇编lr pc b bl ret指令函数调用和返回gif动图演示
  16. 相机数据恢复软件使用办法
  17. Bootstrap重抽样方法
  18. QNX修改程序最终生成的名字
  19. 回头再说--跳蚤效应
  20. SqlSession 同步为注册,因为同步未激活

热门文章

  1. 速率bps(kbps、Mbps)和每秒字节传输B/s(KB/s、MB/s)的关系如下
  2. 韩国appleid17+认证流程
  3. iphone手机如何修改Apple ID密码
  4. 前沿重器[4] | 腾讯搜索的Quer理解如何直击心灵
  5. Windows Message ID
  6. TIJ阅读笔记(第十四章)[转]
  7. Re: 一个公司如何才能留住员工呢?
  8. 院校-美国:麻省理工学院(MIT)
  9. ALC662 在Mac中的安装
  10. 很好听的曲子《红枣树》,歌词写的很好,摘抄一下