在实际工作中,我们常常会遇到定时发送邮件的任务,基于我的实践,分享给大家,也许一篇文章写不完,就先列个目录。
本文想要解决的问题:
用python构造一封邮件,并设置定时发送出去。往往,这只是最低级的需求,实际工作中会有各种细节和附加条件。
学会构造文本、HTML两种格式的邮件正文,学会构造和添加附件,其中,HTML格式要学会使用超链接,学会添加CSS用来美化正文。
将Dataframe格式的表格直接转化为HTML格式的表格,如果有超链接,要学会更改超链接,使之能完全显示,并在HTML正文显示对应的连接内容(比如显示连接的图片)。
1. 初步学会使用python编写发送邮件的脚本
关于python发邮件的类似文章有很多,不过,作为初学者,依然有许多需要注意的细节,如果作者没有写清楚的话,是很容易让人抓狂的。
由于2020年官方就停止更新和支持python2,所以本文顺应大势,使用的python3.6
1. python库
email库,用来编辑邮件内容的,包括标题,发件人,接收人,正文等。
smtplib库,用来发送邮件的,包括创建邮件服务,登陆,发送,退出等动作
一般来说,我是做如下导入,每一个模块都有相应的说明,具体应用继续看后面的内容。
# 导入相关库-email
from email.mime.multipart import MIMEMultipart # 构建邮件头信息,包括发件人,接收人,标题等
from email.mime.text import MIMEText # 构建邮件正文,可以是text,也可以是HTML
from email.mime.application import MIMEApplication # 构建邮件附件,理论上,只要是文件即可,一般是图片,Excel表格,word文件等
from email.header import Header # 专门构建邮件标题的,这样做,可以支持标题中文
import smtplib
2. 发送一个最简单的hello word的邮件(有重点)
发件人信息(重点)
这一小节的重点,也是很多小白容易犯糊涂的地方,就是发件人的账号和密码,以及相应的邮件服务器设置。不同的邮箱,其规则完全不一样,如果你有企业邮箱,那最好用企业邮箱,这点要记住,因为个人邮箱很容易出现网络问题、触发反垃圾机制等等,这是实践的出来的经验。另外,如果你使用过Foxmail、outlook等第三方邮件服务器,那你就更容易理解了。
上面箭头所指,就是163个人邮箱的发件服务器
上面箭头所指,就是163个人邮箱的发件服务器:smtp.163.com,如果是163的企业邮箱,其服务器地址则是:smtp.ym.163.com,我就是用的这个。
下面我要将的内容很关键:163个人邮箱的密码,不是登陆密码,而是客户端授权码,如下图所示:
image.png
我们这里是属于使用SMTP服务登陆和发送邮件的,所以使用常规的登陆密码,是无法发送邮件的。
然而,163的企业邮箱,却没有这个选项,直接使用登陆密码就可以发送邮件(我一直没明白为什么不一样,也许企业邮箱默认的就是开通了这些服务的,给我们的密码也即是授权码)。
常见的qq邮箱,谷歌邮箱,雅虎邮箱都是有这些区别的,新手一定要注意。下面就是我发送邮件的账号的密码设置,大家可以参照一下,不懂的直接在评论区@我:
# 邮件服务信息,个人
# smtp_server = 'smtp.163.com'
# username = "lihua.0221@163.com"
# password = 'xxxxxx' # 授权码,并不是邮箱登陆密码
# 邮件服务信息,公司
smtp_server = 'smtp.ym.163.com'
username = "lihua@everimaging.com"
password = 'xxxxxxxxx' # 授权码,企业163的就是登陆密码
这些信息,我们在构建邮件的发件人的时候需要用到,在使用SMTP发送邮件的时候也会用到,所以,一开始就给出来。
构建邮件正文
# 邮件发送和接收人
sender = username
receiver = ['lihua@everimaging.com', '724694053@qq.com']
# 邮件头信息
msg = MIMEMultipart('related')
msg['Subject'] = Header("我的第一封python邮件")
msg["From"] = sender
msg['To'] = ','.join(receiver) # 这里要注意
# text 内容
content_text = MIMEText("Hello World", "text", "utf-8")
msg.attach(content_text)
可以看到,这一节没有什么难点,先是定义发送者和接收人,然后使用MIMEMultipart类构建一个消息体msg,然后定义msg中的主题,发件人,接收人。其中,主题使用了Header类封装,目的是为了支持中文,最后,添加一段text的正文“hello world”,使用的是MIMEText类封装,第一个参数代表内容,第二个参数代表类型是text,另外还有html类型可选,下节介绍,最后一个参数是定义编码。
这里面只有一个地方需要注意,那就是msg['To'] = ','.join(receiver)这里,我们的邮件接收人是可以很多人的(列表),但是还需要用逗号把它们连接成一个字符串(email库的bug),如果是直接将列表扔给它,是要出错的。
发送邮件
# 发送邮件,测试成功,流程都是固定