Python 发送邮件通知

93 阅读5分钟

SMTP是发送邮件的协议,Python 2.3版本开始内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。本文以QQ邮件为例,用python发送各类邮件。

Python对SMTP支持主要使用smtplib和email两个模块,email模块负责构造邮件,smtplib模块负责发送邮件。

一、 传输简单邮件 smtplib模块

1. SMTP类定义

  • smtplib.SMTP([host[,port[,local_hostname[,timeout]]]]) 作为SMTP的构造函数,功能是与smtp服务器建立连接,在连接成功后,就可以向服务器发送相关请求,比如登录、校验、发送、退出等。

host参数为远程smtp主机地址,比如smtp.163.com port为连接端口,默认为25 local_hostname的作用是在本地主机的FQDN(完整的域名)发送HELO/EHLO(标识用户身份)指令 timeout为连接或尝试在多少秒超时 由于安全问题,通常不直接使用smtplib.SMTP来实例化,第三方邮箱会认为它是不安全的而报错。使用加密过的SMTP_SSL来实例化,它负责让服务器做出具体操作,它有两个参数:

参数1:smtp服务器地址,但它是bytes格式,所以需要编码 参数2:smtp端口,SMTP_SSL协议默认端口是465 smtp_srv = "smtp.qq.com" srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)

2. SMTP类方法

  • SMTP.connect([host[,port]]):连接远程smtp主机 host为远程主机地址,port为远程主机smtp端口,也可以直接使用host:port形式来表示

  • SMTP.connect("smtp.163.com","25")

  • SMTP.login(user, password):远程smtp主机的校验方法 参数为用户名与密码(或者授权码,视邮箱而定)

  • SMTP.login("python_2014@163.com","sdjkg358")

  • SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]):实现邮件的发送功能 参数依次为是发件人、收件人(列表)、邮件内容

  • SMTP.sendmail("python_2014@163.com",["demo@domail.com","demo@domail02.com"],body)

  • SMTP.starttls([keyfile[, certfile]]):启用TLS(安全传输)模式 所有SMTP指令都将加密传输,例如使用gmail的smtp服务时需要启动此项才能正常发送邮件,如SMTP.starttls()。

SMTP.quit():断开smtp服务器的连接

二、 定制个性化邮件 email模块

除简单文本外,很多时候邮件中还会包含HTML、图片、音频、附件等。MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)作为一种新的扩展邮件格式很好地补充了这一点。

可以将email.mime理解成smtplib模块邮件内容主体的扩展,从原先默认只支持纯文本格式扩展到HTML,同时支持附件、音频、图像等格式,smtplib只负责邮件的投递即可。

下面介绍几个常用的MIME实现类:

  • email.mime.multipart.MIMEMultipart([_subtype[,boundary[,_subparts[,_params]]]]):包含多个部分邮件体的MIME对象。 参数_subtype指定要添加到 "Content-type:multipart/subtype" 报头的三种可选子类型:

mixed(默认):构建一个带附件的邮件体 related:构建内嵌资源的邮件体 alternative:构建纯文本与超文本共存的邮件体

  • email.mime.audio.MIMEAudio (_audiodata[,_subtype[,_encoder[,**_params]]]):创建包含音频数据的邮件体 _audiodata包含原始二进制音频数据的字节字符串。

  • email.mime.image.MIMEImage(_imagedata[,_subtype[,_encoder[,**_params]]]):创建包含图片数据的邮件体 _imagedata是包含原始图片数据的字节字符串。

  • email.mime.text.MIMEText (_text[,_subtype[,_charset]]):创建包含文本数据的邮件体 _text是包含消息负载的字符串,_subtype指定文本类型,支持plain(默认值)或html类型的字符串。

三、发送简单文本邮件

下面是一个小例子,只简单发送文本数据

1. 获取授权码

进入QQ 邮箱的主界面→设置→账户,开启“POP3/SMTP服务”和“IMAP/SMTP 服务”。

开启后会弹出授权码,记录下来,如

  • POP3/SMTP服务:kkkkkkkkkkkkkk
  • IMAP/SMTP服务:jjjjjjjjjjjjjjjjjjjjjjjjjjj

image.png

2. Python代码

# -*- coding:utf-8 -*-
#@Time  : 2022/2/5 23:03
#@File  : python_email.py
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
 
# 发件人
from_name = "Hehuyi_In"
# 发件邮箱
from_addr = "xxxxx@qq.com"
# 发件邮箱授权码,注意不是QQ邮箱密码
from_pwd = "jjjjjjjjjj"
# 收件邮箱
to_addr = "yyyyyy@qq.com"
 
# 邮件标题
my_title = "Hehuyi Test"
# 邮件正文
my_msg = "Hello World"
 
# MIMEText三个主要参数
# 1. 邮件内容
# 2. MIME子类型,plain表示text类型
# 3. 邮件编码格式,使用"utf-8"避免乱码
msg = MIMEText(my_msg, 'plain', 'utf-8')
msg['From'] = formataddr([from_name, from_addr])
# 邮件的标题
msg['Subject'] = my_title
 
# SMTP服务器地址,QQ邮箱的SMTP地址是"smtp.qq.com"
smtp_srv = "smtp.qq.com"
 
try:
    # 不能直接使用smtplib.SMTP来实例化,第三方邮箱会认为它是不安全的而报错
    # 使用加密过的SMTP_SSL来实例化,它负责让服务器做出具体操作,它有两个参数
    # 第一个是服务器地址,但它是bytes格式,所以需要编码
    # 第二个参数是服务器的接受访问端口,SMTP_SSL协议默认端口是465
    srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465)
 
    # 使用授权码登录QQ邮箱
    srv.login(from_addr, from_pwd)
 
    # 使用sendmail方法来发送邮件,它有三个参数
    # 第一个是发送地址
    # 第二个是接受地址,是list格式,可以同时发送给多个邮箱
    # 第三个是发送内容,作为字符串发送
    srv.sendmail(from_addr, [to_addr], msg.as_string())
    print('发送成功')
except Exception as e:
    print('发送失败')
finally:
    #无论发送成功还是失败都要退出你的QQ邮箱
    srv.quit()

注意事项:

  1. 直接pip 安装smtplib报错,使用pip install PyEmail命令之后引入模块即可
  2. 文件名字不能为email.py,会导致错误