現(xiàn)實(shí)生活中,如果只是發(fā)郵件給自己,像上一篇文章那樣簡(jiǎn)陋的格式是可以接受的,但若要針對(duì)每個(gè)人進(jìn)行郵件的定制化,群發(fā)給公司客戶、內(nèi)部員工、親戚朋友,則需更加高級(jí)的郵件發(fā)送方式。
我們可以通過HTML制作一封精美的元旦祝福郵件,但是郵件的內(nèi)容——比如姓名、祝福語等應(yīng)該怎樣動(dòng)態(tài)渲染呢?答案是jinja2.
jinja2 是一個(gè)Python 的模板引擎,使用jinja2,我們能夠在郵件HTML中設(shè)定占位符,在Python發(fā)送郵件的時(shí)候,將指定文本渲染到該占位符中,實(shí)現(xiàn)動(dòng)態(tài)渲染的目的。
舉一個(gè)jinja2的簡(jiǎn)單例子:
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)
使用 {{}} 圈起來的是占位符,稱之為模板字符串。模板字符串呈現(xiàn)兩個(gè)變量:名稱和年齡,在這個(gè)例子中,硬編碼了name和age的值傳入模板,得到輸出:
My name is Peter and I am 34
在本篇文章中,我將教大家如何通過Html及Python+jinja2給你的親朋好友們定制元旦祝福郵件。
1.準(zhǔn)備
開始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上,如果沒有,請(qǐng)?jiān)L問這篇文章:超詳細(xì)Python安裝指南 進(jìn)行安裝。
如果你用Python的目的是數(shù)據(jù)分析,可以直接安裝Anaconda:Python數(shù)據(jù)分析與挖掘好幫手—Anaconda,它內(nèi)置了Python和pip.
此外,推薦大家用VSCode編輯器,因?yàn)樗性S多許多的優(yōu)點(diǎn):Python 編程的最好搭檔—VSCode 詳細(xì)指南。
準(zhǔn)備輸入命令安裝依賴,如果你沒有VSCode編輯器,Windows環(huán)境下打開 Cmd (開始-運(yùn)行-CMD),蘋果系統(tǒng)環(huán)境下請(qǐng)打開 Terminal (command+空格輸入Terminal),如果你用的是VSCode編輯器或Pycharm,可以直接在下方的Terminal中輸入命令:
pip install jinja2
pip install yagmail
2.編寫HTML
將需要發(fā)送的郵件模板的HTML編寫好。并將占位符變量提前寫入HTML中。由于我的HTML文件過大,這里就不完全展示了,只展示幾個(gè)關(guān)鍵變量。
為簡(jiǎn)化教程的復(fù)雜度,并盡可能覆蓋到知識(shí)點(diǎn),這里我們使用4個(gè)變量:
1.LOGO圖片(讓你更好地理解圖片是如何渲染到HTMl里并發(fā)郵件)
2.背景圖片
3.祝福對(duì)象
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 >
由于我們需要發(fā)送html形的郵件,因此像代碼這樣將圖片轉(zhuǎn)碼為base64再發(fā)送是最方便的。
其中,base64部分用jinja2語法 {{}} 包起來,中間就是變量名,一會(huì)render渲染的時(shí)候就會(huì)將base64渲染進(jìn)來。
背景圖片的配置比較特殊,使用 base64 渲染的話QQ郵箱會(huì)自動(dòng)過濾為#號(hào),因此必須使用url的形式:
< td valign="middle"style="background-image: url({{backgroud}});" >
其次是祝福對(duì)象和祝福語言的配置:
< h2 >
{{name}}
< br >
祝您2021年元旦快樂
< /h2 >
< p >
{{bless}}.
< /p >
使用 {{}} 包裹變量,name是祝福的對(duì)象,bless是祝福語。這里簡(jiǎn)化了代碼,還有許多樣式要配置詳細(xì)的大家可以看源代碼中的 index_detail.html .
對(duì)了,我們?cè)创a里包括兩份html,一份是 index_detail.html 是未經(jīng)過壓縮的源代碼,還有一份是 index.html,是被壓縮過的源代碼。
為什么要壓縮HTML呢?因?yàn)猷]箱客戶端在解析HTML的時(shí)候,有可能會(huì)將換行符解析成
,因此壓縮HTML不保留任何空格和換行符是最保險(xiǎn)的做法。
詳細(xì)的HTML代碼,大家可以看源代碼中的 index_detail.html .
3.Python代碼
發(fā)送郵件的方法,我們?cè)?人人都能懂的 Python 自動(dòng)發(fā)送郵件教程 中已經(jīng)詳細(xì)地講過了:
class Mail:
"""
郵件相關(guān)類
"""
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):
"""
發(fā)送郵件
Arguments:
html {str} -- 郵件正文(html)
title {str} -- 郵件標(biāo)題
receivers {list} -- 郵件接收者,數(shù)組
"""
yag = yagmail.SMTP(
host='您的郵箱SMTPHOST', user='您的郵箱',
password='您的郵箱密碼', smtp_ssl=True
)
yag.send(receivers, title, html)
self.log("郵件發(fā)送成功")
此外,為了渲染圖片,需要將圖片轉(zhuǎn)化為base64,這個(gè)方法是這樣的:
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")
當(dāng)然,最重要的地方是下面這段代碼,需要針對(duì)每個(gè)人定制祝福語,我們可以采用字典的數(shù)據(jù)結(jié)構(gòu)來保存數(shù)據(jù):
bless_info = {
"admin@pythondict.com": {
"pythondict_img": get_image_base64("./images/pythondict.png"),
"name": "實(shí)用寶典",
"background": "https://背景圖片.jpg",
"bless": "愿所有的幸運(yùn)與您不期而遇..",
"title": "祝寶典哥明年粉絲破十萬"
},
"test@qq.com": {
"pythondict_img": get_image_base64("./images/pythondict.png"),
"name": "老王",
"background": "https://背景圖片.jpg",
"bless": "祝您女兒明年考研順順利利,全家幸福安康..",
"title": "老王,祝您元旦快樂!"
},
}
可以看到 bless_info 字典里的每個(gè)key是發(fā)送對(duì)象的郵箱,而這些 key 對(duì)應(yīng)的value 中就有需要渲染到郵件的變量: pythondict_img , name , **background **及 祝福語 bless . 最后一個(gè)變量title,是用于指定郵件標(biāo)題的。
這樣,渲染+發(fā)送郵件做起來就方便多了:
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():是我們的發(fā)送郵件函數(shù),應(yīng)該不必多說。
bless_info[mail]:是需要渲染的變量,這里面的變量少了可不行,多了沒關(guān)系。
bless_info[mail]["title"]:就是剛剛在字典里指定的最后一個(gè)變量 title ,
由于 sendmail() 函數(shù)里的 receivers 是支持多人的,因此這里需要以數(shù)組的形式傳入函數(shù)。
不過這里還有一個(gè)有趣的改進(jìn),如果你需要用同一個(gè)模板郵件發(fā)送給同一家人,你可以這么做:
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": "老王一家,祝你們?cè)┛鞓罚?
},
}
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(","))
沒錯(cuò),只需要在key里將這一家人的郵箱用逗號(hào)分隔開,然后receivers里改為mail.split(","),你就能實(shí)現(xiàn)同一份郵件發(fā)給一家人的功能,是不是非常方便?
大家可以自己找喜歡的背景圖片,也可以用我在代碼里已給大家提供的圖片。想要去除LOGO的話,直接將pythondict_img設(shè)為空,或者設(shè)為你自己的卡片即可。
在源代碼目錄下運(yùn)行代碼:
python mail.py
即可成功發(fā)送郵件,快打開編輯器試一下吧(記得先測(cè)試)!
-
郵件
+關(guān)注
關(guān)注
0文章
31瀏覽量
18800 -
HTML
+關(guān)注
關(guān)注
0文章
277瀏覽量
34573 -
字符串
+關(guān)注
關(guān)注
1文章
577瀏覽量
20488 -
python
+關(guān)注
關(guān)注
56文章
4783瀏覽量
84473
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論