欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python实现smtp协议发送邮件

程序员文章站 2022-05-18 21:37:05
...

协议简介:
    SMTP和POP3/IMAP协议的一些介绍

1.SMTP协议
     (1) SMTP协议(simple mail transfer protocol) 简单邮件传输协议
     (2) 定义了邮件客户端与SMTP服务器之间、两台SMTP服务器之间的通信规则
     (3) 分为标准SMTP协议和扩展SMTP协议。扩展SMTP协议在标准SMTP协议上增加了邮件
     安全的认证
     (4) 通信双方采用一问一答的命令/响应模式
     (5) 底层基于TCP/IP的应用层协议、默认网络监听号25

2.POP3协议
    (1) 用户要从服务提供商提供的电子邮件中获取自己的电子邮件,需要POP3邮件服务器帮组完成
而POP3(Post Office Protocol) 定义了邮件客户端与POP3服务器通信规则。
    (2) POP3采用的网络监听端口号默认为110

3.IMAP协议
    (1) IMAP (internet Message Access Protocol) 协议是对POP3协议的一种扩展
    (2) 相对于POP3协议而言,定义了更为强大的邮件接收功能
        IMAP具有摘要浏览功能
        IAP可以让用户有选择性地下载邮件附件
        IMAP可以让用户在邮件服务器上创建自己的邮件夹,分类保存各个邮件
    (3) IMAP协议在逐渐取代POP3协议,但POP3协议长期存在也不会在短期内淘汰,所以我们看到
还是两种协议并存

smtplocalhost.py 直接由自己搭建的邮件服务器发送,我这里ubuntu正在配置

# -*- coding: utf-8 -*-
# @Author: Clarence
# @Date:   2018-08-29 22:52:18
# @Last Modified by:   Clarence
# @Last Modified time: 2018-09-10 15:13:28

"""
Python3 SMTP发送邮件
python的smtplib提供一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装
Python创建SMTP对象语法如下:
import smtplib
smtpObj = smtplib.SMTP( [host [, port[, local_hostname]]])
参数:
	host: SMTP服务器主机。你可以指定主机的ip地址或者域名字符串(本地'localhost').
	port: 如果你提供了host参数,你需要指定SMTP服务使用的端口号,一般情况下SMTP端口号为25
	local_hostname: 如果SMTP在你的本机上,你只需要指定服务器地址为localhost即可
Python SMTP对象使用sendmail方法发送邮件,语法如下:
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
参数:
	from_addr: 邮件发送者地址
	to_addrs:字符串列表,邮件发送地址
	msg:发送消息 字符串,邮件一般有标题,发信人,收信人,邮件内容,附件等构成,发送邮件的时候,
	要注意msg的格式。这个格式就是smtp协议中定义的格式。
"""
import smtplib
from email.mime.text import MIMEText
from email.header import Header

sender = 'smtp.mandrillapp.com'
receivers = ['aaa@qq.com'] #接受邮件,可以设置为你的QQ邮箱或者其他邮箱

# 三个参数: 第一个为文本内容,第二个plain设置文本格式,第三个utf-8设置编码
"""
MIME类型(Multipurpose Internet Mail Extensions)是描述消息内容类型的因特网标准
MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据
不同的应用程序支持不同的MIME类型 plain是纯文本格式
"""
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:
	print(type(message), message)
	smtpObj = smtplib.SMTP('localhost') 
	smtpObj.sendmail(sender, receivers, message.as_string())
	print('邮件发送成功')
except smtplib.SMTPException:
	print("Error: 无法发送邮件") 

"""
<class 'email.mime.text.MIMEText'> Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
From: =?utf-8?b?6I+c6bif5pWZ56iL?=
To: =?utf-8?b?5rWL6K+V?=
Subject: =?utf-8?b?UHl0aG9uIFNNVFDpgq7ku7bmtYvor5U=?=

UHl0aG9u6YKu5Lu25Y+R6YCB5rWL6K+VLi4u
可以看到打印出来的message这个MIME文本类,里面包含的内容是编码类型,数据类型,MIME版本,以及传输的编码格式base64,
下面是邮件的首发地址,可以看到这是用base64编码之后的地址

//这里出现由于目标计算机积极拒绝,无法连接错误的原因是,邮件服务器需要认证登陆,大家可以在linux或者win配置sendmail服务端,然后尝试
smtp = smtplib.SMTP_SSL(smtpserver, 465)
smtp.helo()
smtp.ehlo()
smtp.login(user, password)来认证 
"""

通过腾讯或其他的SMTP服务来发送邮箱

smtpremote.py

# -*- coding: utf-8 -*-
# @Author: Clarence
# @Date:   2018-09-10 11:25:25
# @Last Modified by:   Clarence
# @Last Modified time: 2018-09-10 16:54:15
"""
如果本机没有sendmail访问,可以使用其他服务商的SMTP访问(QQ、网易、Google等)
一个具体的STMP通信(如发送端邮件服务器与接收端服务器的通信)的过程如下:
1) 发送端邮件服务器(以下简称客户端)与接收端邮件服务器(以下简称服务器)的25号端口建立TCP连接
2) 客户端向服务器发送各种命令,来请求各种服务(如认证、指定发送人和接收人)
3)服务器解析用户的命令,做出相应动作并返回给客户端一个响应。
4) 2)和3)交替进行,知道所有邮件都发送完成或两者的连接被意外中断
"""
import smtplib
from email.mime.text import MIMEText
from email.header import Header

# 第三方SMTP服务
mail_host = "smtp.qq.com" # 设置服务器
#自己的邮箱,通过QQ邮箱设置获取口令
mail_user = "aaa@qq.com" #用户名
mail_pass = "xxxxxxxxxx" # 口令

sender = 'aaa@qq.com'
receivers = ['aaa@qq.com'] #接受者的邮箱,我的另一个QQ邮箱

'''
如果发送HTML格式的邮件,那么改变MIME类型就可以
发送HTML格式的邮件与发送纯文本消息的邮件不同之处就是将MIMEText中_subtype设置为html
mail_msg = """
<p>Python 邮件发送测试...<p>
<p><a href="http://www.baidu.com">这是一个链接</a></p>
"""
message=MIMEText(mail_msg, 'html', 'utf-8')
'''

# class email.mime.text.MIMEText(_text[, _subtype[, _charset]]) 用于创建主要类型文本的MIME对象,_text是有效负载的字符串,_subtype
# 是次要类型,默认为plain._charset是文本的字符集
message  = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')
message['From'] = Header("菜鸟教程", 'utf-8')
message['To'] = Header("aaa@qq.com", 'utf-8')

subject = 'Python SMTP  邮件测试'
message['Subject'] = Header(subject, 'utf-8')

try:
	smtpObj = smtplib.SMTP()
	smtpObj.connect(mail_host, 25) # 25为SMTP端口号
	smtpObj.login(mail_user, mail_pass) #会返回(状态码, "字符串解释")元组信息
	smtpObj.sendmail(sender, receivers, message.as_string())
	print("邮件发送成功")
except smtplib.SMTPException:
	print("Error: 无法发送邮件")

"""
<smtplib.SMTP object at 0x000001ED3DDFCE48>
邮件发送成功
[Finished in 2.9s] 
大家可以在QQ邮箱上设置中账号菜单设置开启STMP服务,然后获得口令,填入mail_pass,这里我就用xxxx表示口令,可以看到邮件发送成功 
注: sender和mail_user要相同,可能QQSTMP服务器需要知道真实的发送者,所以就这样
"""

发送带附件的邮件

sendAttachmentmail.py

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

# 第三方SMTP服务
mail_host = "smtp.qq.com" # 设置服务器
#自己的邮箱,通过QQ邮箱设置获取口令
mail_user = "aaa@qq.com" #用户名
mail_pass = "xxxxxxxxxxxx" # 口令

#这里sender和mail_user要一致,腾讯可能不让匿名发送邮件
sender = 'aaa@qq.com'
receivers = ['aaa@qq.com'] #接受者的邮箱

# 创建一个带附件的实例
message = MIMEMultipart()
message['From'] = Header("发送邮件者Clarence", 'utf-8')
message['To'] = Header("aaa@qq.com", 'utf-8')
subject = 'Python SMTP  邮件测试'
message['Subject'] = Header(subject, 'utf-8')

# 邮件正文内容
message.attach(MIMEText('这是smtp协议发送邮件测试有效负载内容....', 'plain', 'utf-8'))

# 构造附件1,传送当前目录下的test.txt文件,可以看出是直接读取文本二进制流
attr1 = MIMEText(open('test1.txt', 'rb').read(), 'base64', 'utf-8') 
"""
上行代码作用
Content-Type: text/base64; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
"""
attr1["Content_Type"] = 'application/octet-stream' # 内容是二进制流,不知道文件类型
# 
attr1["Content-Disposition"] = 'attachment; filename="send1.txt"' #Content-Disposition是MIME协议的扩展,支持MIME用户代理如何显示附加的文件
message.attach(attr1)

#构造附件2,传送当前目录下的test2.txt文件
attr2 = MIMEText(open('test2.txt', 'rb').read(), 'base64', 'utf-8')
attr2["Content_Type"] = 'application/octet-stream' 
attr2['Content-Disposition'] = 'attachment; filename="send2.txt'
message.attach(attr2)

try:
	smtpObj = smtplib.SMTP()
	smtpObj.connect(mail_host, 25) # 25为SMTP端口号
	smtpObj.login(mail_user, mail_pass) #会返回(状态码, "字符串解释")元组信息
	smtpObj.sendmail(sender, receivers, message.as_string())
	print(message)
	print("邮件发送成功")
except smtplib.SMTPException:
	print("Error: 无法发送邮件")

 

 python实现smtp协议发送邮件python实现smtp协议发送邮件

发送html且带图像

IncoToHtml.py

"""
在HTML文本中添加图片
"""
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.header import Header

# 第三方SMTP服务
mail_host = "smtp.qq.com" # 设置服务器
#自己的邮箱,通过QQ邮箱设置获取口令
mail_user = "aaa@qq.com" #用户名
mail_pass = "xxxxxx" # 口令

sender = 'aaa@qq.com'
receivers = ['aaa@qq.com'] #接受者的邮箱

# 创建一个带附件的实例
message = MIMEMultipart('related')
message['From'] = Header("发送邮件者Clarence", 'utf-8')
message['To'] = Header("aaa@qq.com", 'utf-8')
subject = 'Python SMTP  邮件测试'
message['Subject'] = Header(subject, 'utf-8')

msgAlternative = MIMEMultipart('alternative')
message.attach(msgAlternative)

mail_msg = """
<p>Python 邮件发送测试...</p>
<p><a href="https://deeplearning4j.org/">深度学习java框架链接</a></p>
<p>图片演示: </p>
<p><img src="cid:image1"></p>
"""
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))
# 指定图片为当前目录下test.png
fp = open('test.png', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()

# 定义图片ID, 在HTML文本中引用
msgImage.add_header('Content-ID', '<image1>')
message.attach(msgImage)

try:
	smtpObj = smtplib.SMTP()
	smtpObj.connect(mail_host, 25) # 25为SMTP端口号
	smtpObj.login(mail_user, mail_pass) #会返回(状态码, "字符串解释")元组信息
	smtpObj.sendmail(sender, receivers, message.as_string())
	print(message)
	print("邮件发送成功")
except smtplib.SMTPException:
	print("Error: 无法发送邮件")

python实现smtp协议发送邮件python实现smtp协议发送邮件

 

好,大家可以去我github查看项目,谢谢大家了https://github.com/youaresherlock