首页 后端开发 Python教程 Python3如何使用SMTP协议发送E-mail电子邮件的示例

Python3如何使用SMTP协议发送E-mail电子邮件的示例

Oct 02, 2017 am 09:43 AM
python3 smtp 协议

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。下面这篇文章主要给大家介绍了关于Python3如何利用SMTP协议发送E-mail电子邮件的方法,需要的朋友可以参考下。

前言

本文主要给大家介绍了关于Python3用SMTP协议发送电子邮件的相关内容,在介绍如何使用python程序向指定邮箱发送邮件之前,我们需要先介绍一下有关电子邮件的相关知识。

Email的历史比Web还要久远,直到现在,Email也是互联网上应用非常广泛的服务。

几乎所有的编程语言都支持发送和接收电子邮件,但是,先等等,在我们开始编写代码之前,有必要搞清楚电子邮件是如何在互联网上运作的。

假设我们自己的电子邮件地址是me@163.com,对方的电子邮件地址是friend@sina.com,现在我们用Outlook或者Foxmail之类的软件写好邮件,填上对方的Email地址,点“发送”,电子邮件就发出去了。这些电子邮件软件被称为MUA:Mail User Agent——邮件用户代理。

Email从MUA发出去,不是直接到达对方电脑,而是发到MTA:Mail Transfer Agent——邮件传输代理,就是那些Email服务提供商,比如网易、新浪等等。由于我们自己的电子邮件是163.com,所以,Email首先被投递到网易提供的MTA,再由网易的MTA发到对方服务商,也就是新浪的MTA。这个过程中间可能还会经过别的MTA,但是我们不关心具体路线,我们只关心速度。

Email到达新浪的MTA后,由于对方使用的是@sina.com的邮箱,因此,新浪的MTA会把Email投递到邮件的最终目的地MDA:Mail Delivery Agent——邮件投递代理。Email到达MDA后,就静静地躺在新浪的某个服务器上,存放在某个文件或特殊的数据库里,我们将这个长期保存邮件的地方称之为电子邮箱。对方要取到邮件,必须通过MUA从MDA上把邮件取到自己的电脑上。

所以,一封电子邮件的旅程就是:

发件人 -> MUA -> MTA -> MTA -> 若干个MTA -> MDA <- MUA <- 收件人

有了上述基本概念,要编写程序来发送和接收邮件,本质上就是:

      1.编写MUA把邮件发到MTA。

      2.编写MUA从MDA上收邮件。

发邮件时,MUA和MTA使用的协议就是SMTP:Simple Mail Transfer Protocol,后面的MTA到另一个MTA也是用SMTP协议。

收邮件时,MUA和MDA使用的协议有两种:POP:Post Office Protocol,目前版本是3,俗称POP3;IMAP:Internet Message Access Protocol,目前版本是4,优点是不但能取邮件,还可以直接操作MDA上存储的邮件,比如从收件箱移到垃圾箱,等等。

邮件客户端软件在发邮件时,会让你先配置SMTP服务器,也就是你要发到哪个MTA上。假设你正在使用163的邮箱,你就不能直接发到新浪的MTA上,因为它只服务新浪的用户,所以,你得填163提供的SMTP服务器地址:smtp.163.com,为了证明你是163的用户,SMTP服务器还要求你填写邮箱地址和邮箱口令,这样,MUA才能正常地把Email通过SMTP协议发送到MTA。

类似的,从MDA收邮件时,MDA服务器也要求验证你的邮箱口令,确保不会有人冒充你收取你的邮件,所以,Outlook之类的邮件客户端会要求你填写POP3或IMAP服务器地址、邮箱地址和口令,这样,MUA才能顺利地通过POP或IMAP协议从MDA取到邮件。

最后特别注意:目前大多数邮件服务商都需要手动打开SMTP发信和POP收信的功能,否则只允许在网页登录:

比如QQ邮箱

接下来,我们开始我们的正题,如何通过python发送电子邮件。

--------------------------------------------------------------------------------

发送简单文本邮件

SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。

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

首先,我们来构造一个最简单的纯文本邮件:


from email.mime.text import MIMEText
msg = MIMEText(&#39;hello, this is axin...&#39;, &#39;plain&#39;, &#39;utf-8&#39;)
登录后复制

注意:到构造MIMEText对象时,第一个参数就是邮件正文,第二个参数是MIME的subtype,传入'plain'表示纯文本,最终的MIME就是'text/plain',最后一定要用utf-8编码保证多语言兼容性。

我们光有了正文内容还不可以,我们还需要给我们要发送的邮件添加头部信息。头部信息中包含发送者和接收者以及邮件主题等信息。


msg = MIMEText(&#39;hello, this is axin...&#39;, &#39;plain&#39;, &#39;utf-8&#39;) #邮件正文
msg[&#39;From&#39;] = _format_addr(&#39;阿鑫 <%s>&#39; % from_addr) #邮件头部,发送者信息
msg[&#39;To&#39;] = _format_addr(&#39;aa <%s>&#39; % to_addr) #接收者信息
msg[&#39;Subject&#39;] = Header(&#39;test&#39;, &#39;utf-8&#39;).encode() #邮件主题
登录后复制

构造完我们要发送的信息后,我们只需要调用python对应的函数,通过SMTP发出去:


server = smtplib.SMTP(smtp_server, 25) #SMTP协议默认端口是25
server.set_debuglevel(1) #打印出和SMTP服务器交互的所有信息
server.login(from_addr, password) #登录SMTP服务器
server.sendmail(from_addr, [to_addr], msg.as_string()) #发送邮件
server.quit()
登录后复制

我们用set_debuglevel(1)就可以打印出和SMTP服务器交互的所有信息。SMTP协议就是简单的文本命令和响应。login()方法用来登录SMTP服务器,sendmail()方法就是发邮件,由于可以一次发给多个人,所以传入一个list,邮件正文是一个str,as_string()把MIMEText对象变成str。

完整代码示例如下:


from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr

import smtplib

def _format_addr(s): #格式化一个邮件地址
name, addr = parseaddr(s)
return formataddr((Header(name, &#39;utf-8&#39;).encode(), addr))

from_addr = &#39;fengxinlinux@sina.com&#39; #发送者邮箱地址
password = &#39;******&#39; #发送者邮箱密码,不告诉你密码=。=
to_addr = &#39;903087053@qq.com&#39; #接收者邮箱地址
smtp_server = &#39;smtp.sina.com&#39; #发送者所在的邮箱供应商的MTA地址
#from_addr = input(&#39;From: &#39;)
#password = input(&#39;Password: &#39;)
#to_addr = input(&#39;To: &#39;)
#smtp_server = input(&#39;SMTP server: &#39;)

msg = MIMEText(&#39;hello, this is axin...&#39;, &#39;plain&#39;, &#39;utf-8&#39;) #邮件正文
msg[&#39;From&#39;] = _format_addr(&#39;阿鑫 <%s>&#39; % from_addr) #邮件头部,发送者信息
msg[&#39;To&#39;] = _format_addr(&#39;axin <%s>&#39; % to_addr) #接收者信息
msg[&#39;Subject&#39;] = Header(&#39;test&#39;, &#39;utf-8&#39;).encode() #邮件主题


server = smtplib.SMTP(smtp_server, 25) # SMTP协议默认端口是25
server.set_debuglevel(1) #打印出和SMTP服务器交互的所有信息
server.login(from_addr, password) #登录SMTP服务器
server.sendmail(from_addr, [to_addr], msg.as_string()) #发送邮件
server.quit()
1
登录后复制

运行程序,我们会发现我测试的邮箱中收到了一封新的邮件。

我们会发现,其他的信息都一样,但是收件人的信息不是我们程序里填写的axin。

因为很多邮件服务商在显示邮件时,会把收件人名字自动替换为用户注册的名字,但是其他收件人名字的显示不受影响。

我在测试时,有时候发送的邮件会被邮件服务商判定为垃圾邮件,直接被放到垃圾箱中了。。。至于什么情况会被认定为垃圾邮件,我也摸不到头绪。。

发送带附件的邮件

上面我们介绍了如何发送文本邮件,有了上面的知识后,发送带有附件的邮件其实也非常的简单。

带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,所以,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面加上一个MIMEText作为邮件正文,再继续往里面加上表示附件的MIMEBase对象即可:


# 邮件对象:
msg= MIMEMultipart()
msg[&#39;From&#39;] = _format_addr(&#39;阿鑫 <%s>&#39; % from_addr) #邮件头部,发送者信息
msg[&#39;To&#39;] = _format_addr(&#39;axin <%s>&#39; % to_addr) #接收者信息
msg[&#39;Subject&#39;] = Header(&#39;test&#39;, &#39;utf-8&#39;).encode() #邮件主题

# 邮件正文是MIMEText:
msg.attach(MIMEText(&#39;hello, this is axin...&#39;, &#39;plain&#39;, &#39;utf-8&#39;))

# 添加附件就是加上一个MIMEBase,从本地读取一个图片:
with open(&#39;/home/fengxin/图片/11.jpg&#39;,&#39;rb&#39;) as fhandle:
mime = MIMEBase(&#39;image&#39;,&#39;jpeg&#39;,filename=&#39;11.jpg&#39;)
mime.add_header(&#39;Content-Disposition&#39;, &#39;attachment&#39;, filename=&#39;11.jpg&#39;)
mime.add_header(&#39;Content-ID&#39;, &#39;<0>&#39;)
mime.add_header(&#39;X-Attachment-Id&#39;, &#39;0&#39;)
# 把附件的内容读进来:
mime.set_payload(fhandle.read())
# 用Base64编码:
encoders.encode_base64(mime)
# 添加到MIMEMultipart:
msg.attach(mime)
登录后复制

然后,按正常发送流程把msg(注意类型已变为MIMEMultipart)发送出去,就可以收到带附件的邮件。

完整代码示例如下:


from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase


import smtplib

def _format_addr(s): #格式化一个邮件地址
name, addr = parseaddr(s)
return formataddr((Header(name, &#39;utf-8&#39;).encode(), addr))

from_addr = &#39;你的邮箱地址&#39; #发送者邮箱地址
password = &#39;你的邮箱密码&#39; #发送者邮箱密码
to_addr = &#39;903087053@qq.com&#39; #接收者邮箱地址
smtp_server = &#39;smtp.sina.com&#39; #发送者所在的邮箱供应商的MTA地址
#from_addr = input(&#39;From: &#39;)
#password = input(&#39;Password: &#39;)
#to_addr = input(&#39;To: &#39;)
#smtp_server = input(&#39;SMTP server: &#39;)


msg= MIMEMultipart()
msg[&#39;From&#39;] = _format_addr(&#39;阿鑫 <%s>&#39; % from_addr) #邮件头部,发送者信息
msg[&#39;To&#39;] = _format_addr(&#39;axin <%s>&#39; % to_addr) #接收者信息
msg[&#39;Subject&#39;] = Header(&#39;test&#39;, &#39;utf-8&#39;).encode() #邮件主题

msg.attach(MIMEText(&#39;hello, this is axin...&#39;, &#39;plain&#39;, &#39;utf-8&#39;))

with open(&#39;/home/fengxin/图片/11.jpg&#39;,&#39;rb&#39;) as fhandle:
mime = MIMEBase(&#39;image&#39;,&#39;jpeg&#39;,filename=&#39;11.jpg&#39;)
mime.add_header(&#39;Content-Disposition&#39;, &#39;attachment&#39;, filename=&#39;11.jpg&#39;)
mime.add_header(&#39;Content-ID&#39;, &#39;<0>&#39;)
mime.add_header(&#39;X-Attachment-Id&#39;, &#39;0&#39;)
# 把附件的内容读进来:
mime.set_payload(fhandle.read())
# 用Base64编码:
encoders.encode_base64(mime)
# 添加到MIMEMultipart:
msg.attach(mime)

server = smtplib.SMTP(smtp_server, 25) # SMTP协议默认端口是25
server.set_debuglevel(1) #打印出和SMTP服务器交互的所有信息
server.login(from_addr, password) #登录SMTP服务器
server.sendmail(from_addr, [to_addr], msg.as_string()) #发送邮件
server.quit()
1
登录后复制

运行后。测试邮箱正确收到邮件,如图:

总结

以上是Python3如何使用SMTP协议发送E-mail电子邮件的示例的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

vivo快充属于哪个协议 vivo快充属于哪个协议 Sep 06, 2022 pm 02:43 PM

vivo快充主要有两个协议:1、“QC 2.0”快充协议,“QC2.0”就是“Quick Charge 2.0”技术,是高通公司发布的快充技术2.0版本,可以输出5V、9V、12V、20V四组电压;2、PD快充协议,是由“USB-IF”组织制定的一种快速充电规范,是目前主流的快充协议之一,可以使目前默认最大功率“5V/2A”的“type-c”接口提高到100W。

pd3.0快充协议最高多少w pd3.0快充协议最高多少w Nov 08, 2022 pm 04:04 PM

pd3.0快充协议最高支持“100W”。2015年11月,USB PD快充迎来了大版本更新,进入到了USB PD3.0快充时代;PD3.0协议支持5V3A、9V3A、12V3A、15V3A、20V5A输出,最大功率可以到100W,不仅可以用在手机充电上,还可以用给笔记本或者是显示器供电。

5种工业通讯协议是什么 5种工业通讯协议是什么 Sep 28, 2022 am 11:52 AM

5种工业通讯协议:1、Modbus协议,是应用于电子控制器上的一种通用语言;2、RS-232协议,是一种串行物理接口标准;3、RS-485协议,是在RS232的基础上发展来的;4、HART协议,是一种用于现场智能仪表和控制室设备之间的通信协议;5、MPI协议,是一个跨语言的通讯协议,用于编写并行计算机。

PHP中的SOAP协议指南 PHP中的SOAP协议指南 May 20, 2023 pm 07:10 PM

随着互联网技术的不断发展,越来越多的企业级应用需要向其它应用程序提供接口以实现数据和业务的交互。在这种情况下,我们需要一种可靠的协议来传输数据并确保数据的完整性和安全性。SOAP(SimpleObjectAccessProtocol)就是一种基于XML的协议,可用于在Web环境中实现应用之间的通信。而PHP作为一种流行的Web编程语言,

php怎么禁止smtp邮件功能 php怎么禁止smtp邮件功能 Mar 22, 2023 pm 03:22 PM

PHP是一种强大的编程语言,广泛应用于Web开发领域中,其中SMTP邮件功能也是PHP开发中的重要一环。但是,在某些情况下,您可能希望禁止SMTP邮件功能,本文将介绍如何实现。

qc4+快充协议是什么 qc4+快充协议是什么 Aug 18, 2022 pm 03:49 PM

QC4+快充协议是USB PD PPS协议和QC3.0/2.0快充协议的综合体,是一种多功能、多协议的快充技术。QC4+充电协议对USB PD3.0(PPS)进行了兼容,同时向下兼容USB PD2.0、QC3.0、QC2.0、BC1.2等协议。支持USB PD、QC4+的首要前提,是两端均有USB-C接口的支持和基于USB-C接口中的CC(配置通道)的电力协商报文。

x.25协议采用的是什么技术 x.25协议采用的是什么技术 Jul 18, 2022 pm 04:05 PM

“x.25”协议采用的是分组交换技术;“x.25”协议是面向计算机的数据通讯网,由传输线路、分组交换机、远程集中器和分组终端等基本设备组成,采用分层的体系结构,在接口的对等层之间通过对等层之间的通信协议进行信息交换的协商、控制和信息的传输。

Windows将在不久的将来停用TLS 1.0和TLS 1.1 Windows将在不久的将来停用TLS 1.0和TLS 1.1 Aug 12, 2023 am 11:37 AM

Microsoft计划在Windows中禁用传输层安全性(TLS)协议版本1.0和1.1。该公司于1年2023月日在其技术社区网站上宣布了这一消息。这两个协议可以追溯到1999年(TLS1.0)和2006年(TLS1.1),此后被新版本TLS1.2和TLS1.3超越。Microsoft指出,在较旧的协议版本中发现了安全问题,并且“互联网标准和监管机构已弃用或不允许TLS版本1.0和1.1作为响应。多年来,TLS1.0和1.1的使用量显着下降,Microsoft认为禁用这两种协议的时候到了。Mic

See all articles