用Python批量发送email

本次项目我们需要使用Python自动提取Excel中的内容,并按照固定的邮件形式发送到自己的邮箱。

以下是我们要提取的Excel表格:

 最终得到的发送邮件形式为:

实现代码:

from openpyxl import load_workbook
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# 设置邮箱账号
account = input('请输入邮箱账户:')
# 设置邮箱授权码
token = input('请输入邮箱授权码:')
# 设置邮箱服务器,端口
smtp = smtplib.SMTP_SSL('smtp.qq.com', 465)
# 登录qq邮箱
smtp.login(account, token)

# 打开工作表
wb = load_workbook('./04_月考勤表.xlsx')
sheet = wb.active

# 编写正文内容
content = '四月的考勤表已出,其中迟到时长超出 45 分钟的人员如下:\n'
for row_data in sheet.iter_rows(min_row=2, values_only=True):
    # 获取迟到时长超过45分钟的人员
    if row_data[2] > 45:
        content += '姓名:{name} 迟到总时长:{time} \n'.format(name=row_data[1], time=row_data[2])
content += '详情见附件内容'

# 创建简单邮件对象
email_content = MIMEText(content, 'plain', 'utf-8')

# 读取工作表文件数据
with open('./04_月考勤表.xlsx', 'rb') as f:
    file_data = f.read()

# 设置内容类型为附件
attachment = MIMEText(file_data, 'base64', 'utf-8')
# 设置附件标题以及文件类型
attachment.add_header('Content-Disposition', 'attachment', filename='04_月考勤表.xlsx')

# 创建复合邮件对象
msg = MIMEMultipart()

# 添加正文到复合邮件对象中
msg.attach(email_content)

# 添加附件到复合邮件对象里
msg.attach(attachment)

# 设置发送者信息
msg['From'] = '陈知枫'
# 设置接受者信息
msg['To'] = '闪光金融的各位同事们' 
# 设置邮件标题
msg['Subject'] = '04_月考勤表'

# 发送邮件
smtp.sendmail(account, 'example@mail.com', msg.as_string())  
# 关闭邮箱服务
smtp.quit() 

 

功能拆解

其实这段代码和我们手工发电子邮件一样,主要包括三个步骤:

1)登录邮箱

2)新建并编辑邮件

3)发送邮件并关闭邮箱服务

其中,新建并编辑邮件又包括这三个步骤:① 设置正文内容;② 设置附件内容;③ 设置邮件内容及信息。

先来看看下面的流程图。

 

图中的每个功能块的实现思路如下:

1)登录邮箱:需要使用smtplib模块来连接服务器,登录邮箱账号。

2)设置正文内容:需要使用email模块创建MIMEText对象,读取表格内容,筛选迟到人员,编辑邮件内容文本。

3)设置附件内容:需要使用email模块再创建一个MIMEText对象,用以承载附件信息并添加入MIMEMultipart对象中。

4)设置邮件内容及信息:需要得到邮件对象(MIMEText/MIMEMultipart对象),并通过邮件对象来设置发件人、接收人、标题等信息。

5)发送邮件并关闭邮箱服务:需要使用smtplib模块发送邮件并退出。

 

我们这里只用到了两个模块:smtplib模块email模块

把上面的问题浓缩一下,那就只剩下两个问题:

1)如何使用smtplib模块,登录邮箱及发送邮件。

2)如何使用email模块,实例化MIMEMultipart/MIMEText对象,生成带附件的邮件内容。

发邮件的第一步当然是登录邮箱,但是Python发邮件和我们平时在网页上登录邮箱会有所不同,听我缓缓道来。

想通过代码登录邮箱发送邮件,就需要先了解一个概念:SMTP(简单邮件传输协议)

SMTP(简单邮件传输协议)

SMTP(简单邮件传输协议)是用于发送电子邮件的协议。规定电子邮件应该如何在邮件服务器之间传递。

总而言之,在点击发送邮件以后,它是计算机要处理的所有其他细节。

它就像一个官方的规则,用于控制信件的中转方式。

想要用Python发电子邮件,就必须学会smtplib模块,它是啥呢?

smtplib是Python的内置模块,它对SMTP协议进行了简单的封装,提供了一种发送电子邮件的方法。

那么问题来了,该如何使用这个模块,登录邮箱发邮件呢?

SMTP_SSL()

第一步,我们需要实例化模块smtplib中的类SMTP_SSL(),得到一个smtp对象

这个smtp对象就像给我们送邮件的邮差。你给他一些特定的命令后,他就会帮你完成邮件的发送等工作。

光说可能干巴巴的,直接给你瞧瞧怎么实例化得到smtp对象

smtp = smtplib.SMTP_SSL(host, port)

 

可以看到,这里我们需要传入两个参数:参数1:host(服务器地址),参数2:port(端口号)。

服务器地址,一般是公开的一个网站地址,相当于是该服务在互联网中的标识。

而端口号就好比一个通道,通向这个网站特定的一个服务。

只有获得了这两个信息,我们才可以通过Python正常的连接使用邮箱服务。

那如何获取邮箱服务器地址及端口号呢?接下来,请你跟着我一起做,取得自己邮箱的服务器地址及端口号。

以qq邮箱为例(看不清可以点击图片放大),在邮箱网页(https://mail.qq.com/)上点击【帮助中心】:

 然后在对应搜索框搜索smtp服务器。

 得到搜索结果以后,找到写有地址的那一框,一般是第一个。

由图可以看到:服务器地址:smtp.qq.com、端口号:465或587

注意】在传入服务器地址的时候需要加上单引号,以字符串的形式传入。

如果你不使用qq邮箱也可以直接百度:对应邮箱+smtp服务器,如:gmail smtp服务器,或在它对应的帮助中心找到服务器地址。

如果你使用qq邮箱的话,直接使用smtp.qq.com这个服务器地址就好了。

找到服务器地址及端口号信息以后,传入参数到SMTP_SSL()方法中。

login()

搞定了邮箱服务器地址及端口号的设置,接下来就要登录qq邮箱账号了,这里需要用到方法login()

通过smtp对象调用login()方法可以登录邮箱账号。

这就相当于你告诉了邮差你的邮箱账号信息,让他可以确定你是不是“qq邮局”的用户。

所以这里我们要传入两个参数:1.邮箱地址、2. 邮箱授权码

与登录密码不同,授权码是用于登录第三方客户端的专用密码,目的是防止你的邮箱密码泄露,造成信息泄露。

smtp.login('example@mail.com',授权码)

 如上面这行代码所示,第一个参数填邮箱地址,第二个填授权码。

Q 邮箱一般默认关闭SMTP服务,我们得先去开启它。

请打开qq邮箱( 登录QQ邮箱)并输入你的账号密码登录。

登录你的邮箱账号以后,点击位于顶部的【设置】按钮,在邮箱设置下选择【账户】。

 

 

 

 

 

 

4. 设置正文内容

简单邮件对象

构建邮件正文内容时,要用到email模块内的类:MIMEText,比对到网页邮件页面就是:

MIMEText()

编辑正文文本,我们需要实例化类MIMEText(),得到一个简单邮件对象

而简单邮件对象可以用来承载邮件内容,例如:正文文本、附件。

那么如何实例化MIMEText呢?来看下面的语法格式。

email_content = MIMEText(_text, _subtype, _charset)

实例化MIMEText()时,需要往括号内传入三个参数:参数1:_text 、参数2:_subtype、参数3:_charset,咱们一个个来看。

参数1:_text,意思就是内容。例如:构造正文时就是正文文本,构造附件时就是读取到的附件文件。

参数2:_subtype,意思是文本格式。构造正文内容时文本格式为'plain',而构造附件时文本格式为'base64'

参数3:_charset,意思是编码方式。此处采用'utf-8',它是电子邮件、网页及其他存储或传送文字的应用中,常常采用的编码。

 

此处,我们需要设置邮件的正文文本,那么对应的参数内容如下: 

 咱们来看看,这部分代码案例具体会是什么样的。

# 编辑邮件文本内容
content = '我是一封邮件的正文。'
# 将正文添加到邮件内容里
email_content = MIMEText(content, 'plain', 'utf-8')

像这样,输入对应的参数以后,我们就完成了一个简单邮件对象的实例化。

假如我们发送一篇只包括正文的邮件,那么现在就可以发出去了。

实例代码:

from openpyxl import load_workbook
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# 设置邮箱账号
account = input('请输入邮箱账户:')
# 设置邮箱授权码
token = input('请输入邮箱授权码:')
# 实例化smtp对象,设置邮箱服务器,端口
smtp = smtplib.SMTP_SSL('smtp.qq.com', 465)
# 登录qq邮箱
smtp.login(account, token)

content = ' welcome to China '
# 添加正文,创建简单邮件对象
email_content = MIMEText(content,'plain' ,'utf-8' )

# 设置发送者信息
email_content['From'] = '陈知枫'
# 设置接受者信息
email_content['To'] = '热爱学习的你'
# 设置邮件标题
email_content['Subject'] = '来自知枫的一封信'

# 发送邮件
smtp.sendmail(account, '1083425287@qq.com', email_content.as_string())
# 关闭邮箱服务
smtp.quit()

运行效果:

5. 设置附件内容

设置附件这一步,在网页上的位置,相当于点击了添加附件这个按钮。

 从代码的角度出发,设置附件内容分为三步:1)读取附件内容;2)设置内容类型为附件;3)设置附件标题及文件类型。

# 读取工作表文件数据
with open('./04_月考勤表.xlsx', 'rb') as f:
    file_data = f.read()

# 设置内容类型为附件
attachment = MIMEText(file_data, 'base64', 'utf-8')

# 设置附件标题以及文件类型
attachment.add_header('Content-Disposition', 'attachment', filename='04_月考勤表.xlsx')

上面是设置附件内容部分的代码,从代码出发,咱们一个个来看。

创建带附件的简单邮件对象

# 读取工作表文件数据
with open('./04_月考勤表.xlsx', 'rb') as f:
    file_data = f.read()

第一步是读取附件内容,即代码中的前三行代码,将读取到的内容赋给file_data。

因为这样,我们才可读取文件并在后续设置为附件。

第二步是设置内容类型为附件

# 设置内容类型为附件
attachment = MIMEText(file_data, 'base64', 'utf-8')

在这里,我们实例化得到一个MIMEText对象,并赋给变量attachment。实例化时需要传入三个参数。

还记得哪三个吗?给你五秒钟回想一下。

是msg内容,type文本类型,和charset编码格式。

这里msg内容为我们之前读取的工作表:file_data、编码格式为:utf-8(发送电子邮件常用)。

前面我们有说过,文本格式为附件时,会与正文有所不同,为:base64。

最后一步是设置附件标题及文件类型,使其能以邮件中附件的形式发送出去。

这里我们需要用到的方法是:add_header()。

# 设置附件标题以及文件类型
attachment.add_header('Content-Disposition', 'attachment', filename='04_月考勤表.xlsx')

其语法格式为:attachment.add_header('Content-Disposition','attachment',filename),此处attachment是我们实例化得到的简单邮件对象名称。

插入附件时,前面俩参数固定为:'Content-Disposition','attachment',其中filename是可以自己命名的,写什么名字,邮件中附件就显示什么名字。

如果不这么设置这几个参数的话,附件在邮件中就无法正常显示了,你收到的将会是一团乱码文件或无法收到附件。

6. 设置邮件内容及信息

欢迎来到流程图中的:设置邮件内容及信息功能块。

当我们邮件内容包括正文和附件的两个内容的时候,就需要实例化复合邮件对象。它可以用来装载多个简单邮件对象。

复合邮件对象

先从概念的角度来说,复合邮件对象可以由多个简单邮件对象组成。

而构建复合邮件内容时,要用到email模块下mime模块下模块中的类:MIMEMultipart()。

和简单邮件对象MIMEText()一样,我们需要对其实例化。

# 实例化复合邮件对象
msg = MIMEMultipart()

简单邮件对象(MIMEText对象),像一个物件,可以是一段文本,一个附件,可以单独作为邮件内容发出。

复合邮件对象(MIMEMultipart对象),像一个容器,由多个简单邮件对象组合而成,一起作为邮件内容发出。

当要发的邮件内容比较多样的时候,就需要用到复合邮件对象(MIMEMultipart对象),来承载多个简单邮件对象(MIMEText对象)一起打包发送。

对比到网页邮件中来看的话:

 

复合邮件对象就相当于是整个邮件的内容的组合,而两个简单邮件对象分别承载正文内容及附件。

attach()方法

如何将简单邮件对象,添加到复合邮件对象msg中呢?需要用到attach()方法。

来看看下面的代码,咱们首先实例化一个复合邮件对象:

# 编写正文内容
content = '我是一段正文'

# 实例化简单邮件对象
email_content = MIMEText(content, 'plain', 'utf-8')

# 实例化复合邮件对象
msg = MIMEMultipart()

# 添加简单邮件对象到复合邮件对象中
msg.attach(email_content)

 

其语法格式为:msg.attach(简单邮件对象),这样复合邮件对象里面就包含了一个简单邮件对象email_content。

对比到我们项目的代码来看看。

# 创建复合邮件对象
msg = MIMEMultipart()

# 添加正文到复合邮件对象中
msg.attach(email_content)

# 添加附件到复合邮件对象中
msg.attach(attachment) 

我们把之前编辑好的正文:email_content,附件:attachment,直接用attach()方法加入到复合邮件对象中就好了。

设置邮件信息

完成了邮件内容的编辑以后,咱们到了设置邮件信息这一步。

每一个邮件都需要有收件人、发件人、还有主题的信息。不能只有正文内容和附件。

前面我们把正文以及附件都放进了复合邮件对象这个大箱子里面。

# 实例化复合邮件对象
msg = MIMEMultipart()

# 设置发送者信息
msg['From'] = '陈知枫'
# 设置接受者信息。
msg['To'] = '闪光科技的同事们' 
# 设置邮件标题
msg['Subject'] = '04_月考勤表'

其中,msg['From']用于设置发送者信息、msg['To']用于设置接受者信息、msg['Subject']用于设置文件标题。

就像增加字典内的键值对一样,我们添加了'From'、'To'、'Subject'三个键,并赋予了一个具体的值。

那么这些值他们对应到在网页中邮件中的显示就是:

此外,例如简单邮件对象就是整个邮件的内容时,也可以对其设置发送者、接收者、邮件标题等信息。

举个例子,对象为单个文本或附件即单个简单邮件对象的时候,也是可以用'From'、'To'、'Subject'来设置邮件信息并发送的。

7. 发送邮件并关闭服务

要实现发送邮件及关闭邮箱服务,我们需要用到smtplib模块里面的两个方法:sendmail()、quit(),咱们一个个讲。

sendmail()

首先是sendmail(),它是smtplib模块中发送邮件的方法,下面是它的语法格式:

# 发送邮件
smtp.sendmail(from_addr, to_addrs, msg.as_string())

 

而对smtp对象调用sendmail()方法,需要传入三个参数:参数1:from_addr(发件邮箱地址)、参数2:to_addrs(收件邮箱地址)、参数3:msg.as_string()(邮件内容)。

msg是需要发送的邮件内容对象,可以是简单邮件对象也可以是复合邮件对象。

其中as_string()是将发送的信息msg变为字符串类型,记得在传输邮件时你也要用as_string()将邮件内容转化为字符串。

还记得在前面的练习曾要你修改其中第二个参数吗?因为那代表着收件人的邮箱地址。

来看看,项目中的这行代码是长什么样的吧。

# 发送邮件
smtp.sendmail(account, 'example@mail.com', msg.as_string())  

 

ok,终于到了最后一步了,关闭邮箱服务。

quit()

关闭邮件服务,需要用smtplib模块中的方法:quit()

对smtp对象调用quit()方法,无需传入参数即可直接关闭邮箱服务。

# 关闭邮箱服务
smtp.quit()

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mez_Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值