欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

python smtplib模塊發送SSL/TLS安全郵件實例

系統 1738 0

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會話有兩種方式,一種是郵件直接投遞,就是說,比如你要發郵件?ozzz@163.com,那就直接連接163.com的郵件服務器,把信投?ozzz@163.com; 另一種是驗證過后的發信,它的過程是,比如你要發郵件?ozzz@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的,都是出錯了。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国内久久 | 亚洲国产成人av好男人在线观看 | 草草视频手机在线观看视频 | 亚洲一二三区视频 | 久久久www成人免费精品张筱雨 | 色狠狠xx| 麻豆一区二区99久久久久 | 男女激情视频在线观看 | 99在线观看 | 波多野结衣一区二区在线 | 欧美成人精品一区二区男人看 | 亚洲精品97福利在线 | 日本一道本视频 | 521色香蕉网站在线观看 | 国产睡熟迷奷系列网站 | 亚洲成网 | 一级黄片毛片免费看 | 欧美成人精品一区二区三区 | av一区二区三区在线观看 | 伊人久久精品成人网 | 精品一区二区三区免费看 | 亚洲欧洲日本天天堂在线观看 | 午夜直播在线 | 91在线精品秘密一区二区 | 亚洲免费观看视频 | 国产精品亚洲第一区二区三区 | 天天干天天添 | 亚洲成人久久久 | a视频在线免费观看 | 日韩精品一区二区三区中文字幕 | 久久久久久久蜜桃 | 日韩久久久久久 | 亚洲国产精品99久久久久久久久 | 玖玖爱365| 亚洲综合激情另类小说区 | 色www 永久免费网站 | 日韩一区二区不卡 | 国产精品美女久久久久久久久久久 | av影音资源 | 欧美日韩在线视频观看 | 国产一区二区三区乱码 |