您的位置:首页 > 编程语言 > Python开发

Python_09_SMTP邮件服务

2018-01-11 10:54 253 查看
Python高级编程之SMTP邮件服务


Python SMTP发送邮件

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

python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。

Python创建 SMTP 对象语法如下:
import smtplib

smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )


参数说明:

host: SMTP 服务器主机。 你可以指定主机的ip地址或者域名如: baidu.com,这个是可选参数。

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 是字符串,表示邮件。邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意 msg 的格式。这个格式就是 smtp 协议中定义的格式。


实例

首先开启并设置用于发件的QQ邮箱SMTP服务

如有问题,可点击这个Q&A



然后就是Python代码,使用QQ的SMTP服务,利用授权码,创建SMTP_SSL连接,发送邮件:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
mailSender = 'XXXXXXXX@qq.com'
# QQ邮箱帐户的提供的授权码
securityCode = 'cvfqrxroexaupajgd'
mailTarget = 'XXXXXXXX@qq.com'
def mail():
ret = True
try:
msg = MIMEText('这是邮件内容','plain','utf-8')
msg['From'] = formataddr(["这是发件人昵称",mailSender])
msg['To'] = formataddr(["这是收件人昵称",mailTarget])
# 邮件的主题(标题)
msg['Subject'] = "这是邮件Subject"

# 发件人QQ邮箱中的SMTP服务器,端口
server = smtplib.SMTP_SSL("smtp.qq.com", 465)
# 登录并发送
server.login(mailSender, securityCode)
server.sendmail(mailSender,[mailTarget,],msg.as_string())
server.quit()
except Exception as s:
ret = False
print "fail:",s
return ret

ret = mail()
if ret:
print("邮件发送成功")
else:
print("邮件发送失败")

效果如下 :



使用新浪的SMTP服务器,创建非SSL连接,发送邮件

1.先到sina邮箱打开smtp设置,如图所示



2.python代码如下:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import smtplib
#创建普通的SMTP(非SSL)
service = smtplib.SMTP("smtp.sina.cn",25)
#打印出和SMTP服务器交互的所有信息。SMTP协议就是简单的文本命令和响应
service.set_debuglevel(1)
#登录SMTP服务器
mailSender = "xxxxxx@sina.cn"
mailTarget = "yyyyyyy@qq.com"
service.login(mailSender,"passcode")

from email.mime.text import MIMEText
from email.utils import formataddr
#邮件正文
msg = MIMEText('这是邮件内容','plain','utf-8')
msg['From'] = formataddr(["这是发件人昵称",mailSender])
msg['To'] = formataddr(["这是收件人昵称",mailTarget])
# 邮件的主题(标题)
msg['Subject'] = "这是邮件Subject"
#发送邮件
try:
service.sendmail(mailSender,[mailTarget,],msg.as_string())
except Exception as s:
print "Error: 无法发送邮件:",s


CMD运行Python smtp_4.py后,中间连接步骤消息打印如下 :

beyondnoMacBookPro:~ beyond$ python /Users/beyond/sg_python/smtp_4.py 
send: 'ehlo 1.0.0.127.in-addr.arpa\r\n'
reply: '250-smtp-5-123.smtpsmail.fmail.xd.sinanode.com\r\n'
reply: '250-AUTH LOGIN PLAIN\r\n'
reply: '250-AUTH=LOGIN PLAIN\r\n'
reply: '250-STARTTLS\r\n'
reply: '250 8BITMIME\r\n'
reply: retcode (250); Msg: smtp-5-123.smtpsmail.fmail.xd.sinanode.com
AUTH LOGIN PLAIN
AUTH=LOGIN PLAIN
STARTTLS
8BITMIME
send: 'AUTH PLAIN AGl4aXhpaUBzaW5hLmNuADEyMzQ1Nk9v\r\n'
reply: '235 OK Authenticated\r\n'
reply: retcode (235); Msg: OK Authenticated
send: 'mail FROM:<xxxxx@sina.cn>\r\n'
reply: '250 ok\r\n'
reply: retcode (250); Msg: ok
send: 'rcpt TO:<yyyyy@qq.com>\r\n'
reply: '250 ok\r\n'
reply: retcode (250); Msg: ok
send: 'data\r\n'
reply: '354 End data with <CR><LF>.<CR><LF>\r\n'
reply: retcode (354); Msg: End data with <CR><LF>.<CR><LF>
data: (354, 'End data with <CR><LF>.<CR><LF>')
send: 'Content-Type: text/plain; charset="utf-8"\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: base64\r\nFrom: \xe8\xbf\x99\xe6\x98\xaf\xe5\x8f\x91\xe4\xbb\xb6\xe4\xba\xba\xe6\x98\xb5\xe7\xa7\xb0 <xxxxx@sina.cn>\r\nTo: \xe8\xbf\x99\xe6\x98\xaf\xe6\x94\xb6\xe4\xbb\xb6\xe4\xba\xba\xe6\x98\xb5\xe7\xa7\xb0
<yyyyy@qq.com>\r\nSubject: \xe8\xbf\x99\xe6\x98\xaf\xe9\x82\xae\xe4\xbb\xb6Subject\r\n\r\n6L+Z5piv6YKu5Lu25YaF5a65\r\n.\r\n'
reply: '250 ok queue id 733794444351\r\n'
reply: retcode (250); Msg: ok queue id 733794444351
data: (250, 'ok queue id 733794444351')

效果如下:





QQ的SMTP只能使用SSL连接,代码极其类似:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import smtplib
#QQ只能创建SMTP_SSL
service = smtplib.SMTP_SSL("smtp.qq.com",465)#方法换成SMTP_SSL,端口从25换成465
#打印出和SMTP服务器交互的所有信息。SMTP协议就是简单的文本命令和响应
service.set_debuglevel(1)
#登录SMTP服务器
mailSender = "xxxx@qq.com"
mailTarget = "yyyy@qq.com"
pwd = "etmnhjmgqkymajia"#密码换成授权码
service.login(mailSender,pwd)

from email.mime.text import MIMEText
from email.utils import formataddr
#邮件正文
msg = MIMEText('这是邮件内容','plain','utf-8')
msg['From'] = formataddr(["这是发件人昵称",mailSender])
msg['To'] = formataddr(["这是收件人昵称",mailTarget])
# 邮件的主题(标题)
msg['Subject'] = "这是邮件Subject"
#发送邮件
try:
service.sendmail(mailSender,[mailTarget,],msg.as_string())
except Exception as s:
print "Error: 无法发送邮件:",s


发送HTML邮件:


使用Python发送HTML格式的邮件

Python发送HTML格式的邮件与发送纯文本消息的邮件不同之处就是将MIMEText中第2个参数_subtype由plain改为html。具体代码如下:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
#发送HTML

import smtplib
#QQ只能创建SMTP_SSL
service = smtplib.SMTP_SSL("smtp.qq.com",465)
#打印出和SMTP服务器交互的所有信息。SMTP协议就是简单的文本命令和响应
service.set_debuglevel(1)
#登录SMTP服务器
mailSender = "xxx@qq.com"
mailTarget = "yyy@qq.com"
pwd = "etmnhjmgqkymajia"
service.login(mailSender,pwd)

from email.mime.text import MIMEText
from email.utils import formataddr
#邮件正文(plain,html)
mailContent = """
<p>html格式的内容</p>
<p><a href="http://www.baidu.com">百度一下</a></p>
"""
msg = MIMEText(mailContent,'html','utf-8')
msg['From'] = formataddr(["这是发件人昵称",mailSender])
msg['To'] = formataddr(["这是收件人昵称",mailTarget])
# 邮件的主题(标题)
msg['Subject'] = "这是邮件Subject"
#发送邮件
try:
service.sendmail(mailSender,[mailTarget,],msg.as_string())
except Exception as s:
print "Error: 无法发送邮件:",s

效果如下:





发送带附件的邮件:

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

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#发送带附件的邮件

import smtplib
#QQ只能创建SMTP_SSL
service = smtplib.SMTP_SSL("smtp.qq.com",465)
#打印出和SMTP服务器交互的所有信息。SMTP协议就是简单的文本命令和响应
service.set_debuglevel(1)
#登录SMTP服务器
mailSender = "xxx@qq.com"
mailTarget = "yyy@qq.com"
pwd = "etmnhjmgqkymajia"
service.login(mailSender,pwd)

from email.mime.text import MIMEText
from email.utils import formataddr
#附件
from email.mime.multipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email import encoders

#邮件正文(plain,html)
mailContent = "带附件的邮件正文"
msgMulti = MIMEMultipart();
msgMulti['From'] = formataddr(["这是发件人昵称",mailSender])
msgMulti['To'] = formataddr(["这是收件人昵称",mailTarget])
# 邮件的主题(标题)
msgMulti['Subject'] = "这是带附件邮件的Subject"
# attach正文
msgMulti.attach(MIMEText(mailContent,'plain','utf-8'))
# attach附件1
# 添加附件就是加上一个MIMEBase,从本地读取一个图片:
with open('/Users/beyond/sg_python/iscream.jpg', 'rb') as iscreamImg:
# 设置附件的MIME和文件名,这里是png类型:
mimeFile = MIMEBase('image', 'png', filename='iscream.jpg')
# 加上必要的头信息:
mimeFile.add_header('Content-Disposition', 'attachment', filename='iscream.jpg')
mimeFile.add_header('Content-ID', '<0>')
mimeFile.add_header('X-Attachment-Id', '0')
# 把附件的内容读进来:
mimeFile.set_payload(iscreamImg.read())
# 用Base64编码:
encoders.encode_base64(mimeFile)
# 添加到MIMEMultipart:
msgMulti.attach(mimeFile)

# attach附件2
mimeFile2 = MIMEText(open('/Users/beyond/sg_python/QQ.dmg', 'rb').read(), 'base64', 'utf-8')
mimeFile2["Content-Type"] = 'application/octet-stream'
mimeFile2["Content-Disposition"] = 'attachment; filename="QQ.dmg"'
msgMulti.attach(mimeFile2)

#发送邮件
try:
service.sendmail(mailSender,[mailTarget,],msgMulti.as_string())
except Exception as s:
print "Error: 无法发送邮件:",s


运行效果如下:





附Python的SMTP模块详细函数参数摘要:

对于Python来说,需要编写脚本调用邮件服务器来发送邮件,使用的协议是SMTP。接收邮件,使用的协议是POP3和IMAP。 

POP3和IMAP的区别:POP3在客户端邮箱中所做的操作不会反馈到邮箱服务器,比如删除一封邮件,邮箱服务器并不会删除。

IMAP则会反馈到邮箱服务器,会做相应的操作。

Python分别提供了收发邮件的库,smtplib、poplib和imaplib。

在smtplib库中,主要主要用smtplib.SMTP_SSL()类,用于连接SMTP服务器,发送邮件。

这个类有几个常用的方法:
方法
描述
SMTP.set_debuglevel(level)设置输出debug调试信息,默认不输出
SMTP.docmd(cmd[, argstring])发送一个命令到SMTP服务器
SMTP.connect([host[, port]])连接到指定的SMTP服务器
SMTP.helo([hostname])使用helo指令向SMTP服务器确认你的身份
SMTP.ehlo(hostname)使用ehlo指令像ESMTP(SMTP扩展)确认你的身份
SMTP.ehlo_or_helo_if_needed()如果在以前的会话连接中没有提供ehlo或者helo指令,这个方法会调用ehlo()或helo()
SMTP.has_extn(name)判断指定名称是否在SMTP服务器上
SMTP.verify(address)判断邮件地址是否在SMTP服务器上
SMTP.starttls([keyfile[, certfile]])使SMTP连接运行在TLS模式,所有的SMTP指令都会被加密
SMTP.login(user, password)登录SMTP服务器
SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])发送邮件

from_addr:邮件发件人

to_addrs:邮件收件人

msg:发送消息
SMTP.quit()关闭SMTP会话
SMTP.close()关闭SMTP服务器连接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Python SMTP Mail 邮件