python利用poplib來收取郵件

收取郵件有兩種方式,一種是POP3, 另外一種是IMAP,它們都是收取郵件服務器支持的協議,咱們用foxmail進行郵件的收發,感受不到收發的流程,而實際上收和發是做用在不一樣的服務器上,發郵件有專門的發郵件服務器,收郵件也有專門的收郵件服務器,發郵件只負責發送無論收取,同時收取郵件也無論如何發郵件,所以在測試時收和發郵件是分開進行的,雖然大多數時候收發郵件服務是裝在一個服務器上,但測試測的是協議,如SMTP, 如POP3, IMAP,python中的poplib收取郵件仍是很是簡單的,重點是收來的郵件須要解析,由於SMTP是進行編碼過的,收來的郵件須要進行處理後才能被咱們閱讀,所以又要用到email模塊,SMTP用email來傳遞內容,POP3用email來解析內容html

poplibpython

#返回全部郵件的編號
list(self,which=None): 
	['response',['message_count, octets'],octets]/[scan listing for the message]
-----------------------------
('+OK 7 messages:', ['1 1080', '2 1080', '3 1079', '4 675265', '5 675506', '6 675534', '7 597'], 61)

#收取整封郵件,索引號必需從1開始
retr(self,which): 
	return whole message of number which
	
#身份認證
user(self,user)
pass_(self.pwd)

#顯示調試信息
set_debuglevel(self,level)

#返回郵件數量和郵件大小
stat(self)
	get mailbox size
	return(mail_counter, mailbox_size)
-------------------------------------------
(7, 2030141)

#顯示郵件的頭信息,以及定製正文數據	
top(self,which,howmuch)
	return head of message of which, and how much lines of body message

原郵件以下:服務器

26169 From hding@hding.com  Tue Aug 16 20:06:02 2016
26170 Return-Path: <hding@hding.com>
26171 Received: from hding.com ([192.168.10.3])
26172     by ding.com (8.13.8/8.13.8) with ESMTP id u7GC623I002429
26173     (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
26174     for <qa@ding.com>; Tue, 16 Aug 2016 20:06:02 +0800
26175 Received: from 10.8.116.6 ([10.8.116.6])
26176     (authenticated bits=0)
26177     by hding.com (8.13.8/8.13.8) with ESMTP id u7GC0v9x027721
26178     for qa@ding.com; Tue, 16 Aug 2016 20:05:13 +0800
26179 Date: Tue, 16 Aug 2016 20:00:57 +0800
26180 From: hding@hding.com
26181 Message-Id: <201608161205.u7GC0v9x027721@hding.com>
26182 X-UID: 71                                                  
26183 Status: O
26184 
26185 "hello world"
26186 I am terry
26187 please welcome me

top(7,1)函數返回的第7封郵件的頭信息,1行正文,是一個元組函數

('+OK', ['Return-Path: <hding@hding.com>', 'Received: from hding.com ([192.168.10.3])', '\tby ding.com (8.13.8/8.13.8) with ESMTP id u7GC623I002429', '\t(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)', '\tfor <qa@ding.com>; Tue, 16 Aug 2016 20:06:02 +0800', 'Received: from 10.8.116.6 ([10.8.116.6])', '\t(authenticated bits=0)', '\tby hding.com (8.13.8/8.13.8) with ESMTP id u7GC0v9x027721', '\tfor qa@ding.com; Tue, 16 Aug 2016 20:05:13 +0800', 'Date: Tue, 16 Aug 2016 20:00:57 +0800', 'From: hding@hding.com', 'Message-Id: <201608161205.u7GC0v9x027721@hding.com>', '', '"hello world"'], 566)

retr(7) 函數返回整封郵件,是一元組,內容在retr(7)[1]測試

('+OK 597 octets', ['Return-Path: <hding@hding.com>', 'Received: from hding.com ([192.168.10.3])', '\tby ding.com (8.13.8/8.13.8) with ESMTP id u7GC623I002429', '\t(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)', '\tfor <qa@ding.com>; Tue, 16 Aug 2016 20:06:02 +0800', 'Received: from 10.8.116.6 ([10.8.116.6])', '\t(authenticated bits=0)', '\tby hding.com (8.13.8/8.13.8) with ESMTP id u7GC0v9x027721', '\tfor qa@ding.com; Tue, 16 Aug 2016 20:05:13 +0800', 'Date: Tue, 16 Aug 2016 20:00:57 +0800', 'From: hding@hding.com', 'Message-Id: <201608161205.u7GC0v9x027721@hding.com>', '', '"hello world"', 'I am terry', 'please welcome me'], 597)

只取正文信息只須要把retr獲得的所有信息減掉頭信息便可編碼

head = pop.top(7,0)
message = pop.retr(7)
body = [line for line in message[1] if line not in head[1]]

若是郵件有附件如何處理debug

retr()收到的郵件是一個多字段的列表,還談不上是郵件,須要經過mail.parser去解析,解析出來的郵件將符合郵件的格式,如Mail From, Mail To, 等調試

獲取第7封開始的郵件
messages = [pop_conn.retr(i) for i in range(7, pop_conn.stat()[0]+1)] 
--------------------------------------------------------------------------
[('+OK 597 octets', ['Return-Path: <hding@hding.com>', 'Received: from hding.com ([192.168.10.3])', '\tby ding.com (8.13.8/8.13.8) with ESMTP id u7GC623I002429', '\t(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)', '\tfor <qa@ding.com>; Tue, 16 Aug 2016 20:06:02 +0800', 'Received: from 10.8.116.6 ([10.8.116.6])', '\t(authenticated bits=0)', '\tby hding.com (8.13.8/8.13.8) with ESMTP id u7GC0v9x027721', '\tfor qa@ding.com; Tue, 16 Aug 2016 20:05:13 +0800', 'Date: Tue, 16 Aug 2016 20:00:57 +0800', 'From: hding@hding.com', 'Message-Id: <201608161205.u7GC0v9x027721@hding.com>', '', '"hello world"', 'I am terry', 'please welcome me'], 597)]
給每封郵件中的內容以'\n'字符做爲鏈接符造成字符串
messages = ["\n".join(msg[1]) for msg in messages]
---------------------------------------------------------------------------
['Return-Path: <hding@hding.com>\nReceived: from hding.com ([192.168.10.3])\n\tby ding.com (8.13.8/8.13.8) with ESMTP id u7GC623I002429\n\t(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)\n\tfor <qa@ding.com>; Tue, 16 Aug 2016 20:06:02 +0800\nReceived: from 10.8.116.6 ([10.8.116.6])\n\t(authenticated bits=0)\n\tby hding.com (8.13.8/8.13.8) with ESMTP id u7GC0v9x027721\n\tfor qa@ding.com; Tue, 16 Aug 2016 20:05:13 +0800\nDate: Tue, 16 Aug 2016 20:00:57 +0800\nFrom: hding@hding.com\nMessage-Id: <201608161205.u7GC0v9x027721@hding.com>\n\n"hello world"\nI am terry\nplease welcome me']
解析文件內容
messages = [parser.Parser().parsestr(msg) for msg in messages] 
------------------------------------------------------------------------------
[<email.message.Message instance at 0x02C1C9B8>]           返回了一個message的實例
獲取單封郵件message內容
for message in messages:
    print message
--------------------------------------------------------------------------------
From nobody Wed Aug 17 19:04:31 2016
Return-Path: <hding@hding.com>
Received: from hding.com ([192.168.10.3])
 by ding.com (8.13.8/8.13.8) with ESMTP id u7GC623I002429
 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
 for <qa@ding.com>; Tue, 16 Aug 2016 20:06:02 +0800
Received: from 10.8.116.6 ([10.8.116.6]) (authenticated bits=0)
 by hding.com (8.13.8/8.13.8) with ESMTP id u7GC0v9x027721
 for qa@ding.com; Tue, 16 Aug 2016 20:05:13 +0800
Date: Tue, 16 Aug 2016 20:00:57 +0800
From: hding@hding.com
Message-Id: <201608161205.u7GC0v9x027721@hding.com>

"hello world"
I am terry
please welcome me
----------------------------------------------------------------------------------
從上文能夠看出解析的很是好,如何區別附件和正文
    for part in message.walk():                                                      #遍歷郵件內容 
        fileName = part.get_filename()                                               #獲得附件名 
        contentType = part.get_content_type()                                        #獲得附件類型  
        # 保存附件  
        if fileName:             #若是有附件則必定會有文件名                                                                              #附件從新寫到新的文件中 
            data = part.get_payload(decode=True)  
            f_attach = open(fileName, 'wb')  
            f_attach.write(data)  
            f_attach.close()  
        elif contentType == 'text/plain' or contentType == 'text/html':               #正文照抄到正文中 
            #保存正文  
            data = part.get_payload(decode=True)  
            print data
----------------------------------------------------------------------------------
"hello world"
I am terry
please welcome me

帶附件的郵件code

26229 From hding@hding.com  Wed Aug 17 19:21:08 2016                           fist part
26230 Return-Path: <hding@hding.com>
26231 Received: from hding.com ([192.168.10.3])
26232     by ding.com (8.13.8/8.13.8) with ESMTP id u7HBL8rW015601
26233     (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
26234     for <qa@ding.com>; Wed, 17 Aug 2016 19:21:08 +0800                                                         
26235 Received: from ding.com ([10.10.10.3])
26236     (authenticated bits=0)
26237     by hding.com (8.13.8/8.13.8) with ESMTP id u7HBL7sl008349
26238     (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
26239     for <qa@ding.com>; Wed, 17 Aug 2016 19:21:07 +0800
26240 Date: Wed, 17 Aug 2016 19:21:07 +0800
26241 Message-Id: <201608171121.u7HBL7sl008349@hding.com>
26242 Content-Type: multipart/mixed; boundary="===============4712348666551551578=="
26243 MIME-Version: 1.0
26244 From: hding@hding.com
26245 To: qa@ding.com
26246 Subject: test_mail
26247 X-UID: 73                                                 
26248 Status: RO
26249 
26250 --===============4712348666551551578==                                   second part
26251 Content-Type: doc/test_file
26252 MIME-Version: 1.0
26253 Content-Disposition: attachment; filename="test_file"
26254 Content-Transfer-Encoding: base64
26255 
26256 aGVsbG8gd29ybGQKCkkgYW0gYSB0ZXN0IGZpbGUsIGNhbiB5b3UgcmVhZCBpdCAKCmFuZCBnaXZl
26257 IG1lIGEgcmVzcG9uc2UK
26258 
26259 --===============4712348666551551578==                                  third part
26260 Content-Type: text/plain; charset="utf-8"
26261 MIME-Version: 1.0
26262 Content-Transfer-Encoding: base64
26263 
26264 aGVsbG8gd29ybGQKCkkgYW0gYSB0ZXN0IGZpbGUsIGNhbiB5b3UgcmVhZCBpdCAKCmFuZCBnaXZl
26265 IG1lIGEgcmVzcG9uc2UKPGltYWdlIHNyYz0nY2lkOjEnPg==
26266 
26267 --===============4712348666551551578==--

在工做中,因爲我只須要在pop3上進行收文件便可,無需真實下載下來,所以只須要retr函數就完成任務server

1 #!/usr/bin/env python
  2 #coding:utf-8
  3 
  4 from poplib import POP3_SSL
  5 
  6 class DPI_SSL_POP3(object):
  7 
  8     def __init__(self,username='username',password='password',host='192.168.10.3'):
  9         self.pop = POP3_SSL(host)
 10         self.pop.user(username)
 11         self.pop.pass_(password)
 12 
 13     def get_message_from_pop3s(self):
 14         self.pop.retr(self.pop.stat()[0])                       #最新一封郵件
 15 
 16 
 17 if __name__ == '__main__':
 18 
 19     pops = DPI_SSL_POP3()
 20     pops.get_message_from_pop3s()

pop3 server在WAN側, 我在LAN側執行腳本,收取帶有病毒的附件,病毒通過Firewall,進行檢測

相關文章
相關標籤/搜索