最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python使用poplib模塊和smtplib模塊收發(fā)電子郵件的教程

 更新時間:2016年07月02日 14:59:20   作者:zhaoweikid  
smtplib模塊一般我們比較熟悉、這里我們會來講解使用smtplib發(fā)送SSL/TLS安全郵件的方法,而poplib模塊則負責處理接收pop3協(xié)議的郵件,下面我們就來看Python使用poplib模塊和smtplib模塊收發(fā)電子郵件的教程

poplib模塊接收郵件
python的poplib模塊是用來從pop3收取郵件的,也可以說它是處理郵件的第一步。
POP3協(xié)議并不復雜,它也是采用的一問一答式的方式,你向服務(wù)器發(fā)送一個命令,服務(wù)器必然會回復一個信息。pop3命令碼如下:

命令 poplib方法  參數(shù)    狀態(tài)     描述
-----------------------------------------------------------------------------------------------
USER  user   username  認可  用戶名,此命令與下面的pass命令若成功,將導致狀態(tài)轉(zhuǎn)換
PASS  pass_   password  認可  用戶密碼   
APOP  apop   Name,Digest 認可  Digest是MD5消息摘要
-----------------------------------------------------------------------------------------------
STAT  stat   None    處理  請求服務(wù)器發(fā)回關(guān)于郵箱的統(tǒng)計資料,如郵件總數(shù)和總字節(jié)數(shù)
UIDL  uidl   [Msg#]   處理  返回郵件的唯一標識符,POP3會話的每個標識符都將是唯一的
LIST  list   [Msg#]   處理  返回郵件數(shù)量和每個郵件的大小
RETR  retr   [Msg#]   處理  返回由參數(shù)標識的郵件的全部文本
DELE  dele   [Msg#]   處理  服務(wù)器將由參數(shù)標識的郵件標記為刪除,由quit命令執(zhí)行
RSET  rset   None    處理  服務(wù)器將重置所有標記為刪除的郵件,用于撤消DELE命令
TOP   top    [Msg#]   處理  服務(wù)器將返回由參數(shù)標識的郵件前n行內(nèi)容,n必須是正整數(shù)
NOOP  noop   None    處理  服務(wù)器返回一個肯定的響應(yīng)
----------------------------------------------------------------------------------------------
QUIT  quit   None    更新    

 

python的poplib也針對這些命令分別提供了對應(yīng)的方法,上面在第二列里已經(jīng)標出來。收取郵件的過程一般是:
1. 連接pop3服務(wù)器 (poplib.POP3.__init__)
2. 發(fā)送用戶名和密碼進行驗證 (poplib.POP3.user poplib.POP3.pass_)
3. 獲取郵箱中信件信息 (poplib.POP3.stat)
4. 收取郵件 (poplib.POP3.retr)
5. 刪除郵件 (poplib.POP3.dele)
6. 退出 (poplib.POP3.quit)
注意的是,上面我在括號里寫的是使用什么方法來完成這個操作,在實際的代碼中不能那樣寫,應(yīng)該是創(chuàng)建poplib.POP3的對象,然后,調(diào)用這個對象的方法。比如:

poplib.POP3.quit 

應(yīng)該理解為

a = poplib.POP3(host)
a.quit()

下面看看實際的代碼:

#-*- encoding: gb2312 -*-
import os, sys, string
import poplib

# pop3服務(wù)器地址
host = "pop3.163.com"
# 用戶名
username = "xxxxxx@163.com"
# 密碼
password = "xxxxxxx"
# 創(chuàng)建一個pop3對象,這個時候?qū)嶋H上已經(jīng)連接上服務(wù)器了
pp = poplib.POP3(host)
# 設(shè)置調(diào)試模式,可以看到與服務(wù)器的交互信息
pp.set_debuglevel(1)
# 向服務(wù)器發(fā)送用戶名
pp.user(username)
# 向服務(wù)器發(fā)送密碼
pp.pass_(password)
# 獲取服務(wù)器上信件信息,返回是一個列表,第一項是一共有多上封郵件,第二項是共有多少字節(jié)
ret = pp.stat()
print ret
# 需要取出所有信件的頭部,信件id是從1開始的。
for i in range(1, ret[0]+1):
  # 取出信件頭部。注意:top指定的行數(shù)是以信件頭為基數(shù)的,也就是說當取0行,
  # 其實是返回頭部信息,取1行其實是返回頭部信息之外再多1行。
  mlist = pp.top(i, 0)
  print 'line: ', len(mlist[1])
# 列出服務(wù)器上郵件信息,這個會對每一封郵件都輸出id和大小。不象stat輸出的是總的統(tǒng)計信息
ret = pp.list()
print ret
# 取第一封郵件完整信息,在返回值里,是按行存儲在down[1]的列表里的。down[0]是返回的狀態(tài)信息
down = pp.retr(1)
print 'lines:', len(down)
# 輸出郵件
for line in down[1]:
  print line
# 退出
pp.quit()

在有些地方,有安全郵件這一說,其實是對pop3做了ssl加密。這樣的,poplib一樣可以處理,只不過不是用POP3這個類,而是用POP3_SSL, 他們的方法都一樣。因此支持ssl在上面代碼中,替換創(chuàng)建pop3對象的一行為:

pp = poplib.POP3_SSL(host)

smtplib: 用python發(fā)送SSL/TLS安全郵件
python的smtplib提供了一種很方便的途徑發(fā)送電子郵件。它對smtp協(xié)議進行了簡單的封裝。
smtp協(xié)議的基本命令包括:

  •     HELO 向服務(wù)器標識用戶身份
  •     MAIL 初始化郵件傳輸 mail from:
  •     RCPT 標識單個的郵件接收人;常在MAIL命令后面,可有多個rcpt to:
  •     DATA 在單個或多個RCPT命令后,表示所有的郵件接收人已標識,并初始化數(shù)據(jù)傳輸,以.結(jié)束
  •     VRFY 用于驗證指定的用戶/郵箱是否存在;由于安全方面的原因,服務(wù)器常禁止此命令
  •     EXPN 驗證給定的郵箱列表是否存在,擴充郵箱列表,也常被禁用
  •     HELP 查詢服務(wù)器支持什么命令
  •     NOOP 無操作,服務(wù)器應(yīng)響應(yīng)OK
  •     QUIT 結(jié)束會話
  •     RSET 重置會話,當前傳輸被取消
  •     MAIL FROM 指定發(fā)送者地址
  •     RCPT TO 指明的接收者地址

    一般smtp會話有兩種方式,一種是郵件直接投遞,就是說,比如你要發(fā)郵件給zzz@163.com,那就直接連接163.com的郵件服務(wù)器,把信投給zzz@163.com; 另一種是驗證過后的發(fā)信,它的過程是,比如你要發(fā)郵件給zzz@163.com,你不是直接投到163.com,而是通過自己在sina.com的另一個郵箱來發(fā)。這樣就要先連接sina.com的smtp服務(wù)器,然后認證,之后在把要發(fā)到163.com的信件投到sina.com上,sina.com會幫你把信投遞到163.com。

    第一種方式的命令流程基本是這樣:
      1. helo
      2. mail from
      3. rcpt to
      4. data
      5. quit
    但是第一種發(fā)送方式一般有限制的,就是rcpt to指定的這個郵件接收者必須在這個服務(wù)器上存在,否則是不會接收的。 先看看代碼:

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

# 郵件服務(wù)器地址
mailserver = "smtp.163.com"
# smtp會話過程中的mail from地址
from_addr = "asfgysg@zxsdf.com"
# smtp會話過程中的rcpt to地址
to_addr = "zhaoweikid@163.com"
# 信件內(nèi)容
msg = "test mail"

svr = smtplib.SMTP(mailserver)
# 設(shè)置為調(diào)試模式,就是在會話過程中會有輸出信息
svr.set_debuglevel(1)
# helo命令,docmd方法包括了獲取對方服務(wù)器返回信息
svr.docmd("HELO server")
# mail from, 發(fā)送郵件發(fā)送者
svr.docmd("MAIL FROM: <%s>" % from_addr)
# rcpt to, 郵件接收者
svr.docmd("RCPT TO: <%s>" % to_addr)
# data命令,開始發(fā)送數(shù)據(jù)
svr.docmd("DATA")
# 發(fā)送正文數(shù)據(jù)
svr.send(msg)
# 比如以 . 作為正文發(fā)送結(jié)束的標記,用send發(fā)送的,所以要用getreply獲取返回信息
svr.send(" . ")
svr.getreply()
# 發(fā)送結(jié)束,退出
svr.quit()

    注意的是,163.com是有反垃圾郵件功能的,想上面的這種投遞郵件的方法不一定能通過反垃圾郵件系統(tǒng)的檢測的。所以一般不推薦個人這樣發(fā)送。
    第二種有點不一樣:
      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

# 郵件服務(wù)器地址
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"
# 信件內(nèi)容
msg = "my test mail"

svr = smtplib.SMTP(mailserver)
# 設(shè)置為調(diào)試模式,就是在會話過程中會有輸出信息
svr.set_debuglevel(1)
# ehlo命令,docmd方法包括了獲取對方服務(wù)器返回信息
svr.docmd("EHLO server")
# auth login 命令
svr.docmd("AUTH LOGIN")
# 發(fā)送用戶名,是base64編碼過的,用send發(fā)送的,所以要用getreply獲取返回信息
svr.send(base64.encodestring(username))
svr.getreply()
# 發(fā)送密碼
svr.send(base64.encodestring(password))
svr.getreply()
# mail from, 發(fā)送郵件發(fā)送者
svr.docmd("MAIL FROM: <%s>" % from_addr)
# rcpt to, 郵件接收者
svr.docmd("RCPT TO: <%s>" % to_addr)
# data命令,開始發(fā)送數(shù)據(jù)
svr.docmd("DATA")
# 發(fā)送正文數(shù)據(jù)
svr.send(msg)
# 比如以 . 作為正文發(fā)送結(jié)束的標記
svr.send(" . ")
svr.getreply()
# 發(fā)送結(jié)束,退出
svr.quit()

    
    上面說的是最普通的情況,但是不能忽略的是現(xiàn)在好多企業(yè)郵件是支持安全郵件的,就是通過SSL發(fā)送的郵件,這個怎么發(fā)呢?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)
        # 新增加的創(chuàng)建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

    # 設(shè)置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是我自己的測試服務(wù)器.
    第二種是新增加了starttls的命令,這個很簡單,smtplib里就有這個方法,叫smtplib.starttls()。當然,不是所有的郵件系統(tǒng)都支持安全郵件的,這個需要從ehlo的返回值里來確認,如果里面有starttls,才表示支持。相對于發(fā)送普通郵件的第二種方法來說,只需要新增加一行代碼就可以了:

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

# 郵件服務(wù)器地址
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"
# 信件內(nèi)容
msg = "my test mail"

svr = smtplib.SMTP(mailserver)
# 設(shè)置為調(diào)試模式,就是在會話過程中會有輸出信息
svr.set_debuglevel(1)
# ehlo命令,docmd方法包括了獲取對方服務(wù)器返回信息,如果支持安全郵件,返回值里會有starttls提示
svr.docmd("EHLO server")
svr.starttls() # <------ 這行就是新加的支持安全郵件的代碼!
# auth login 命令
svr.docmd("AUTH LOGIN")
# 發(fā)送用戶名,是base64編碼過的,用send發(fā)送的,所以要用getreply獲取返回信息
svr.send(base64.encodestring(username))
svr.getreply()
# 發(fā)送密碼
svr.send(base64.encodestring(password))
svr.getreply()
# mail from, 發(fā)送郵件發(fā)送者
svr.docmd("MAIL FROM: <%s>" % from_addr)
# rcpt to, 郵件接收者
svr.docmd("RCPT TO: <%s>" % to_addr)
# data命令,開始發(fā)送數(shù)據(jù)
svr.docmd("DATA")
# 發(fā)送正文數(shù)據(jù)
svr.send(msg)
# 比如以 . 作為正文發(fā)送結(jié)束的標記
svr.send(" . ")
svr.getreply()
# 發(fā)送結(jié)束,退出
svr.quit()

注意: 以上的代碼為了方便我都沒有判斷返回值,嚴格說來,是應(yīng)該判斷一下返回的代碼的,在smtp協(xié)議中,只有返回代碼是2xx或者3xx才能繼續(xù)下一步,返回4xx或5xx的,都是出錯了。

相關(guān)文章

  • Python使用PIL進行JPEG圖像壓縮的簡易教程

    Python使用PIL進行JPEG圖像壓縮的簡易教程

    本文介紹了如何使用Python編程語言和wxPython圖形用戶界面庫進行JPEG圖像的壓縮,通過添加滑塊控件,我們可以調(diào)整壓縮質(zhì)量,并將壓縮后的照片另存為原來的名稱加上后綴"壓縮+質(zhì)量數(shù)字"的新文件,需要的朋友可以參考下
    2023-09-09
  • Python代碼實現(xiàn)KNN算法

    Python代碼實現(xiàn)KNN算法

    這篇文章主要為大家詳細介紹了Python代碼實現(xiàn)KNN算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 用Python實現(xiàn)的等差數(shù)列方式

    用Python實現(xiàn)的等差數(shù)列方式

    這篇文章主要介紹了用Python實現(xiàn)的等差數(shù)列方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Django Admin 實現(xiàn)外鍵過濾的方法

    Django Admin 實現(xiàn)外鍵過濾的方法

    下面小編就為大家?guī)硪黄狣jango Admin 實現(xiàn)外鍵過濾的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • python數(shù)字圖像處理實現(xiàn)圖像的形變與縮放

    python數(shù)字圖像處理實現(xiàn)圖像的形變與縮放

    這篇文章主要為大家介紹了python數(shù)字圖像處理實現(xiàn)圖像的形變與縮放示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 舉例講解Python中is和id的用法

    舉例講解Python中is和id的用法

    這篇文章主要介紹了舉例講解Python中is和id的用法,是Python學習當中的基礎(chǔ)知識,作者舉例進行了簡單說明,需要的朋友可以參考下
    2015-04-04
  • Python基于time模塊求程序運行時間的方法

    Python基于time模塊求程序運行時間的方法

    這篇文章主要介紹了Python基于time模塊求程序運行時間的方法,涉及Python time模塊的使用及數(shù)值運算相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09
  • 完美解決ARIMA模型中plot_acf畫不出圖的問題

    完美解決ARIMA模型中plot_acf畫不出圖的問題

    這篇文章主要介紹了完美解決ARIMA模型中plot_acf畫不出圖的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • Python在for循環(huán)中更改list值的方法【推薦】

    Python在for循環(huán)中更改list值的方法【推薦】

    這篇文章主要介紹了Python在for循環(huán)中更改list值的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • Python繪制指數(shù)概率分布函數(shù)

    Python繪制指數(shù)概率分布函數(shù)

    指數(shù)分布是一種廣泛應(yīng)用于數(shù)據(jù)科學和統(tǒng)計學中的連續(xù)概率分布,本文將詳細介紹如何在Python中快速上手繪制指數(shù)分布的概率密度函數(shù)圖,需要的可以參考下
    2025-01-01

最新評論

尚义县| 四会市| 驻马店市| 桑植县| 五大连池市| 灵丘县| 偃师市| 高密市| 弋阳县| 阿勒泰市| 府谷县| 白山市| 三亚市| 巢湖市| 辽源市| 阳曲县| 华蓥市| 达尔| 忻城县| 彭泽县| 灵台县| 弋阳县| 岳阳县| 林芝县| 和硕县| 满城县| 扶绥县| 金溪县| 余庆县| 大理市| 巴塘县| 黑山县| 漳州市| 澄迈县| 木兰县| 盐山县| 新源县| 秦安县| 平凉市| 丽水市| 乌苏市|