首先在进入正题之前,我们需要对一些基本内容有所了解:常用的电子邮件协议有SMTP、POP3、IMAP4,它们都隶属于TCP/IP协议簇,默认状态下,分别通过TCP端口25、110和143建立连接。Python内置对SMTP的支持,该协议支持发送纯文本邮件、HTML邮件以及带附件的邮件,Python的smtplib,email模块都支持该协议。

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。

发邮件需要掌握两个模块的用法,smtplib和email,这俩模块是python自带的,只需import即可使用。smtplib模块主要负责发送邮件,email模块主要负责构造邮件。

smtplib模块主要负责发送邮件:是一个发送邮件的动作,连接邮箱服务器,登录邮箱,发送邮件(有发件人,收信人,邮件内容)。

email模块主要负责构造邮件:指的是邮箱页面显示的一些构造,如发件人,收件人,主题,正文,附件等。

第一步,首先你要准备两个邮箱帐号,一个是常用的(接收端),另一个可以注册网易163邮箱或者foxmail邮箱也可(发送端),本次我使用两个QQ邮箱进行演示。首先在邮箱的设置-账户中开启SMTP功能

第二步,点击生成授权码,按照弹出窗口的提示发送短信,发送后单击我已发送按钮将生成的授权码复制下来以备接下来使用。

QQ 邮箱 SMTP 服务器地址:smtp.qq.com,ssl 端口:465。授权码是下面案例中的密码

1.smtplib模块

smtplib使用较为简单。以下是最基本的语法。

导入及使用方法如下:

import smtplibsmtp = smtplib.SMTP()
smtp.connect('smtp.163.com,25')
smtp.login(username, password)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()

说明:

smtplib.SMTP():实例化SMTP()

connect(host,port):

host:指定连接的邮箱服务器。常用邮箱的smtp服务器地址如下:

新浪邮箱:smtp.sina.com,新浪VIP:smtp.vip.sina.com,搜狐邮箱:smtp.sohu.com,126邮箱:smtp.126.com,139邮箱:smtp.139.com,163网易邮箱:smtp.163.com。

port:指定连接服务器的端口号,默认为25.

login(user,password):

user:登录邮箱的用户名。

password:登录邮箱的密码,像笔者用的是网易邮箱,网易邮箱一般是网页版,需要用到客户端密码,需要在网页版的网易邮箱中设置授权码,该授权码即为客户端密码。

sendmail(from_addr,to_addrs,msg,...):

from_addr:邮件发送者地址

to_addrs:邮件接收者地址。字符串列表['接收地址1','接收地址2','接收地址3',...]或'接收地址'

msg:发送消息:邮件内容。一般是msg.as_string():as_string()是将msg(MIMEText对象或者MIMEMultipart对象)变为str。

quit():用于结束SMTP会话。

2.email模块

email模块下有mime包,mime英文全称为“Multipurpose Internet Mail Extensions”,即多用途互联网邮件扩展,是目前互联网电子邮件普遍遵循的邮件技术规范。

该mime包下常用的有三个模块:text,image,multpart。

导入方法如下:

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage

构造一个邮件对象就是一个Message对象,如果构造一个MIMEText对象,就表示一个文本邮件对象,如果构造一个MIMEImage对象,就表示一个作为附件的图片,要把多个对象组合起来,就用MIMEMultipart对象,而MIMEBase可以表示任何对象。它们的继承关系如下:

Message
+- MIMEBase+- MIMEMultipart+- MIMENonMultipart+- MIMEMessage+- MIMEText+- MIMEImage

2.1 text说明

邮件发送程序为了防止有些邮件阅读软件不能显示处理HTML格式的数据,通常都会用两类型分别为"text/plain"和"text/html"

构造MIMEText对象时,第一个参数是邮件正文,第二个参数是MIME的subtype,最后一定要用utf-8编码保证多语言兼容性。

2.1.1添加普通文本

text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.baidu.com"
text_plain = MIMEText(text,'plain', 'utf-8') 

查看MIMEText属性:可以观察到MIMEText,MIMEImage和MIMEMultipart的属性都一样。

print dir(text_plain)

['__contains__', '__delitem__', '__doc__', '__getitem__', '__init__', '__len__', '__module__', '__setitem__', '__str__', '_charset', '_default_type', '_get_params_preserve', '_headers', '_payload', '_unixfrom', 'add_header', 'as_string', 'attach', 'defects', 'del_param', 'epilogue', 'get', 'get_all', 'get_boundary', 'get_charset', 'get_charsets', 'get_content_charset', 'get_content_maintype', 'get_content_subtype', 'get_content_type', 'get_default_type', 'get_filename', 'get_param', 'get_params', 'get_payload', 'get_unixfrom', 'has_key', 'is_multipart', 'items', 'keys', 'preamble', 'replace_header', 'set_boundary', 'set_charset', 'set_default_type', 'set_param', 'set_payload', 'set_type', 'set_unixfrom', 'values', 'walk']

import smtplib
from email.mime.text import MIMEText
from email.header import Header# 第三方 SMTP 服务
mail_host = "smtp.qq.com"  # 设置服务器
mail_user = "******@qq.com"  # 用户名
mail_pass = "xocdirmaacdudhei"  # 授权码sender = '******@qq.com'
receivers = ['****@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')message['From'] = Header("菜鸟教程", 'utf-8') #括号里的对应发件人邮箱昵称(随便起)、发件人邮箱账号
message['To'] = Header("测试", 'utf-8') #括号里的对应收件人邮箱昵称、收件人邮箱账号subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')try:smtpObj = smtplib.SMTP()smtpObj.connect(mail_host, 25)  # 发件人邮箱中的SMTP服务器,端口是25smtpObj.login(mail_user, mail_pass)smtpObj.sendmail(sender, receivers, message.as_string())print("邮件发送成功")
except smtplib.SMTPException:print("Error: 无法发送邮件")

2.1.2添加超文本

Python发送HTML格式的邮件与发送纯文本消息的邮件不同之处就是将MIMEText中_subtype设置为html。具体代码如下:

import smtplib
from email.mime.text import MIMEText
from email.header import Header# 第三方 SMTP 服务
mail_host = "smtp.qq.com"  # 设置服务器
mail_user = "18037525190@qq.com"  # 用户名
mail_pass = "xocdirmaacdudhei"  # 授权码sender = '18037525190@qq.com'
receivers = ['468521886@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱#使用Python发送HTML格式的邮件mail_msg = """
<p>Python 邮件发送测试...</p>
<p><a href="http://www.runoob.com">这是一个链接</a></p>
"""message = MIMEText(mail_msg, 'html', 'utf-8')message['From'] = Header("菜鸟教程", 'utf-8') #括号里的对应发件人邮箱昵称(随便起)、发件人邮箱账号
message['To'] = Header("测试", 'utf-8') #括号里的对应收件人邮箱昵称、收件人邮箱账号subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')try:smtpObj = smtplib.SMTP()smtpObj.connect(mail_host, 25)  # 发件人邮箱中的SMTP服务器,端口是25smtpObj.login(mail_user, mail_pass)smtpObj.sendmail(sender, receivers, message.as_string())print("邮件发送成功")
except smtplib.SMTPException:print("Error: 无法发送邮件")

2.1.3 image说明

import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header# 第三方 SMTP 服务
mail_host = "smtp.qq.com"  # 设置服务器
mail_user = "****@qq.com"  # 用户名
mail_pass = "xocdirmaacdudhei"  # 授权码sender = '*****@qq.com'
receivers = ['*****@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱msgRoot = MIMEMultipart('related')
msgRoot['From'] = Header("发送者", 'utf-8')
msgRoot['To'] = Header("测试", 'utf-8')
subject = 'Python SMTP 邮件测试'
msgRoot['Subject'] = Header(subject, 'utf-8')msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)mail_msg = """
<p>Python 邮件发送测试...</p>
<p><a href="http://www.runoob.com">菜鸟教程链接</a></p>
<p>图片演示:</p>
<p><img src="cid:image1"></p>
"""
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))# 指定图片为当前目录
fp = open('3.jpg', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()# 定义图片 ID,在 HTML 文本中引用
msgImage.add_header('Content-ID', '<image1>')
msgRoot.attach(msgImage)try:smtpObj = smtplib.SMTP()smtpObj.connect(mail_host, 25)  # 发件人邮箱中的SMTP服务器,端口是25smtpObj.login(mail_user, mail_pass)smtpObj.sendmail(sender, receivers, msgRoot.as_string())print("邮件发送成功")
except smtplib.SMTPException:print("Error: 无法发送邮件")

2.1.4添加附件

发送带附件的邮件,首先要创建MIMEMultipart()实例,然后构造附件,如果有多个附件,可依次构造,最后利用smtplib.smtp发送。

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Headersender = 'from@runoob.com'
receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱#创建一个带附件的实例
message = MIMEMultipart()
message['From'] = Header("菜鸟教程", 'utf-8')
message['To'] =  Header("测试", 'utf-8')
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')#邮件正文内容
message.attach(MIMEText('这是菜鸟教程Python 邮件发送测试……', 'plain', 'utf-8'))# 构造附件1,传送当前目录下的 test.txt 文件
att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="test.txt"'
message.attach(att1)# 构造附件2,传送当前目录下的 runoob.txt 文件
att2 = MIMEText(open('runoob.txt', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="runoob.txt"'
message.attach(att2)try:smtpObj = smtplib.SMTP('localhost')smtpObj.sendmail(sender, receivers, message.as_string())print "邮件发送成功"
except smtplib.SMTPException:print "Error: 无法发送邮件"

2.3 multpart说明

常见的multipart类型有三种:multipart/alternative, multipart/related和multipart/mixed。

邮件类型为"multipart/alternative"的邮件包括纯文本正文(text/plain)和超文本正文(text/html)。

邮件类型为"multipart/related"的邮件正文中包括图片,声音等内嵌资源。

邮件类型为"multipart/mixed"的邮件包含附件。向上兼容,如果一个邮件有纯文本正文,超文本正文,内嵌资源,附件,则选择mixed类型。

msg = MIMEMultipart('mixed')

我们必须把Subject,From,To,Date添加到MIMEText对象或者MIMEMultipart对象中,邮件中才会显示主题,发件人,收件人,时间(若无时间,就默认一般为当前时间,该值一般不设置)。

msg = MIMEMultipart('mixed')
msg['Subject'] = 'Python email test'
msg['From'] = 'XXX@163.com <XXX@163.com>'
msg['To'] = 'XXX@126.com'
msg['Date']='2012-3-16'

查看MIMEMultipart属性:

msg = MIMEMultipart('mixed')
print dir(msg) 

结果:

['__contains__', '__delitem__', '__doc__', '__getitem__', '__init__', '__len__', '__module__', '__setitem__', '__str__', '_charset', '_default_type', '_get_params_preserve', '_headers', '_payload', '_unixfrom', 'add_header', 'as_string', 'attach', 'defects', 'del_param', 'epilogue', 'get', 'get_all', 'get_boundary', 'get_charset', 'get_charsets', 'get_content_charset', 'get_content_maintype', 'get_content_subtype', 'get_content_type', 'get_default_type', 'get_filename', 'get_param', 'get_params', 'get_payload', 'get_unixfrom', 'has_key', 'is_multipart', 'items', 'keys', 'preamble', 'replace_header', 'set_boundary', 'set_charset', 'set_default_type', 'set_param', 'set_payload', 'set_type', 'set_unixfrom', 'values', 'walk']

说明:

msg.add_header(_name,_value,**_params):添加邮件头字段。

msg.as_string():是将msg(MIMEText对象或者MIMEMultipart对象)变为str,如果只有一个html超文本正文或者plain普通文本正文的话,一般msg的类型可以是MIMEText;如果是多个的话,就都添加到MIMEMultipart,msg类型就变为MIMEMultipart。

msg.attach(MIMEText对象或MIMEImage对象):将MIMEText对象或MIMEImage对象添加到MIMEMultipart对象中。MIMEMultipart对象代表邮件本身,MIMEText对象或MIMEImage对象代表邮件正文。

以上的构造的文本,超文本,附件,图片都何以添加到MIMEMultipart('mixed')中:

msg.attach(text_plain)
msg.attach(text_html)
msg.attach(text_att)
msg.attach(image)

附加案例:

案例一:

from email.header import Headerfrom email.mime.text import MIMETextfrom email.utils import parseaddr,formataddrimport smtplibdef _format_addr(s):name,addr = parseaddr(s)# print('name is',name,addr)# print('header is ',Header(name,'utf-8').encode())return formataddr((Header(name,'utf-8').encode(),addr))#发件人地址from_addr = '*****@qq.com'#密码刚才复制的邮箱的授权码password = 'xocdirmaacdudhei'#收件人地址to_addr =  '****@qq.com'#邮箱服务器地址smtp_server = 'smtp.qq.com'#设置邮件信息msg = MIMEText('Python爬虫运行异常,异常信息为遇到HTTP 403','plain','utf-8')
# print('msg is ',msg)msg['From'] = _format_addr('Python爬虫一号<%s>'%from_addr)#括号里的对应发件人邮箱昵称(随便起)、发件人邮箱账号
# print('msg[form is',msg['From'])msg['To'] = _format_addr('管理员<%s>'%to_addr)msg['Subject'] = Header('一号爬虫运行异常.','utf-8').encode()#发送邮件server = smtplib.SMTP_SSL(smtp_server,465)#打印出和SMTP服务器交互的所有信息server.set_debuglevel(1)#登录SMTP服务器server.login(from_addr,password)#sendmail():发送邮件,由于可以一次发给多个人,所以传入一个list邮件正文是一个str,as_string()把MIMEText对象变成str。server.sendmail(from_addr,to_addr,msg.as_string())
server.quit()
print('邮件发送成功!')

文字,html,图片,附件实现案例:

#coding: utf-8    import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.header import Header   #设置smtplib所需的参数
#下面的发件人,收件人是用于邮件传输的。
smtpserver = 'smtp.163.com'
username = 'XXX@163.com'
password='XXX'
sender='XXX@163.com'
#receiver='XXX@126.com'
#收件人为多个收件人
receiver=['XXX@126.com','XXX@126.com']subject = 'Python email test'
#通过Header对象编码的文本,包含utf-8编码信息和Base64编码信息。以下中文名测试ok
#subject = '中文标题'
#subject=Header(subject, 'utf-8').encode()#构造邮件对象MIMEMultipart对象
#下面的主题,发件人,收件人,日期是显示在邮件页面上的。
msg = MIMEMultipart('mixed')
msg['Subject'] = subject
msg['From'] = 'XXX@163.com <XXX@163.com>'
#msg['To'] = 'XXX@126.com'
#收件人为多个收件人,通过join将列表转换为以;为间隔的字符串
msg['To'] = ";".join(receiver)
#msg['Date']='2012-3-16'#构造文字内容
text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.baidu.com"
text_plain = MIMEText(text,'plain', 'utf-8')
msg.attach(text_plain)    #构造图片链接
sendimagefile=open(r'D:\pythontest\testimage.png','rb').read()
image = MIMEImage(sendimagefile)
image.add_header('Content-ID','<image1>')
image["Content-Disposition"] = 'attachment; filename="testimage.png"'
msg.attach(image)#构造html
#发送正文中的图片:由于包含未被许可的信息,网易邮箱定义为垃圾邮件,报554 DT:SPM :<p><img src="cid:image1"></p>
html = """
<html>  <head></head>  <body>  <p>Hi!<br>  How are you?<br>  Here is the <a href="http://www.baidu.com">link</a> you wanted.<br> </p> </body>
</html>
"""
text_html = MIMEText(html,'html', 'utf-8')
text_html["Content-Disposition"] = 'attachment; filename="texthtml.html"'
msg.attach(text_html)    #构造附件
sendfile=open(r'D:\pythontest\1111.txt','rb').read()
text_att = MIMEText(sendfile, 'base64', 'utf-8')
text_att["Content-Type"] = 'application/octet-stream'
#以下附件可以重命名成aaa.txt
#text_att["Content-Disposition"] = 'attachment; filename="aaa.txt"'
#另一种实现方式
text_att.add_header('Content-Disposition', 'attachment', filename='aaa.txt')
#以下中文测试不ok
#text_att["Content-Disposition"] = u'attachment; filename="中文附件.txt"'.decode('utf-8')
msg.attach(text_att)    #发送邮件
smtp = smtplib.SMTP()
smtp.connect('smtp.163.com')
#我们用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息。
#smtp.set_debuglevel(1)
smtp.login(username, password)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()

参考:https://docs.python.org/2/library/email-examples.html

https://www.cnblogs.com/yufeihlf/p/5726619.html

http://www.runoob.com/python/python-email.html

更详细的内容可以看官方文档:

  • smtplib模块:https://docs.python.org/2/library/smtplib.html

  • email模块:https://docs.python.org/2/library/email.html

  • poplib模块:https://docs.python.org/2/library/poplib.html

  • imaplib模块:https://docs.python.org/2/library/imaplib.html

Python SMTP发送邮件相关推荐

  1. Python——SMTP发送邮件(发送不同格式、附件)

    SMTP发送邮件 一.Python3 SMTP发送邮件 二.使用第三方 SMTP 服务发送 1.QQ邮箱 2.网易邮箱 三.发送HTML格式的邮件 四.发送带附件的邮件 一.Python3 SMTP发 ...

  2. [转载]Python SMTP发送邮件-smtplib模块

    在进入正题之前,我们需要对一些基本内容有所了解:常用的电子邮件协议有SMTP.POP3.IMAP4,它们都隶属于TCP/IP协议簇,默认状态下,分别通过TCP端口25.110和143建立连接. Pyt ...

  3. Python SMTP 发送邮件

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. Python的smtplib提供了一 ...

  4. python SMTP 发送邮件 阿里企业邮箱、163邮箱 及535错误

    class SendEmail(object):def __init__(self, type, to_addr):self.to_addr = to_addrself.sys_date = time ...

  5. python SMTP发送邮件常出现问题

    https://blog.csdn.net/Mk1128/article/details/105228918/

  6. 基于python SMTP实现自动发送邮件教程解析

    更多编程教程请到:菜鸟教程 https://www.piaodoo.com/ 友情链接: 高州阳光论坛https://www.hnthzk.com/ 人人影视http://www.sfkyty.com ...

  7. Python基础《十八:SMTP发送邮件》

    Python SMTP发送邮件 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. py ...

  8. Python使用SMTP发送邮件

    1.目标 使用SMTP发送邮件 2.系统环境 操作系统:Win7 64 Python版本:3.7.0 3.代码参考 #config:utf-8                         #强制使 ...

  9. python怎么发送邮件_python中是如何借助smtp协议发送邮件的?

    前言 现如今邮件已经逐渐替代了书信传递,成为日常办公不可缺少的一部分.在Java开发中,我们会利用POP3协议和SMTP协议借助java类来发送邮件,从而我们了解到,要想发送邮件,需要拥有可以发送邮件 ...

最新文章

  1. 简单理解重量级锁、轻量级锁、偏向锁
  2. 在HTML网页中嵌入脚本的方式
  3. HTTPS 路径配置
  4. Web前端笔记-安装vue的4.5.9版本
  5. Flask中那些特殊的装饰器
  6. hdfs 中chunk_HDFS读写流程
  7. 配置idea开发go编程语言并配置导入本地包
  8. iPhone app 和android app开发环境和语言的区别
  9. 面对不稳定的百度网盘离线下载,这些备用方案可以帮你应急
  10. Android系统优化的那些年那些事
  11. 安卓开发——MaterialDesign实战
  12. 那些漂亮有创意的思维导图真的更吸引人吗?
  13. 类和对象总结及用法 计算点到点距离 线与线的关系 计算三角形平行四边形面积周长 判断形状
  14. 现代富文本编辑器Quill的内容渲染机制
  15. 数据结构基础知识点,看完保证期末不挂科!
  16. 抖音计算机音乐谱小苹果,抖音最火歌曲简谱 电子琴
  17. 怎么在自己的电脑上录音,电脑录音的软件有哪些
  18. mediainfo php,MediaInfo Mac版下载
  19. 西门子S7300PLC转以太网连接CHNet-S7300MD实现以太网通信配置方法
  20. 2022-2028全球与中国头孢呋辛市场现状及未来发展趋势

热门文章

  1. Nodejs+express+vue+Elementui酒店客房管理系统
  2. Cat4模块SIM7600CE介绍
  3. 2021全球程序员收入报告出炉,字节高级码农年薪274万元排第5!
  4. 上海高中开设计算机课,如何提升高中计算机课的趣味性
  5. termux—手机远程连接服务器教程
  6. 微信小程序手把手入门教程
  7. linux mtd 指令,mtd交叉编译mkfs命令
  8. 因收费被抵制、如今又被明星索赔百万,丰巢出路在何方?
  9. 分子遗传学重点(可缩印)
  10. 第三章:EB配置DIO输出(s32k144)