現實生活中,如果只是發郵件給自己,像上一篇文章那樣簡陋的格式是可以接受的,但若要針對每個人進行郵件的定制化,群發給公司客戶、內部員工、親戚朋友,則需更加高級的郵件發送方式。
我們可以通過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給你的親朋好友們定制元旦祝福郵件。
1.準備
開始之前,你要確保Python和pip已經成功安裝在電腦上,如果沒有,請訪問這篇文章:超詳細Python安裝指南 進行安裝。
如果你用Python的目的是數據分析,可以直接安裝Anaconda:Python數據分析與挖掘好幫手—Anaconda,它內置了Python和pip.
此外,推薦大家用VSCode編輯器,因為它有許多許多的優點:Python 編程的最好搭檔—VSCode 詳細指南。
準備輸入命令安裝依賴,如果你沒有VSCode編輯器,Windows環境下打開 Cmd (開始-運行-CMD),蘋果系統環境下請打開 Terminal (command+空格輸入Terminal),如果你用的是VSCode編輯器或Pycharm,可以直接在下方的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的時候,有可能會將換行符解析成
,因此壓縮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
即可成功發送郵件,快打開編輯器試一下吧(記得先測試)!
-
郵件
+關注
關注
0文章
32瀏覽量
18808 -
HTML
+關注
關注
0文章
278瀏覽量
35379 -
字符串
+關注
關注
1文章
579瀏覽量
20518 -
python
+關注
關注
56文章
4797瀏覽量
84690
發布評論請先 登錄
相關推薦
評論