上一篇关于邮件的自动发送教程中,我们讲解了如何使用yagmail进行简单的邮件发送。
现实生活中,如果只是发邮件给自己,像上一篇文章那样简陋的格式是可以接受的,但若要针对每个人进行邮件的定制化,群发给公司客户、内部员工、亲戚朋友,则需更加高级的邮件发送方式。
我们可以通过HTML制作一封精美的元旦祝福邮件,但是邮件的内容——比如姓名、祝福语等应该怎样动态渲染呢?答案是jinja2.
jinja2 是一个Python 的模板引擎,使用jinja2,我们能够在邮件HTML中设定占位符,在Python发送邮件的时候,将指定文本渲染到该占位符中,实现动态渲染的目的。
比如举一个jinja2的简单例子:
from jinja2 import Template name = 'Peter' age = 34 tm = Template("My name is {{ name }} and I am {{ age }}") msg = tm.render(name=name, age=age) print(msg)
使用 {{}} 圈起来的是占位符,称之为模板字符串。模板字符串呈现两个变量:名称和年龄,在这个例子中,硬编码了name和age的值传入模板,得到输出:
My name is Peter and I am 34
在本篇文章中,我将教大家如何通过Html及Python+jinja2给你的好友们定制元旦祝福邮件。
本文所有素材及源代码均可以在此下载:
https://pythondict.com/download/python-new-year-mail/
或Python实用宝典公众号回复:元旦邮件 直接拿到网盘下载链接。
1.准备
开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。
如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.
此外,推荐大家用VSCode编辑器,因为它实在是太方便了:Python 编程的最好搭档—VSCode 详细指南
Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),准备开始输入命令安装依赖。
pip install jinja2 pip install yagmail
2.编写HTML
将需要发送的邮件模板的HTML编写好。并将占位符变量提前写入HTML中。由于我的HTML文件过大,这里就不完全展示了,只展示几个关键变量。
为简化教程的复杂度,并尽可能覆盖到知识点,这里我们使用4个变量:
1.LOGO图片(让你更好地理解图片是如何渲染到HTMl里并发邮件)
2.背景图片
3.祝福对象
4.祝福语言
首先,是图片变量的配置:
<tr> <td valign="left" width="50%" class="logo sub-gd" style="padding-left:0;"> <h1> <img src="data:image/png;base64, {{pythondict_img}}"> </h1> </td> </tr>
由于我们需要发送html形的邮件,因此像代码这样将图片转码为base64再发送是最方便的。
其中,base64部分用jinja2语法 {{}} 包起来,中间就是变量名,一会render渲染的时候就会将base64渲染进来。
背景图片的配置比较特殊,使用 base64 渲染的话QQ邮箱会自动过滤为#号,因此必须使用url的形式:
<td valign="middle"style="background-image: url({{backgroud}});">
其次是祝福对象和祝福语言的配置:
<h2> {{name}} <br> 祝您2021年元旦快乐 </h2> <p> {{bless}}. </p>
使用 {{}} 包裹变量,name是祝福的对象,bless是祝福语。这里简化了代码,还有许多样式要配置详细的大家可以看源代码中的 index_detail.html.
对了,我们源代码里包括两份html,一份是 index_detail.html 是未经过压缩的源代码,还有一份是 index.html,是被压缩过的源代码。
为什么要压缩HTML呢?因为邮箱客户端在解析HTML的时候,有可能会将换行符解析成<br>,因此压缩HTML不保留任何空格和换行符是最保险的做法。
详细的HTML代码,大家可以看源代码中的 index_detail.html.
3.Python代码
发送邮件的方法,我们在Python 自动发送邮件详细教程中已经详细地讲过了:
class Mail: """ 邮件相关类 """ def log(self, content): now_time = time.strftime( "%Y-%m-%d %H:%M:%S", time.localtime() ) print(f'{now_time}: {content}') def sendmail(self, html, title, receivers): """ 发送邮件 Arguments: html {str} -- 邮件正文(html) title {str} -- 邮件标题 receivers {list} -- 邮件接收者,数组 """ yag = yagmail.SMTP( host='您的邮箱SMTPHOST', user='您的邮箱', password='您的邮箱密码', smtp_ssl=True ) yag.send(receivers, title, html) self.log("邮件发送成功")
此外,为了渲染图片,需要将图片转化为base64,这个方法是这样的:
def get_image_base64(path): """ 获得图片的base64编码 Args: path (str): 图片路径 Returns: str: base64编码 """ import base64 f = open(path, "rb") base64_data = base64.b64encode(f.read()) f.close() return base64_data.decode("utf-8")
当然,最重要的地方是下面,需要针对每个人定制祝福语,我们可以采用字典的数据结构来保存数据:
bless_info = { "admin@pythondict.com": { "pythondict_img": get_image_base64("./images/pythondict.png"), "name": "实用宝典", "background": "https://背景图片.jpg", "bless": "愿所有的幸运与您不期而遇..", "title": "祝宝典哥明年粉丝破十万" }, "test@qq.com": { "pythondict_img": get_image_base64("./images/pythondict.png"), "name": "老王", "background": "https://背景图片.jpg", "bless": "祝您女儿明年考研顺顺利利,全家幸福安康..", "title": "老王,祝您元旦快乐!" }, }
可以看到 bless_info 字典里的每个key是发送对象的邮箱,而这些 key 对应的value 中就有需要渲染到邮件的变量: pythondict_img, name, background 及 祝福语bless. 最后一个变量title,是用于指定邮件标题的。
这样,渲染+发送邮件做起来就方便多了:
tm = Template(open('./index.html', encoding="utf-8").read()) for mail in bless_info: msg = tm.render(bless_info[mail]) Mail().sendmail(html=msg, title=bless_info[mail]["title"], receivers=[mail])
Mail().sendmail():是我们的发送邮件函数,应该不必多说。
bless_info[mail]:是需要渲染的变量,这里面的变量少了可不行,多了没关系。
bless_info[mail][“title”]:就是刚刚在字典里指定的最后一个变量 title,
由于 sendmail() 函数里的 receivers 是支持多人的,因此这里需要以数组的形式传入函数。
不过这里还有一个有趣的改进,如果你需要用同一个模板邮件发送给同一家人,你可以这么做:
bless_info = { ..., "test1@qq.com,test2@qq.com,test3@qq.com": { "pythondict_img": get_image_base64("./images/pythondict.png"), "name": "老王一家", "background": "https://背景图片.jpg", "bless": "祝王小女明年考研顺顺利利,老王全家幸福安康,吉祥如意..", "title": "老王一家,祝你们元旦快乐!" }, } tm = Template(open('./index.html', encoding="utf-8").read()) for mail in bless_info: msg = tm.render(bless_info[mail]) Mail().sendmail(html=msg, title=bless_info[mail]["title"], receivers=mail.split(","))
没错,只需要在key里将这一家人的邮箱用逗号分隔开,然后receivers里改为mail.split(“,”),你就能实现同一份邮件发给一家人的功能,是不是非常方便?
大家可以自己找喜欢的背景图片,也可以用我在代码里已给大家提供的图片。想要去除LOGO的话,直接将pythondict_img设为空,或者设为你自己的卡片即可。
在源代码目录下运行代码:
python mail.py
即可成功发送邮件,快打开编辑器试一下吧(记得先测试)!
我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。
有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。
原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!
Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典
评论(0)