说说如何使用 Python 发送电子邮件

使用 Python 的 smtplib 模块,就可以实现发送邮件。

1 电子邮件服务器

如果是网易 163 邮箱,我们可以在浏览器中登陆 https://mail.163.com/ 邮箱后,依次点击 设置 → POP3/SMTP/IMAP ,进入服务器设置页:

进入服务器设置页后,确保开启 SMTP 与 IMAP 服务。设置页的最下面就是网易邮箱的服务器地址:

(1)SMTP

发送电子邮件使用的协议是简单邮件传输协议( SMTP ,Simple Mail Transfer Protocol)。它是一种提供可靠且有效的电子邮件传输的协议。 SMTP 是建立在 FTP 文件传输服务上的一种邮件服务,主要用于系统之间的邮件信息传递,并提供有关来信的通知。 SMTP 独立于特定的传输子系统,且只需要可靠有序的数据流信道支持, SMTP 的重要特性之一是其能跨越网络传输邮件,即“ SMTP 邮件中继 ”。 使用 SMTP ,可实现相同网络处理进程之间的邮件传输,也可通过中继器或网关实现某处理进程与其他网络之间的邮件传输。

(2)IMAP

IMAP(Internet Mail Access Protocol)以前称作交互邮件访问协议(Interactive Mail Access Protocol),是一个应用层协议。IMAP是斯坦福大学在1986年开发的一种邮件获取协议。它的主要作用是邮件客户端可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。当前的权威定义是RFC3501。IMAP协议运行在TCP/IP协议之上,使用的端口是143。

(3)POP3

POP3,全名为“Post Office Protocol - Version 3”,即“邮局协议版本3”。是TCP/IP协议族中的一员,由RFC1939 定义。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。提供了SSL加密的POP3协议被称为POP3S。

POP 协议支持 “ 离线 ” 邮件处理。其具体过程是:邮件发送到服务器上,电子邮件客户端调用邮件客户机程序以连接服务器,并下载所有未阅读的电子邮件。这种离线访问模式是一种存储转发服务,将邮件从邮件服务器端送到个人终端机器上,一般是 PC 机或 MAC 。 一旦邮件发送到 PC 机或 MAC 上,邮件服务器上的邮件将会被删除。但 POP 3邮件服务器大都可以 “ 只下载邮件,服务器端并不删除 ” ,也就是改进的 POP 3协议。


IMAP 与 POP3 协议的主要区别是用户可以不用把所有的邮件全部下载,可以通过客户端直接对服务器上的邮件进行操作。所以相对来说,IMAP 协议更先进。

2 发送电子邮件

(1)创建 SMTP 对象

首先创建一个 SMTP 对象,入参为 163 邮箱地址与端口号:

smtp_obj = smtplib.SMTP('smtp.163.com', 25);

(2)建立连接

response = smtp_obj.ehlo()
logging.info('ehlo() -> %s', response)

运行结果:

INFO - ehlo() -> (250, b'mail\nPIPELINING\nAUTH LOGIN PLAIN\nAUTH=LOGIN PLAIN\ncoremail xxx\nSTARTTLS\n8BITMIME')

得到 SMTP 对象后,调用 ehlo() 方法,连接 SMTP 电子邮件服务器, 也就是 “ 打招呼 ”๑乛◡乛๑。

250 就表示连接成功。

SMTP 协议有以下这些响应码,每个响应码的具体说明如下:

响应码 说明
501 参数格式错误
502 命令不可实现
503 错误的命令序列
504 命令参数不可实现
211 系统状态或系统帮助响应
214 帮助信息
220 <domain>服务就绪
221 <domain>服务关闭
421 <domain>服务未就绪,关闭传输信道
250 操作完成
251 用户非本地,将转发到<forward-path>
450 要求的操作未完成,收信端无此账户
550 要求的操作未完成,邮箱不可用
451 放弃要求的操作;处理过程中出错
551 用户非本地,请尝试<forward-path>
452 系统存储不足,要求的操作未执行
552 过量的存储分配,要求的操作未执行
553 邮箱名不可用,要求的操作未执行
554 操作失败

(3)TLS 加密

网易邮箱的 POP3/SMTP/IMAP 服务全部支持 SSL 连接。

安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。

传输层安全性协议( Transport Layer Security ,缩写作 TLS ),及其前身安全套接层( Secure Sockets Layer ,缩写作 SSL )是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。网景公司( Netscape )在 1994 年推出首版网页浏览器,网景导航者时,推出 HTTPS 协议,以 SSL 进行加密,这是 SSL 的起源 。IETF 将 SSL 进行标准化, 1999 年公布第一版 TLS 标准文件。随后又公布 RFC5246 ( 2008 年8月)与 RFC6176 ( 2011 年3月)。在浏览器 、 邮箱 、 即时通信 、 VoIP 、 网络传真等应用程序中,广泛支持这个协议。主要的网站,如Google 、 Facebook等也以这个协议来创建安全连线,发送数据。目前已成为互联网上保密通信的工业标准。

response = smtp_obj.starttls()
logging.info('starttls() -> %s\n', response)

运行结果:

INFO - starttls() -> (220, b'Ready to start TLS')

响应码 220 表示服务器已开启 TLS 加密模式。

(4)登陆 SMTP 服务器

建立 TLS 加密连接后,就可以调用 login() 方法,用邮箱账户名与密码进行登录操作。建议使用 input() ,在程序运行时输入密码。这样做的好处是,避免因为源代码泄露,导致密码外泄。

email_address = xxx@xxx.com'
pwd = input('please input your password:')

response = smtp_obj.login(email_address, pwd)
logging.info('\nlogin() -> %s', response)

运行结果:

please input your password:> xxx
INFO - 
login() -> (235, b'Authentication successful')

login 方法接收账号与密码作为入参。这里返回 235 表示认证成功。如果密码不正确, Python 会抛出 smtplib.SMTPAuthenticationError 异常。

(5)定义发送内容

msg = MIMEMultipart()
msg["From"] = email_address
to_mail_address = yyy@yyy.com'
msg['To'] = to_mail_address
msg['Subject'] = '确认《Spring Cloud微服务架构》'
content = MIMEText('收到这本书后,<b>请回复下</b>', 'html', 'utf-8')
msg.attach(content)

先创建 MIMEMultipart 对象,然后定义以下内容:

说明
From 发送端邮箱地址。
To 接收端邮箱地址。
Subject 邮箱标题。
content 邮箱内容,HTML 格式。

(6)发送邮件

response = smtp_obj.sendmail(email_address, to_mail_address, msg.as_string())
logging.info('sendmail() -> %s', response)

运行结果:

INFO - sendmail() -> {}

然后调用 sendmail()方法来发送电子邮件。 sendmail() 的返回值是一个字典类型。如果发送失败,那么该字典就会返回包含失败收件人的键值对信息;如果发送成功,那么该字典为空。

(7)断开连接

response = smtp_obj.quit()
logging.info('quit() -> %s', response)

运行结果:

INFO - quit() -> (221, b'Bye')

发送电子邮件后,调用 quit()方法,断开与 SMTP 服务器的连接。 响应码 221 表示会话结束。


完整示例如下:

import logging
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

logging.basicConfig(level=logging.DEBUG, format='%(levelname)s - %(message)s')

'''
send email
@author Deniro Lee
'''
print('$$$')
smtp_obj = smtplib.SMTP('smtp.163.com', 25);
response = smtp_obj.ehlo()
logging.info('ehlo() -> %s', response)
response = smtp_obj.starttls()
logging.info('starttls() -> %s\n', response)

email_address = xxx@xxx.com'
pwd = input('please input your password:')

response = smtp_obj.login(email_address, pwd)
logging.info('\nlogin() -> %s', response)

msg = MIMEMultipart()
msg["From"] = email_address
to_mail_address = yyy@yyy.com'
msg['To'] = to_mail_address
msg['Subject'] = '确认《Spring Cloud微服务架构》'
content = MIMEText('收到这本书后,<b>请回复下</b>', 'html', 'utf-8')
msg.attach(content)

response = smtp_obj.sendmail(email_address, to_mail_address, msg.as_string())
logging.info('sendmail() -> %s', response)

response = smtp_obj.quit()
logging.info('quit() -> %s', response)

运行结果:

INFO - ehlo() -> (250, b'mail\nPIPELINING\nAUTH LOGIN PLAIN\nAUTH=LOGIN PLAIN\ncoremail xxx\nSTARTTLS\n8BITMIME')
INFO - starttls() -> (220, b'Ready to start TLS')
please input your password:> xxx
INFO - 
login() -> (235, b'Authentication successful')
INFO - sendmail() -> {}
INFO - quit() -> (221, b'Bye')

打开发送目标邮箱后,就会看到刚刚发出的这封邮件:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,392评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,258评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,417评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,992评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,930评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,199评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,652评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,327评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,463评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,382评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,432评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,118评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,704评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,787评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,999评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,476评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,057评论 2 341