使用Python发送邮件
背景
公司内网有个论坛,各种公司的前沿消息都会有人在讨论。一忙起来,经常忘记逛论坛,所以写了个爬虫,爬取论坛前10页帖子,将回复量较多的帖子通过邮件发送给自己,这样,在没时间逛论坛的时候,也能关注到一些相关消息。
基于以上背景,涉及到了python发送邮件,写下这篇文章作为对相关知识的复习与巩固。
相关模块介绍
-
smtplib模块
-
SMTP类
smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])
如上可看出,构造函数的参数都是可选参数。- 当没有参数的时候,会创建出一个SMTP连接实例
- 当传入host和port参数时,在初始化SMTP实例时,会自动调用connect()函数
-
SMTP对象拥有的方法
-
SMTP.connect([host[, port]])
连接到给定端口的主机。
- 没参数时,则通过标准的SMTP端口25连接到本地主机
- 当host参数末尾加上:25(如"smtp.163.com:25"),则不需要指定port端口号
- 函数返回值为一个包含两个元素的元组。一个返回状态码,一个服务器发送的连接反馈消息
- 当创建实例时传入了hostname,该函数会被自动调用
-
SMTP.login(user, password)
登录到SMTP服务器。 -
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
发送邮件。
- from_addr 发件人地址
- to_addrs 收件人地址列表,如果该参数为一个字符串,则把它当作数组的第一个元素
- msg一个字符串格式的message报文
-
SMTP.quit()
结束SMTP会话并关闭连接。
-
-
常见使用方式
smtpObj = smtplib.SMTP()
smtpObj.connect('hostname:port')
smtpObj.login(user,password)
smtpObj.sendmail(from,to,msg)
smtpObj.quit()
-
email模块
email模块是一个用来管理email消息的库,包含MIME和其他基于RFC2822的消息文档。它并不负责处理发送邮件。
-
email.mime子模块
创建email和MIME对象- email.mime.multipart.MIMEMultipart([_subtype[, boundary[, _subparts[, _params]]]])
MIMEBase的一个子类,多个MIME对象的集合,- _subtype默认值为mixed。
- boundary是MIMEMultipart的边界,默认边界是可数的。
- _subparts可以转化成list的MIME对象。
- 可通过message.attach将新的MIME对象添加到附件中。
- email.mime.multipart.MIMEMultipart([_subtype[, boundary[, _subparts[, _params]]]])
-
email.mime.audio.MIMEAudio(_audiodata[, _subtype[,_encoder[, **_params]]])
该类用来创建音频类型的MIME消息对象- _audiodata参数是一个包含音频数据流的字符串
- 如果audiodata数据由标准库sndhdr
译码,那么subtype则会被自动包含在Content-type头中,否则,必须显示的指定subtype参数
-
email.mime.image.MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]])
该类用来创建图像类型的MIME消息对象- 参数与上一个类相似,不做详细解释
-
email.mime.text.MIMEText(_text[, _subtype[, _charset]])
该类用来创建文本类型的MIME消息对象 -
_subtype默认的plain格式
-
_charset是文本的字符集,默认为ascii
-
如果文本为unicode编码格式,将使用_charset的output_charset(详见 email.charset
)进行编码,否则,按照原来的格式输出 -
email.header子模块
- email.header.Header([s[, charset[, maxlinelen[, header_name[, continuation_ws[, errors]]]]]])
创建一个遵从MIME的包含不同字符集编码字符串的header- 可选的s是header的初始化值,默认为空,如果没有赋值,可以通过append函数进行插入。
- email.header.Header([s[, charset[, maxlinelen[, header_name[, continuation_ws[, errors]]]]]])
-
例子
- 创建一个普通文本消息
from email.mime.text import MIMEText
from email.header import Header
mes = MIMEText(body, 'plain', 'utf-8') # 正文
mes['From'] = Header('xxx@xxx.com','utf-8') # 发件人
mes['To'] = Header('xxx@xxx.com','utf-8') # 收件人
mes['Cc'] = Header('xxx@xxx.com','utf-8') # 抄送人
mes['Subject'] = Header(subject, 'utf-8') # 主题
- 创建一个html文本消息
from email.mime.text import MIMEText
from email.header import Header
mes = MIMEText(body, 'html', 'utf-8') # body按照html格式写
mes['From'] = Header('xxx@xxx.com','utf-8') # 发件人
mes['To'] = Header('xxx@xxx.com','utf-8') # 收件人
mes['Cc'] = Header('xxx@xxx.com','utf-8') # 抄送人
mes['Subject'] = Header(subject, 'utf-8') # 主题
msg['date']='xxxx-xx-xx' #
3. 创建带附件邮件
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
#创建一个带附件的实例
msg = MIMEMultipart()
#构造附件1
att1 = MIMEText(open('d:\\123.rar', 'rb').read(), 'base64', 'gb2312')
att1["Content-Type"] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="123.doc"'#这里的filename可以任意写,写什么名字,邮件中显示什么名字
msg.attach(att1)
#构造附件2
att2 = MIMEText(open('d:\\123.txt', 'rb').read(), 'base64', 'gb2312')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="123.txt"'
msg.attach(att2)
#加邮件头
msg['to'] = 'YYY@YYY.com'
msg['from'] = 'XXX@XXX.com'
msg['subject'] = 'hello world'
- 如果想发送一个带图片附件的邮件,同时图片还显示在正文中
- 按照3.的方式(图片用MIMEImage)插入图片附件hello.jpg
- 按照2.的方式,发送一个html文件,在html中插入img标签,src为图片的路径
![](cid:hello.jpg)