北京电子商务app网站建设大兴,公司官网的意义,销售网站开发意义,小型门户网站建设硬件配置转载请注明原文出自 http://blog.csdn.net/zhaoweikid/ python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。smtp协议的基本命令包括#xff1a; HELO 向服务器标识用户身份 MAIL 初始化邮件传输 mail from: RCPT 标识单个的邮件…转载请注明原文出自 http://blog.csdn.net/zhaoweikid/ python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。smtp协议的基本命令包括 HELO 向服务器标识用户身份 MAIL 初始化邮件传输 mail from: RCPT 标识单个的邮件接收人常在MAIL命令后面,可有多个rcpt to: DATA 在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以.结束 VRFY 用于验证指定的用户/邮箱是否存在由于安全方面的原因,服务器常禁止此命令 EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用 HELP 查询服务器支持什么命令 NOOP 无操作,服务器应响应OK QUIT 结束会话 RSET 重置会话,当前传输被取消 MAIL FROM 指定发送者地址 RCPT TO 指明的接收者地址 一般smtp会话有两种方式一种是邮件直接投递就是说比如你要发邮件給zzz163.com那就直接连接163.com的邮件服务器把信投給zzz163.com; 另一种是验证过后的发信它的过程是比如你要发邮件給zzz163.com你不是直接投到163.com而是通过自己在sina.com的另一个邮箱来发。这样就要先连接sina.com的smtp服务器然后认证之后在把要发到163.com的信件投到sina.com上sina.com会帮你把信投递到163.com。 第一种方式的命令流程基本是这样 1. helo 2. mail from 3. rcpt to 4. data 5. quit 但是第一种发送方式一般有限制的就是rcpt to指定的这个邮件接收者必须在这个服务器上存在否则是不会接收的。 先看看代码 #-*- encoding: gb2312 -*-import os, sys, stringimport smtplib# 邮件服务器地址mailserver smtp.163.com# smtp会话过程中的mail from地址from_addr asfgysgzxsdf.com# smtp会话过程中的rcpt to地址to_addr zhaoweikid163.com# 信件内容msg test mailsvr smtplib.SMTP(mailserver)# 设置为调试模式就是在会话过程中会有输出信息svr.set_debuglevel(1)# helo命令docmd方法包括了获取对方服务器返回信息svr.docmd(HELO server)# mail from, 发送邮件发送者svr.docmd(MAIL FROM: %s % from_addr)# rcpt to, 邮件接收者svr.docmd(RCPT TO: %s % to_addr)# data命令开始发送数据svr.docmd(DATA)# 发送正文数据svr.send(msg)# 比如以 . 作为正文发送结束的标记,用send发送的所以要用getreply获取返回信息svr.send( . )svr.getreply()# 发送结束退出svr.quit() 注意的是163.com是有反垃圾邮件功能的想上面的这种投递邮件的方法不一定能通过反垃圾邮件系统的检测的。所以一般不推荐个人这样发送。 第二种有点不一样 1.ehlo 2.auth login 3.mail from 4.rcpt to 5.data 6.quit 相对于第一种来说多了一个认证过程就是auth login这个过程。 #-*- encoding: gb2312 -*-import os, sys, stringimport smtplibimport base64# 邮件服务器地址mailserver smtp.163.com# 邮件用户名username xxxxxx163.com# 密码password xxxxxxx# smtp会话过程中的mail from地址from_addr xxxxxx163.com# smtp会话过程中的rcpt to地址to_addr yyyyyy163.com# 信件内容msg my test mailsvr smtplib.SMTP(mailserver)# 设置为调试模式就是在会话过程中会有输出信息svr.set_debuglevel(1)# ehlo命令docmd方法包括了获取对方服务器返回信息svr.docmd(EHLO server)# auth login 命令svr.docmd(AUTH LOGIN)# 发送用户名是base64编码过的用send发送的所以要用getreply获取返回信息svr.send(base64.encodestring(username))svr.getreply()# 发送密码svr.send(base64.encodestring(password))svr.getreply()# mail from, 发送邮件发送者svr.docmd(MAIL FROM: %s % from_addr)# rcpt to, 邮件接收者svr.docmd(RCPT TO: %s % to_addr)# data命令开始发送数据svr.docmd(DATA)# 发送正文数据svr.send(msg)# 比如以 . 作为正文发送结束的标记svr.send( . )svr.getreply()# 发送结束退出svr.quit() 上面说的是最普通的情况但是不能忽略的是现在好多企业邮件是支持安全邮件的就是通过SSL发送的邮件这个怎么发呢SMTP对SSL安全邮件的支持有两种方案一种老的是专门开启一个465端口来接收ssl邮件另一种更新的做法是在标准的25端口的smtp上增加一个starttls的命令来支持。 看看第一种怎么办: #-*- encoding: gb2312 -*-import os, sys, string, socketimport smtplibclass SMTP_SSL (smtplib.SMTP): def __init__(self, host, port465, local_hostnameNone, keyNone, certNone): self.cert cert self.key key smtplib.SMTP.__init__(self, host, port, local_hostname) def connect(self, hostlocalhost, port465): if not port and (host.find(:) host.rfind(:)): i host.rfind(:) if i 0: host, port host[:i], host[i1:] try: port int(port) except ValueError: raise socket.error, nonnumeric port if not port: port 654 if self.debuglevel 0: printstderr, connect:, (host, port) msg getaddrinfo returns an empty list self.sock None for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa res try: self.sock socket.socket(af, socktype, proto) if self.debuglevel 0: printstderr, connect:, (host, port) self.sock.connect(sa) # 新增加的创建ssl连接 sslobj socket.ssl(self.sock, self.key, self.cert) except socket.error, msg: if self.debuglevel 0: printstderr, connect fail:, (host, port) if self.sock: self.sock.close() self.sock None continue break if not self.sock: raise socket.error, msg # 设置ssl self.sock smtplib.SSLFakeSocket(self.sock, sslobj) self.file smtplib.SSLFakeFile(sslobj); (code, msg) self.getreply() if self.debuglevel 0: printstderr, connect:, msg return (code, msg) if __name__ __main__: smtp SMTP_SSL(192.168.2.10) smtp.set_debuglevel(1) smtp.sendmail(zzzxxx.com, zhaoweizhaowei.com, xxxxxxxxxxxxxxxxx) smtp.quit() 这里我是从原来的smtplib.SMTP派生出了新的SMTP_SSL类它专门来处理ssl连接。我这里测试的192.168.2.10是我自己的测试服务器. 第二种是新增加了starttls的命令这个很简单smtplib里就有这个方法叫smtplib.starttls()。当然不是所有的邮件系统都支持安全邮件的这个需要从ehlo的返回值里来确认如果里面有starttls才表示支持。相对于发送普通邮件的第二种方法来说只需要新增加一行代码就可以了: #-*- encoding: gb2312 -*-import os, sys, stringimport smtplibimport base64# 邮件服务器地址mailserver smtp.163.com# 邮件用户名username xxxxxx163.com# 密码password xxxxxxx# smtp会话过程中的mail from地址from_addr xxxxxx163.com# smtp会话过程中的rcpt to地址to_addr yyyyyy163.com# 信件内容msg my test mailsvr smtplib.SMTP(mailserver)# 设置为调试模式就是在会话过程中会有输出信息svr.set_debuglevel(1)# ehlo命令docmd方法包括了获取对方服务器返回信息如果支持安全邮件返回值里会有starttls提示svr.docmd(EHLO server)svr.starttls() # ------ 这行就是新加的支持安全邮件的代码# auth login 命令svr.docmd(AUTH LOGIN)# 发送用户名是base64编码过的用send发送的所以要用getreply获取返回信息svr.send(base64.encodestring(username))svr.getreply()# 发送密码svr.send(base64.encodestring(password))svr.getreply()# mail from, 发送邮件发送者svr.docmd(MAIL FROM: %s % from_addr)# rcpt to, 邮件接收者svr.docmd(RCPT TO: %s % to_addr)# data命令开始发送数据svr.docmd(DATA)# 发送正文数据svr.send(msg)# 比如以 . 作为正文发送结束的标记svr.send( . )svr.getreply()# 发送结束退出svr.quit() 注意 以上的代码为了方便我都没有判断返回值严格说来是应该判断一下返回的代码的在smtp协议中只有返回代码是2xx或者3xx才能继续下一步返回4xx或5xx的都是出错了。转载于:https://www.cnblogs.com/sislcb/archive/2008/12/02/1345467.html