Python普通的邮件发送
需要一个安全的连接,例如SSL,因此接下来我们会使用SSL的方式去登录,但是在那之前,我们需要做一些准备,打开qq邮箱,点击设置->账户,找到POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务,开启IMAP/SMTP服务,然后根据要求使用手机发送到指定号码,获取授权码,这个授权码就是你接下来登录要使用的密码.
1 | from email.mime.text import MIMEText |
▲smtplib.SMTP_SSL([host[, port[, local_hostname[, keyfile[, certfile[, timeout]]]]]])
这是一个派生自SMTP的子类,通过SSL加密的套接字连接(使用此类,您需要使用SSL支持编译的套接字模块)。如果未指定主机,则使用“(本地主机)”。如果省略端口,则使用标准的SMTP-over-SSL端口(465)
本机已安装了支持 SMTP 的服务,如:sendmail:
1 | import smtplib |
第三方SMTP发送邮件:
1 | import smtplib |
Python 发送带附件的邮件:
发送带附件的邮件,首先要创建MIMEMultipart()实例,然后构造附件,如果有多个附件,可依次构造,最后利用smtplib.smtp发送。
1 | #!/usr/bin/python |
在 HTML 文本中添加图片
1 | #!/usr/bin/python |
flask-email
阻塞发送
最简单的调用
1 | from flask import Flask |
读取配置+视图函数中调用
1 | # 配置邮箱信息 |
1 | from flask import Flask |
tips:tip:具体工程中,配置可以写在单独一个文件如”.env”,然后利用python-envcfg来读取配置,如:
app.config.from_object(‘envcfg.raw’)
异步发送
1 | from flask import Flask |
▲. 许多Flask的扩展都是假定自己运行在一个活动的应用和请求上下文中,Flask-Mail的send函数使用到current_app 这个上下文了,所以当 mail.send()函数在一个线程中执行的时候需要人为的创建一个上下文。在示例 send_async_email 中使用了 app.app_context() 来创建一个上下文。
既然异步的邮件发送功能已经实现了,如果将来我们需要实现其它异步的函数,还有什么需要改进的吗?我们需要为每一个实现异步功能的函数拷贝多线程的代码吗?这并不好。
我们可以通过实现一个 装饰器 来解决这个问题。有了装饰器,上面的代码可以修改为:
1 | from .decorators import async |
好的多了吧,对不对?
这个神奇的代码其实很简单。我们把它放入一个新文件(文件 app/decorators.py):
1 | from threading import Thread |
作为一个练习,大家可以考虑考虑如何用 *multiprocessing* 模块来实现上面的功能。
摘自flask文档
django.core.mail邮件
EmailMessage: 标题. 内容.发件人.收件人
1 | from django.core.mail import send_mail |
send_mail()
subject,message,from_emailandrecipient_list这四个参数是必须的。
subject: 字符串,表示邮件标题。message: 字符串,表示邮件内容。from_email: 字符串,表示发件邮箱。recipient_list: 字符串列表,列表中每个成员都是一个邮箱地址,而且每个收件人都会在 “收件人/To:” 栏看到出现在recipient_list中的其他收件人。fail_silently: (可选)布尔值。为False时,send_mail会抛出smtplib.SMTPException异常。smtplib文档列出了所有可能的异常。 这些异常都是SMTPException的子类。auth_user: (可选)SMTP服务器的认证用户名。没提供该参数的情况下,Django会使用EMAIL_HOST_USER配置项的设置。auth_password: (可选)SMTP服务器的认证密码,没提供该参数的情况下,Django会使用EMAIL_HOST_PASSWORD配置项的设置。connection: (可选)发送邮件的后端。没提供该参数的情况下,Django会使用默认后端的实例。可查看 Email backends 了解更多细节。
send_mass_mail() 和 send_mail() 的区别在于: send_mail() 每发送一封邮件就会打开一次邮件服务器链接,而send_mass_mail() 则是打开一次链接,发送所有的邮件。 send_mass_mail() 明显更高效。
main_admins()
mail_admins(subject, message, fail_silently=False, connection=None, html_message=None)
django.core.mail.mail_admins() 是一个给网站后台管理员(admin)发邮件的快捷方法,管理员设置放在 ADMINS 配置项。
mail_admins() 使用 EMAIL_SUBJECT_PREFIX 配置项的值做为邮件标题的前缀,默认情况下是 "[Django] " 。
mail_managers()
mail_managers`(subject, message, fail_silently=False, connection=None, html_message=None)
mail_managers(*subject*, *message*, *fail_silently=False*, *connection=None*, *html_message=None*)django.core.mail.mail_managers()is just likemail_admins(),不同之处在于该方法的邮件接收人是网站负责人(manager), 可以在 [MANAGERS`]配置项设置网站负责人
EmailMessage 对象
- *class *
EmailMessage
EmailMessage 类使用下列参数初始化(除非使用位置参数,否则默认顺序如下)。所有参数均可选,均可在调用 send()方法之前的任何时间对其赋值。
加入了 cc 参数(cc是抄送)
-
subject: 邮件的标题行 -
body: 邮件的主体内容文本,须是纯文本信息。 -
from_email: 发送者的地址。fred@example.com或Fred <fred@example.com>格式都是合法的。如果忽略该参数,Django就会使用DEFAULT_FROM_EMAIL配置项。 -
to: 收件人地址列表或元组。 -
bcc: 发送邮件时用于”Bcc”头信息的一组列表或元组,也就是暗送的收件人。 -
connection: 一个邮件后端实例。用同一个链接发送多封邮件就要用到该参数。忽略该参数时,会在调用send()时自动创建一个新链接。 -
attachments: 置于邮件报文内的附件列表。列表元素可以是email.MIMEBase.MIMEBase实例,也可以是(filename, content, mimetype)三部分构成的元组。 -
headers: 置于邮件报文内的其他头信息(header)的字典。字典的key是头信息的名称,字典的value是头信息的值。 这样做能确保头信息的名称和对应值会以正确的格式保存于邮件报文中。 -
cc: 发送邮件时放于”Cc”头信息的一系列列表或元组。例如:
1
2
3email = EmailMessage('Hello', 'Body goes here', 'from@example.com',
['to1@example.com', 'to2@example.com'], ['bcc@example.com'],
headers = {'Reply-To': 'another@example.com'})该类方法如下:
-
send(fail_silently=False)发送邮件报文。如果在构造邮件时如果指定了某个链接(connection),就会使用该链接发邮件。 否则,就会使用默认后端的实例发邮件。如果关键字参数fail_silently为True,就会忽略邮件发送时抛出的异常。 -
message()构造了一个django.core.mail.SafeMIMEText对象 (Python的email.MIMEText.MIMEText类的子类) 或是django.core.mail.SafeMIMEMultipart对象(该对象保存即将发送出去邮件报文)。如需扩展EmailMessage类,一般情况下要覆写该方法,将你所需的内容添加到MIME对象中。 -
recipients()返回邮件中所有收件人的列表,不管收件人是在to还是bcc属性中。这是另一个经常被继承覆写的方法, 因为SMTP服务器在发送邮件报文时,要接收完整的收件人列表。即使你自己的类使用其他方式来指定收件人,也仍然需要使用该方法返回收件人列表。 -
attach()创建一个新的文件附件,并把它添加到邮件报文中。 有两种方法调用attach():-
传递一个单独的
email.MIMEBase.MIMEBase实例做为参数。该实例会直接添加到最终的邮件报文中。 -
或者,给
attach()传递三个参数:filename,content和mimetype.filename是出现在邮件中的附件文件的名称,content是附件的内容,而mimetype是附件所使用的MIME类型。 如果忽略mimetype, Django会自动根据附件文件名来推测MIME内容类型。例如:
1
message.attach('design.png', img_data, 'image/png')
-
-
attach_file()使用当前文件系统下的某个文件做为附件。调用时,传入某个文件的完整路径,以及该附件的MIME类型(可选的)。 忽略MIME类型的话,Django会自动根据附件文件名来推测MIME类型。最简单的用法如下:1
message.attach_file('/images/weather_map.png')
-
发送多用途邮件
在同一封邮件中包含多种版本的内容是非常有用的;典型的例子就是发送既有纯文本版本内容又有HTML版本内容的邮件。 在Django的邮件库中,可以使用 EmailMultiAlternatives 类来达到该目的。 EmailMessage 的子类有一个attach_alternative() 方法用来包含其他版本的邮件主体内容。所有其他方法(包括类的初始化方法)都直接继承自 EmailMessage 。
发送一封文本/HTML混合邮件,代码如下:
1 | from django.core.mail import EmailMultiAlternatives |
默认情况下,EmailMessage 类中的 body 参数的MIME类型是 "text/plain" 。 大多数情况下,没必要更改该MIME,因为这样能保证每个收件人能够阅读该邮件,而不论他们使用的是什么邮件客户端。 不过,在能确保收件人能处理多用途邮件的情况下,可以使用:class:~django.core.mail.EmailMessage 类的 content_subtype 属性 来更改邮件内容类型。主类型总是 "text" ,子类型可以设置为别的版本(比如html),例如:
1 | msg = EmailMessage(subject, html_content, from_email, [to]) |
获取邮件发送后端的实例
1 | django.core.mail 的 get_connection() 函式返回你当前使用的邮件后端的实例。 |
-
SMTP backend --默认的后端
-
Console backend
-
File backend --该后端并不建议在生产环境下使用–它仅仅是为开发提供方便
-
In-memory backend(内存后端)
-
Dummy backend(空后端)
需要在 settings.py中设置的东西:
1 | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' |
Author: Mrli
Link: https://nymrli.top/2018/12/12/Python中邮件的发送/
Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.