文章内容

2022/5/26 19:15:54,作 者: 黄兵

在 Python 中发送 html 页面邮件

最近在网站上增加了一个邮件订阅的功能,每次又新文章或者是其他重要消息,通过电子邮件通知用户。

在使用邮件订阅的时候,用户在网站输入电子邮件之后,通过链接激活邮件,有新文章增加,通过已经激活的邮件通知订阅人,整个是这样的一个流程。

但是在编写后端服务的时候,遇到一些问题,主要是通过电子邮件发送 html 页面问题,需要自定义页面的内容,通过电子邮件发送,所以需要用到模板。

经过研究 Python 有 Jinja2 可以设置 html 模板,Jinja2 是一个强大的模板引擎,它允许您通过变量、循环、块等获得动态内容。您甚至可以扩展模板以设置所有其他模板构建的一些“基础”模板。

安装 Jinja2 与设置模板目录

首先我们需要通过以下命令安装 Jinja2:

pip install Jinja2

之后设置一个 template 模板目录,项目结构如下:

创建相关模板函数

导入相关的模块,代码如下:

from jinja2 import Environment, PackageLoader, select_autoescape

创建模板相关代码示例:

def send_template_email(self, template, to, subj, **kwargs):
get_template_path = os.path.join(os.getcwd(), 'templates')
"""Sends an email using a template."""
env = Environment(
loader=FileSystemLoader(get_template_path),
autoescape=select_autoescape(['html', 'xml'])
)
template = env.get_template(template)
self.send_email(to, subj, template.render(**kwargs))

首先获取了 template 的路径,之后使用 FileSystemLoader 加载模板,同时将 Jinja2 始终设置为自动转义模板。

一旦我们有了 env 变量,我们就可以使用它来创建我们的模板:

template = env.get_template(template)

之后渲染模板里面的内容:

template.render(**kwargs)

以上就完成了对于基本的 Jinja2 内容模板的渲染。

发送邮件的函数示例:

def send_email(self, to, subj, body):
"""Sends an email."""
# 发送方邮箱
msg_from = self._msg_from
# 授权码
pwd = self._msg_password
# msg邮件对象
msg = MIMEText(body, 'html', 'utf-8')
msg['Subject'] = subj
msg['To'] = to
msg['From'] = msg_from

try:
ssl_context = ssl.create_default_context()
service = smtplib.SMTP('smtp.googlemail.com', 587)
service.ehlo()
service.starttls(context=ssl_context)
service.ehlo()
service.login(msg_from, pwd)
service.sendmail(msg_from, to, msg.as_string()) # 发送
return True
except Exception as e:
self._logging.error(f"邮件发送失败,错误内容:{e}")
return False

创建 html 页面模板

现在我们已经创建了函数,让我们创建我们的第一个模板,由于我开发网站一直使用的是 flask ,flask 默认的 html 渲染模板就使用的是 Jinja2,下面也 html 页面模板示例:

<div class="article container" style="width:100%;max-width:700px;margin:auto;font-size:18px">
{{ article_body_html | safe }}
</div>

可以说非常简单,由于发送邮件,不支持外部样式,所以只能内联样式。

渲染模板调用

我们之前定义的函数 template, to, subj, **kwargs 作为参数。然后将 kwargs 它们传递给 render() 方法。

下面是示例代码

init_email = email_util.EmailUtil()
init_email.send_template_email(
template='article_template.html',
to='hu@163.com',
subj=self.publisher.getArticles()[1]['title'].decode('utf-8'),
article_body_html=self.publisher.getArticles()[1]['body_html'].decode('utf-8'),
)

首先定义了模板的文件名,可以看到最上面的截图,文件名是 article_template.html ,后面是要传递的一些参数,article_body_html 是要传给模板的参数,也就是文章的内容。


参考资料:

1、Using Jinja for HTML Email Templates in Python

2、How to Send Emails through Gmail in Python?

3、如何修复:[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1076)


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 - 在 Python 中发送 html 页面邮件

分享到:

发表评论

评论列表