`
huangro
  • 浏览: 333376 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

python模块之smtplib: 用python发送SSL/TLS安全邮件

阅读更多

原文出自 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会话有两种方式,一种是邮件直接投递,就是说,比如你要发邮件給zzz@163.com,那就直接连接163.com的邮件服务器,把信投給 zzz@163.com; 另一种是验证过后的发信,它的过程是,比如你要发邮件給zzz@163.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, string
import smtplib

# 邮件服务器地址
mailserver = " smtp.163.com "
# smtp会话过程中的mail from地址
from_addr = " asfgysg@zxsdf.com "
# smtp会话过程中的rcpt to地址
to_addr = " zhaoweikid@163.com "
# 信件内容
msg = " test mail "

svr
= 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, string
import smtplib
import base64

# 邮件服务器地址
mailserver = " smtp.163.com "
# 邮件用户名
username = " xxxxxx@163.com "
# 密码
password = " xxxxxxx "
# smtp会话过程中的mail from地址
from_addr = " xxxxxx@163.com "
# smtp会话过程中的rcpt to地址
to_addr = " yyyyyy@163.com "
# 信件内容
msg = " my test mail "

svr
= 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, socket
import smtplib


class SMTP_SSL (smtplib.SMTP):
    
def __init__ (self, host = '' , port = 465 , local_hostname = None, key = None, cert = None):
         self.cert
= cert
         self.key
= key
         smtplib.SMTP.
__init__ (self, host, port, local_hostname)
        
    
def connect(self, host = ' localhost ' , port = 465 ):
        
if not port and (host.find( ' : ' ) == host.rfind( ' : ' )):
             i
= host.rfind( ' : ' )
            
if i >= 0:
                 host, port
= host[:i], host[i + 1 :]
                
try : port = int(port)
                
except ValueError:
                    
raise socket.error, " nonnumeric port "
        
if not port: port = 654
        
if self.debuglevel > 0: print >> stderr, ' 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: print >> stderr, ' 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:
                    
print >> stderr, ' 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: print >> stderr, " connect: " , msg
        
return (code, msg)
        
if __name__ == ' __main__ ' :
     smtp
= SMTP_SSL( ' 192.168.2.10 ' )
     smtp.set_debuglevel(
1 )
     smtp.sendmail(
" zzz@xxx.com " , " zhaowei@zhaowei.com " , " xxxxxxxxxxxxxxxxx " )
     smtp.quit()

   
    这里我是从原来的smtplib.SMTP派生出了新的SMTP_SSL类,它专门来处理ssl连接。我这里测试的192.168.2.10是我自己的测试服务器.
    第二种是新增加了starttls的命令,这个很简单,smtplib里就有这个方法,叫smtplib.starttls()。当然,不是所有的邮件系 统都支持安全邮件的,这个需要从ehlo的返回值里来确认,如果里面有starttls,才表示支持。相对于发送普通邮件的第二种方法来说,只需要新增加 一行代码就可以了:

# -*- encoding: gb2312 -*-
import os, sys, string
import smtplib
import base64

# 邮件服务器地址
mailserver = " smtp.163.com "
# 邮件用户名
username = " xxxxxx@163.com "
# 密码
password = " xxxxxxx "
# smtp会话过程中的mail from地址
from_addr = " xxxxxx@163.com "
# smtp会话过程中的rcpt to地址
to_addr = " yyyyyy@163.com "
# 信件内容
msg = " my test mail "

svr
= 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的,都是出错了。

分享到:
评论
3 楼 hfa1s2 2012-07-06  
是的。谢谢你哈! 我解决了这个问题
2 楼 huangro 2012-06-13  
587端口的是很麻烦的,毕竟是需要ssl验证的。
1 楼 hfa1s2 2012-05-30  
我想利用内网往公司邮箱里发,但接口是587 的 而且需要 SSL验证 ,好麻烦啊~ 还没有解决。

相关推荐

    python smtplib模块发送SSL/TLS安全邮件实例

    在本文中,我们将探讨如何使用`smtplib`模块发送SSL/TLS安全邮件,以及两种不同的发送方式。 首先,让我们了解一下SMTP的基本命令。SMTP协议中包含以下几个关键命令: 1. `HELO`:向服务器表明身份。 2. `MAIL FROM...

    通过TLS发送邮件

    这个脚本可能会使用`smtplib`和`email`模块来创建和发送邮件,以及使用`starttls()`方法来开启TLS连接。 在实际应用中,确保正确配置TLS对于避免中间人攻击和其他网络安全威胁至关重要。同时,邮件服务器应持有有效...

    python使用smtplib模块通过gmail实现邮件发送的方法

    ### Python使用smtplib模块通过Gmail实现邮件发送的方法 #### 概述 在现代软件开发过程中,电子邮件作为最常用的信息传递方式之一,在系统报警、用户通知等方面扮演着重要角色。Python作为一种流行的编程语言,...

    SMTP发送邮件 SSL

    综上所述,SMTP发送邮件结合SSL或TLS提供了安全的邮件传输手段,支持发送附件的功能使得邮件更加实用,而跨平台的设计则确保了代码的通用性和可移植性。这些技术在现代电子邮件系统中扮演着至关重要的角色。

    Python-python发送邮件报表

    在这个例子中,我们使用了SSL/TLS安全连接,并且需要提供SMTP服务器的相关凭证。请注意,实际应用中应避免明文存储密码,可以考虑使用环境变量或密钥管理服务。 通过以上步骤,你可以用Python编写一个脚本来定期...

    基于Pyqt5实现的邮件发送器(Python).zip

    6. **SSL/TLS安全**:为了保证通信安全,SMTP连接通常需要使用SSL或TLS加密。Python的`smtplib`库支持这些安全连接。 7. **认证机制**:如果邮件服务器需要用户名和密码,开发者可能使用了SMTP的AUTH扩展来实现身份...

    python自动发送邮件,支持所有邮箱.rar

    7. **SSL/TLS安全连接**:为了确保数据传输的安全,许多SMTP服务器要求使用SSL或TLS加密连接。`smtplib.SMTP_SSL`用于直接建立SSL连接,而`smtplib.SMTP`则可以使用`starttls()`方法开启TLS连接。 8. **处理异常**...

    好用的邮件库.zip

    5. **加密与安全**:现代邮件库会支持SSL/TLS加密,以保护用户数据在传输过程中的安全性。此外,还可能涉及认证机制,如OAuth2,以增强安全性。 6. **多语言支持**:为了满足全球用户的需要,邮件库可能会有对多种...

    python smtplib模块实现发送邮件带附件sendmail

    Python的`smtplib`模块是用于发送电子邮件的,它提供了低级别的SMTP(简单邮件传输协议)接口。在本文中,我们将深入探讨如何使用`smtplib`结合其他相关模块来发送带有附件的邮件。 首先,我们需要导入必要的模块。...

    Python使用poplib模块和smtplib模块收发电子邮件的教程

    当我们讨论发送电子邮件时,特别是涉及到安全性较高的场景(如通过SSL/TLS加密通道发送),smtplib模块是非常重要的。 ##### 1.1 发送SSL/TLS加密邮件 要使用`smtplib`模块发送加密邮件,我们需要连接到支持SSL或...

    Python实现邮件服务功能.zip

    许多SMTP服务器需要身份验证,Python通过`smtplib.SMTP_SSL`或`smtplib.SMTP.starttls()`实现SSL/TLS加密,以确保通信安全。 5. **发送邮件** 使用`smtplib.SMTP`实例,调用`sendmail()`方法发送邮件。你需要指定...

    基于Python的电子邮件自动发送程序设计.zip

    首先,我们需要了解Python中的SMTP(Simple Mail Transfer Protocol)模块,这是Python标准库中的一个组件,用于发送邮件。SMTP是互联网上用于发送电子邮件的标准协议,而Python的`smtplib`库则提供了与SMTP服务器...

    实现电子邮件的接受和发送,并且在发送和接受过程中可以进行加密和解密.zip

    在实现电子邮件发送时,你需要使用编程语言中的邮件库,如Python的smtplib和email库。以下是一个简单的示例: ```python import smtplib from email.mime.text import MIMEText smtp_server = 'smtp.example.com' ...

    python smtplib模块自动收发邮件功能(一)

    Python作为一门广泛使用的编程语言,其smtplib模块提供了简单直观的方式实现电子邮件的发送和接收。本文将详细介绍如何使用Python的smtplib模块来实现邮件的自动收发功能,内容涵盖了基本的使用方法、文本邮件和HTML...

    python 邮件发送模块 mail 自动 邮件 定时

    Python邮件发送模块是Python编程中一个非常实用的功能,它允许我们自动发送电子邮件,这对于自动化报告、通知服务或者定期任务的提醒来说非常有用。在Python中,我们可以使用内置的`smtplib`和`email`库来实现这个...

    Python基于smtplib模块发送邮件代码实例

    首先,`smtplib`模块是Python的标准库之一,它提供了与SMTP(简单邮件传输协议)服务器交互的能力,负责邮件的发送。通过这个模块,我们可以连接到SMTP服务器,登录我们的邮箱,并发送邮件。下面是一段基本的使用`...

    Python基于PyQt5和SMTP协议实现邮件发送程序案例源码.7z

    1. **Python smtplib模块**:这个模块是Python标准库的一部分,用于处理SMTP协议,让我们能够发送电子邮件。通过它,我们可以连接到邮件服务器,建立会话,验证用户凭据,然后发送邮件。 2. **Python email库**:这...

    python网络编程(第3版)配套代码_python网络编程(第3版)配套代码_

    - SMTP(简单邮件传输协议)用于发送电子邮件,Python的`smtplib`模块可用来实现邮件发送。 7. **SSL/TLS安全通信**: - 为了加密通信,Python的`ssl`模块提供了对SSL/TLS的支持,可用于创建安全的HTTPS连接或...

    利用socket发送接收邮件(转)

    综上所述,利用Socket编程发送和接收邮件涉及到对SMTP、POP3/IMAP协议的理解,以及如何使用Python的socket、smtplib、poplib和imaplib等库。通过实践,你可以构建自己的邮件客户端,实现个性化和安全的邮件服务。

    python 实现的发送邮件模板【普通邮件、带附件、带图片邮件】

    在Python编程中,发送邮件是一项常见的任务,尤其对于自动化报告或者通知系统来说。Python提供了多种库来处理邮件发送,如`smtplib`和`email...同时,确保你的SMTP服务器支持SSL/TLS安全连接,以及正确配置了登录凭证。

Global site tag (gtag.js) - Google Analytics