Python_09_SMTP邮件服务

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服务器连接











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值