1. 程式人生 > >python實現IMAP協議下email收取

python實現IMAP協議下email收取

本文為轉載,原文在這裡

 

    所謂無痕取信,目前主要是指從郵箱中把信件收取後,郵箱內狀態不發生任何改變。這裡的狀態主要是指兩部分,一部分是郵件狀態不變,即已讀與未讀狀態不變,另一部分是指郵箱記錄的登陸IP不發生改變。本文中所說的偽“無痕”取信主要是指實現第一部分。
一、準備知識
1、Imaplib

IMAP4.append(mailbox, flags, date_time, message):Append message to named mailbox.

IMAP4.authenticate(mechanism, authobject):Authenticate command — requires response processing.mechanism specifies which authentication mechanism is to be used - it should appear in the instance variable capabilities in the form AUTH=mechanism.

IMAP4.check():Checkpoint mailbox on server.

IMAP4.close():Close currently selected mailbox. Deleted messages are removed from writable mailbox. This is the recommended command before LOGOUT.

IMAP4.copy(message_set, new_mailbox):Copy message_set messages onto end of new_mailbox.

IMAP4.create(mailbox):Create new mailbox named mailbox.

IMAP4.delete(mailbox):Delete old mailbox named mailbox.

IMAP4.deleteacl(mailbox, who):Delete the ACLs (remove any rights) set for who on mailbox.

IMAP4.expunge():Permanently remove deleted items from selected mailbox. Generates an EXPUNGE response for each deleted message. Returned data contains a list of EXPUNGE message numbers in order received.

IMAP4.fetch(message_set, message_parts):Fetch (parts of) messages. message_parts should be a string of message part names enclosed within parentheses, eg: "(UID BODY[TEXT])". Returned data are tuples of message part envelope and data.

IMAP4.getacl(mailbox):Get the ACLs for mailbox. The method is non-standard, but is supported by the Cyrus server.

IMAP4.getannotation(mailbox, entry, attribute):Retrieve the specified ANNOTATIONs for mailbox. The method is non-standard, but is supported by the Cyrus server.

IMAP4.getquota(root):Get the quota root‘s resource usage and limits. This method is part of the IMAP4 QUOTA extension defined in rfc2087.

IMAP4.getquotaroot(mailbox):Get the list of quota roots for the named mailbox. This method is part of the IMAP4 QUOTA extension defined in rfc2087.

IMAP4.list([directory[, pattern]]):List mailbox names in directory matching pattern. directory defaults to the top-level mail folder, and pattern defaults to match anything. Returned data contains a list of LIST responses.

IMAP4.login(user, password):Identify the client using a plaintext password. The password will be quoted.

IMAP4.login_cram_md5(user, password):Force use of CRAM-MD5 authentication when identifying the client to protect the password. Will only work if the server CAPABILITY response includes the phrase AUTH=CRAM-MD5.

IMAP4.logout():Shutdown connection to server. Returns server BYE response.

IMAP4.lsub([directory[, pattern]]):List subscribed mailbox names in directory matching pattern. directory defaults to the top level directory and pattern defaults to match any mailbox. Returned data are tuples of message part envelope and data.

IMAP4.myrights(mailbox):Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).

IMAP4.namespace():Returns IMAP namespaces as defined in RFC2342.

IMAP4.noop():Send NOOP to server.

IMAP4.open(host, port):Opens socket to port at host. This method is implicitly called by the IMAP4 constructor. The connection objects established by this method will be used in the read, readline, send, and shutdown methods. You may override this method.

IMAP4.partial(message_num, message_part, start, length):Fetch truncated part of a message. Returned data is a tuple of message part envelope and data.

IMAP4.proxyauth(user):Assume authentication as user. Allows an authorised administrator to proxy into any user’s mailbox.

IMAP4.read(size):Reads size bytes from the remote server. You may override this method.

IMAP4.readline():Reads one line from the remote server. You may override this method.

IMAP4.recent():Prompt server for an update. Returned data is None if no new messages, else value of RECENT response.

IMAP4.rename(oldmailbox, newmailbox):Rename mailbox named oldmailbox to newmailbox.

IMAP4.response(code):Return data for response code if received, or None. Returns the given code, instead of the usual type.

IMAP4.search(charset, criterion[, ...]):Search mailbox for matching messages. charset may be None, in which case no CHARSET will be specified in the request to the server. The IMAP protocol requires that at least one criterion be specified; an exception will be raised when the server returns an error.

IMAP4.send(data):Sends data to the remote server. You may override this method.

IMAP4.setacl(mailbox, who, what):Set an ACL for mailbox. The method is non-standard, but is supported by the Cyrus server.

IMAP4.setannotation(mailbox, entry, attribute[, ...]):Set ANNOTATIONs for mailbox. The method is non-standard, but is supported by the Cyrus server.

IMAP4.setquota(root, limits):Set the quota root‘s resource limits. This method is part of the IMAP4 QUOTA extension defined in rfc2087.

IMAP4.shutdown():Close connection established in open. This method is implicitly called by IMAP4.logout(). You may override this method.

IMAP4.socket():Returns socket instance used to connect to server.

IMAP4.sort(sort_criteria, charset, search_criterion[, ...]):The sort command is a variant of search with sorting semantics for the results. Returned data contains a space separated list of matching message numbers.

IMAP4.status(mailbox, names):Request named status conditions for mailbox.

IMAP4.store(message_set, command, flag_list):Alters flag dispositions for messages in mailbox. command is specified by section 6.4.6 of RFC 2060 as being one of “FLAGS”, “+FLAGS”, or “-FLAGS”, optionally with a suffix of ”.SILENT”.

IMAP4.thread(threading_algorithm, charset, search_criterion[, ...]):The thread command is a variant of search with threading semantics for the results. Returned data contains a space separated list of thread members.

IMAP4.uid(command, arg[, ...]):Execute command args with messages identified by UID, rather than message number. Returns response appropriate to command. At least one argument must be supplied; if none are provided, the server will return an error and an exception will be raised.

IMAP4.unsubscribe(mailbox):Unsubscribe from old mailbox.

IMAP4.xatom(name[, arg[, ...]]):Allow simple extension commands notified by server in CAPABILITY response.

IMAP4_SSL.ssl():Returns SSLObject instance used for the secure connection with the server.

IMAP4.PROTOCOL_VERSION:The most recent supported protocol in the CAPABILITY response from the server.

IMAP4.debug:Integer value to control debugging output. The initialize value is taken from the module variable Debug. Values greater than three trace each command.

2、imap 命令詳解

CREATE <folder>:CREATE可以建立指定名字的新郵箱。郵箱名稱通常是帶路徑的資料夾全名。(有些IMAP客戶機使用郵件夾稱呼新郵箱)
C: A003 CREATE owatagusiam/                 /*建立一個新目錄owatagusiam*/
S: A003 OK CREATE completed
C: A004 CREATE owatagusiam/blurdybloop 
/* 在建立的目錄owatagusiam下建立一個名為blurdybloop 的郵箱,當然可以省略第一步,直接A004 CREATE owatagusiam/blurdybloop ,表示在新的目錄owatagusiam 下建立了一個名為blurdybloop 的郵箱*/        
S: A004 OK CREATE completed

DELETE <folder>:DELETE命令刪除指定名字的資料夾。資料夾名字通常是帶路徑的資料夾全名,當郵箱被刪除後,其中的郵件也不復存在。
C: A683 DELETE blurdybloop
S: A683 OK DELETE completed
C: A684 DELETE foo
S: A684 NO Name "foo" has inferior hierarchical names
C: A685 DELETE foo/bar
S: A685 OK DELETE Completed

RENAME <old folder><new folder>:RENAME命令可以修改資料夾的名稱,它使用兩個引數:當前郵箱名和新郵箱名,兩個引數的命名符合標準路徑命名規則。
C: A683 RENAME blurdybloop sarasoop
S: A683 OK RENAME completed
C: A684 RENAME stuff/junk newbox         /*把stuff目錄(資料夾)下的郵箱junk改名為newbox*/
S: A684 OK RENAME Completed

LIST <BASE><template>:LIST命令用於列出郵箱中已有的資料夾,有點像作業系統的列目錄命令,有兩個引數,郵箱路徑引數BASE:表示使用者登陸目錄;第二個引數template:表示希望顯示的郵箱名。這個命令可以包含起始的路徑位置和需要列出的資料夾所符合的特徵,可以使用萬用字元"*"。
C: A101 LIST "" ""
S: * LIST (\Noselect) "/" ""
S: A101 OK LIST Completed
C: A102 LIST #news.comp.mail.misc ""
S: * LIST (\Noselect) "." #news.
S: A102 OK LIST Completed
C: A103 LIST /usr/staff/jones ""
S: * LIST (\Noselect) "/" /
S: A103 OK LIST Completed
C: A202 LIST ~/Mail/ %
S: * LIST (\Noselect) "/" ~/Mail/foo
S: * LIST () "/" ~/Mail/meetings
S: A202 OK LIST completed

APPEND <folder><attributes><date/time><size><mail data>:APPEND命令允許Client上載一個郵件到指定的Folder(資料夾/郵箱)中。命令中包含了新郵件的屬性、日期/時間、大小,隨後是郵件資料。
C: A003 APPEND saved-messages (\Seen) {310}
C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
C: From: Fred Foobar <[email protected]>
C: Subject: afternoon meeting
C: To: [email protected]
C: Message-Id: <[email protected]>
C: MIME-Version: 1.0
C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
C:
C: Hello Joe, do you think we can meet at 3:30 tomorrow?
C:
S: A003 OK APPEND completed

SELECT <folder>:SELECT命令讓Client選定某個郵箱(Folder),表示即將對該郵箱(Folder)內的郵件作操作。郵箱標誌的當前狀態也返回給了使用者,同時返回的還有一些關於郵件和郵箱的附加資訊。
C: A142 SELECT INBOX
S: * 172 EXISTS
S: * 1 RECENT
S: * OK [UNSEEN 12] Message 12 is first unseen
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
S: A142 OK [READ-WRITE] SELECT completed

FETCH <mail id><datanames>:FETCH 命令用於讀取郵件的文字資訊,且僅用於顯示的目的。包含兩個引數,messageset:表示希望讀取的郵件號列表,IAMP伺服器郵箱中的每個郵件都有 一個唯一的ID標識,(郵件號列表引數可以是一個郵件號,也可以是由逗號分隔的多個郵件號,或者由冒號間隔的一個範圍),IMAP伺服器返回郵件號列表中 全部郵件的指定資料項內容。
資料名引數確定能夠被獨立返回的郵件的一部分,下面我們看看各引數返回的郵件資訊:
ALL:只返回按照一定格式的郵件摘要,包括郵件標誌、RFC822.SIZE、自身的時間和信封資訊。IMAP客戶機能夠將標準郵件解析成這些資訊並顯示出來。
BODY:只返回郵件體文字格式和大小的摘要資訊。IMAP客戶機可以識別這些細膩,並向用戶顯示詳細的關於郵件的資訊。其實是一些非擴充套件的BODYSTRUCTURE的資訊。
FAST:只返回郵件的一些摘要,包括郵件標誌、RFC822.SIZE、和自身的時間。
FULL:同樣的還是一些摘要資訊,包括郵件標誌、RFC822.SIZE、自身的時間和BODYSTRUCTURE的資訊。
BODYSTRUCTUR: 是郵件的[MIME-IMB]的體結構。這是伺服器通過解析[RFC-2822]頭中的[MIME-IMB]各欄位和[MIME-IMB]頭資訊得出來 的。包括的內容有:郵件正文的型別、字符集、編碼方式等和各附件的型別、字符集、編碼方式、檔名稱等等。
ENVELOPE:資訊的信封結構。是伺服器通過解析[RFC-2822]頭中的[MIME-IMB]各欄位得出來的,預設各欄位都是需要的。主要包括:自身的時間、附件數、收件人、發件人等。
FLAGS:此郵件的標誌。
INTERNALDATE:自身的時間。
RFC822.SIZE:郵件的[RFC-2822]大小
RFC822.HEADER:在功能上等同於BODY.PEEK[HEADER],
RFC822:功能上等同於BODY[]。
RFC822.TEXT:功能上等同於BODY[TEXT]
UID:返回郵件的UID號,UID號是唯一標識郵件的一個號碼。
BODY[section] <<partial>>:返回郵件的中的某一指定部分,返回的部分用section來表示,section部分包含的資訊通常是 代表某一部分的一個數字或者是下面的某一個部分:HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。如果section部分是空的話,那就代表返回全部的資訊,包括頭資訊。
BODY[HEADER]返回完整的檔案頭資訊。
BODY[HEADER.FIELDS ()]:在小括號裡面可以指定返回的特定欄位。
BODY[HEADER.FIELDS.NOT ()]:在小括號裡面可以指定不需要返回的特定欄位。
BODY[MIME]:返回郵件的[MIME-IMB]的頭資訊,在正常情況下跟BODY[HEADER]沒有區別。
BODY[TEXT]:返回整個郵件體,這裡的郵件體並不包括郵件頭。

STORE <mail id><new attributes>:STORE 命令用於修改指定郵件的屬性,包括給郵件打上已讀標記、刪除標記,等等。STORE命令當前只有兩個資料項型別可用,FLAGS:表示郵件的一組標誌; FLAGS.SLIENT,表示一組郵件的標誌,通過在兩種資料項前加上加號或者減號可以進一步改變它們的執行情況,加號表示資料項的值新增到郵件中,減 號表示將資料項的值從郵件中刪除。
C: A003 STORE 2:4 +FLAGS (\Deleted)      /*冒號表示間隔的一個範圍:給從2到4的郵件設定Deleted屬性*/
S: * 2 FETCH FLAGS (\Deleted \Seen)
S: * 3 FETCH FLAGS (\Deleted)
S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
S: A003 OK STORE completed
同時改命令還可以用於把郵件標記為未讀等等。在web上可以對郵件進行的操作在imap中都可以實現。

CLOSE:CLOSE命令表示Client結束對當前Folder(資料夾/郵箱)的訪問,關閉郵箱該郵箱中所有標誌為、DELETED的郵件就被從物理上刪除。CLOSE沒有命令引數。隨後可以SELECT另一Folder。
C: A341 CLOSE
S: A341 OK CLOSE completed


EXPUNGE:EXPUNGE命令在不關閉郵箱的情況下刪除所有的標誌為、DELETED的郵件。EXPUNGE刪除的郵件將不可以恢復。
C: A202 EXPUNGE
S: * 3 EXPUNGE
S: * 3 EXPUNGE
S: * 5 EXPUNGE
S: * 8 EXPUNGE
S: A202 OK EXPUNGE completed

LOGOUT:LOGOUT命令結束本次IMAP會話。
C: A023 LOGOUT
S: * BYE IMAP4rev1 Server logging out
S: A023 OK LOGOUT completed
(Server and client then close the connection)

EXAMINE <mailbox>:
EXAMINE命令以只讀方式開啟郵箱,引數是需要開啟的郵箱的名字,使用EXAMINE命令開啟的郵箱不允許對郵件進行改動,因此不能增加或刪除郵件的標誌。

SUBSCRIBE <mailbox>:SUBSCRIBE命令用來在客戶機的活動郵箱列表中增加一個郵箱,該命令只有一個引數,希望新增的郵箱名。
C: A114 SUBSCRIBE new/anotherbox
S: A114 OK SUBSCRIBE completed

UNSUBSCRIBE <mailbox>:UNSUBSCRIBE命令用來從活動列表中去掉一個郵箱,一個引數:希望去掉的郵箱名。
C: A115 UNSUBSCRIBE new/anotherbox
S: A115 OK SUBSCRIBE completed

LSUB <folder><mailbox>:LSUB命令修正了LIST命令,LIST返回使用者$HOME目錄下所有的檔案,但LSUB命令只顯示那些使用SUBSCRIBE命令設定為活動郵箱的檔案。兩個引數:郵箱路徑和郵箱名。
C: A116 LSUB “” *
S:* LSUB () “/” stuff/junk
S:* LSUB () “/” neebox
S:* LSUB () “/” new/anotherbox
S: A116 OK LSUB completed

STATUS <mailbox>(<parameter1>  < parameter2>  ……<parameter5>):STATUS命令查詢郵箱的當前狀態。第一個引數是需要查詢的郵箱名,第二個引數是客戶機需要查詢的專案列表(要查詢顯示的資訊),當在圓括號中。STATUS可以在不使用SELECT命令(開啟郵箱)或者EXAMINE(以只讀方式開啟郵箱)前提下獲取郵箱的資訊。
STATUS命令可以獲得的資料項
項 目                 說  明
MESSAGE         郵箱中的郵件總數
RECENT         郵箱中標誌為\RECENT的郵件數
UIDNEXT         可以分配給新郵件的下一個UID
UIDVALIDITY         郵箱的UID有效性標誌
UNSEEN         郵箱中沒有被標誌為\UNSEEN的郵件數
C: A117 STATUS inbox  (message recent unseen)
S:* STATUS inbox (MESSAGE 1 RECENT 0 UNSENN 0)
S: A117 OK STATUS completed
C: A118 STATUS newbox  (message recent unseen)
S:* STATUS inbox (MESSAGE 1 RECENT 0 UNSENN 2)
S: A118 OK STATUS completed

CHECK :CHECK命令用來在郵箱設定一個檢查點。沒有引數。就是IMAP中的sync命令。任何未完成的操作,例如從伺服器記憶體向硬碟寫資料,都將會被做完以保持郵箱的一致性狀態。該命令確保乃村中的磁碟緩衝資料都被寫到了磁碟上。

SEARCH [CHARSET specification] (search criteria):命 令可以根據搜尋條件在處於活動狀態的郵箱中搜索郵件,然後顯示匹配的郵件編號。字符集標誌引數[CHARSET specification]由CHARSET和註冊的字符集標誌符組成,預設的標誌符是US-ASCⅡ,所以該引數長省略。search criteria:查詢條件引數,明確查詢的關鍵字和值。查詢關鍵字有幾十種。
C: A119 SEARCH header subject another
S: SEARCH 1 2
S:* A119 OK SEARCH completed
C: A120 SEARCH header subject another
S: *SEARCH 2
S: A120 OK SEARCH completed
C: A121 SEARCH UNSEEN
S: *SEARCH 1 2
S: A120 OK SEARCH completed
以上每個例子都在郵件頭的Subject:欄位中查詢一個不同的單詞。伺服器返回條件的郵件號列表,如果沒有匹配郵件則返回不帶UID的SEARCH單詞。

COPY <mail id><mailboxname>:COPY命令可以把郵件從一個郵箱複製到另一個郵箱,兩個引數:mail id是希望從活動郵箱中複製的郵件的標號,mailboxname是希望郵件被複制到的郵箱。
IAMP沒有定義移動郵件的命令,移動操作相當於先把郵件複製到新郵箱中,然後對源郵箱中的郵件設定\DELETED標誌。下一次執行檢查點過後,新郵箱中的郵件被刪除,新郵件就被顯示出來。

UID:UID 命令和FETCH、COPY、STORE命令或者SEARCH命令一起使用,它允許這些命令使用郵件的UID號而不是在郵箱中的順序號。UID號是唯一標 識郵件系統中郵件的32位證書。通常這些命令都使用順序號來標識郵箱中的郵件,使用UID可以使IMAP客戶機記住不同IMAP會話中的郵件。

CAPABILITY:CAPABILITY命令請求返回IMAP伺服器支援的功能列表,伺服器收到客戶機發送的CAPABILITY命令後將返回該伺服器所支援的功能。無引數。
C: A122 CAPABILITY
S:*A122 CAPABILITY IMAP4 IMAP4REVl NAMESPACE IDLE SCAN SORT   MAILBOX
--REFERRALS [ic:ccc] LOGIN-REFERRALS AUTH=LOGIN THREAD=
ORDERDSUBJECT
S: A122 OK CAPABILITY completed

NOOP:NOOP命令什麼也不做,用來向伺服器傳送自動命令,防止因長時間處於不活動狀態而導致連線中斷,伺服器對該命令的響應始終為肯定。無引數。

LOGOUT:LOGOUT命令使當前登陸使用者退出登陸並關閉所有開啟的郵箱,任何做了\DELETED標誌的郵件都將在這個時候被刪除。

二、以yahoo郵箱為例進行偽無痕收信
    要做到郵件狀態不發生變化,實現上關鍵在fetch的引數上。如果我們僅是讀取郵件頭BODY.PEEK[HEADER],那麼郵件的狀態是不發生變化的。如果我們要讀取全部郵件內容,那麼必須使用BODY.PEEK[],這樣才能保證不發生變化。如下面的例子:

複製程式碼
#-*- coding:UTF-8 -*-
#@小五義 http://www.cnblogs.com/xiaowuyi

import imaplib, string, email
import os
M = imaplib.IMAP4_SSL("imap.mail.yahoo.com","993")
t=0
try:
    try:
        M.login('[email protected]','YYYY')####YYYY為密碼
    except Exception,e:
        #print "wrong!"
        print 'login error: %s' % e
        M.close()
    
    M.select('INBOX',False)
    
   # result, message = M.select()
    typ, data = M.search(None, 'ALL')
    for num in string.split(data[0]):
        try:
            typ, data = M.fetch(num, '(UID BODY.PEEK[])')
            msg = email.message_from_string(data[0][1])
            t=t+1
            filename=str(t)+".eml"
            f=open(filename,'wb')
            f.write(str(msg))
            f.close
        except Exception,e:
            print 'got msg error: %s' % e            
    print "OK!"
    M.logout()
except Exception, e:
    print 'imap error: %s' % e
    M.close()
複製程式碼

前面說的有些抽象,typ, data = M.fetch(num, '(UID BODY.PEEK[])')在這一句中,可以償試著將UID BODY.PEEK[HEADER]、UID BODY[]、RFC822、RFC822.HEADER等進行收信比較,將會更加直觀。這裡就不再一一解釋。

    所謂無痕取信,目前主要是指從郵箱中把信件收取後,郵箱內狀態不發生任何改變。這裡的狀態主要是指兩部分,一部分是郵件狀態不變,即已讀與未讀狀態不變,另一部分是指郵箱記錄的登陸IP不發生改變。本文中所說的偽“無痕”取信主要是指實現第一部分。
一、準備知識
1、Imaplib

IMAP4.append(mailbox, flags, date_time, message):Append message to named mailbox.

IMAP4.authenticate(mechanism, authobject):Authenticate command — requires response processing.mechanism specifies which authentication mechanism is to be used - it should appear in the instance variable capabilities in the form AUTH=mechanism.

IMAP4.check():Checkpoint mailbox on server.

IMAP4.close():Close currently selected mailbox. Deleted messages are removed from writable mailbox. This is the recommended command before LOGOUT.

IMAP4.copy(message_set, new_mailbox):Copy message_set messages onto end of new_mailbox.

IMAP4.create(mailbox):Create new mailbox named mailbox.

IMAP4.delete(mailbox):Delete old mailbox named mailbox.

IMAP4.deleteacl(mailbox, who):Delete the ACLs (remove any rights) set for who on mailbox.

IMAP4.expunge():Permanently remove deleted items from selected mailbox. Generates an EXPUNGE response for each deleted message. Returned data contains a list of EXPUNGE message numbers in order received.

IMAP4.fetch(message_set, message_parts):Fetch (parts of) messages. message_parts should be a string of message part names enclosed within parentheses, eg: "(UID BODY[TEXT])". Returned data are tuples of message part envelope and data.

IMAP4.getacl(mailbox):Get the ACLs for mailbox. The method is non-standard, but is supported by the Cyrus server.

IMAP4.getannotation(mailbox, entry, attribute):Retrieve the specified ANNOTATIONs for mailbox. The method is non-standard, but is supported by the Cyrus server.

IMAP4.getquota(root):Get the quota root‘s resource usage and limits. This method is part of the IMAP4 QUOTA extension defined in rfc2087.

IMAP4.getquotaroot(mailbox):Get the list of quota roots for the named mailbox. This method is part of the IMAP4 QUOTA extension defined in rfc2087.

IMAP4.list([directory[, pattern]]):List mailbox names in directory matching pattern. directory defaults to the top-level mail folder, and pattern defaults to match anything. Returned data contains a list of LIST responses.

IMAP4.login(user, password):Identify the client using a plaintext password. The password will be quoted.

IMAP4.login_cram_md5(user, password):Force use of CRAM-MD5 authentication when identifying the client to protect the password. Will only work if the server CAPABILITY response includes the phrase AUTH=CRAM-MD5.

IMAP4.logout():Shutdown connection to server. Returns server BYE response.

IMAP4.lsub([directory[, pattern]]):List subscribed mailbox names in directory matching pattern. directory defaults to the top level directory and pattern defaults to match any mailbox. Returned data are tuples of message part envelope and data.

IMAP4.myrights(mailbox):Show my ACLs for a mailbox (i.e. the rights that I have on mailbox).

IMAP4.namespace():Returns IMAP namespaces as defined in RFC2342.

IMAP4.noop():Send NOOP to server.

IMAP4.open(host, port):Opens socket to port at host. This method is implicitly called by the IMAP4 constructor. The connection objects established by this method will be used in the read, readline, send, and shutdown methods. You may override this method.

IMAP4.partial(message_num, message_part, start, length):Fetch truncated part of a message. Returned data is a tuple of message part envelope and data.

IMAP4.proxyauth(user):Assume authentication as user. Allows an authorised administrator to proxy into any user’s mailbox.

IMAP4.read(size):Reads size bytes from the remote server. You may override this method.

IMAP4.readline():Reads one line from the remote server. You may override this method.

IMAP4.recent():Prompt server for an update. Returned data is None if no new messages, else value of RECENT response.

IMAP4.rename(oldmailbox, newmailbox):Rename mailbox named oldmailbox to newmailbox.

IMAP4.response(code):Return data for response code if received, or None. Returns the given code, instead of the usual type.

IMAP4.search(charset, criterion[, ...]):Search mailbox for matching messages. charset may be None, in which case no CHARSET will be specified in the request to the server. The IMAP protocol requires that at least one criterion be specified; an exception will be raised when the server returns an error.

IMAP4.send(data):Sends data to the remote server. You may override this method.

IMAP4.setacl(mailbox, who, what):Set an ACL for mailbox. The method is non-standard, but is supported by the Cyrus server.

IMAP4.setannotation(mailbox, entry, attribute[, ...]):Set ANNOTATIONs for mailbox. The method is non-standard, but is supported by the Cyrus server.

IMAP4.setquota(root, limits):Set the quota root‘s resource limits. This method is part of the IMAP4 QUOTA extension defined in rfc2087.

IMAP4.shutdown():Close connection established in open. This method is implicitly called by IMAP4.logout(). You may override this method.

IMAP4.socket():Returns socket instance used to connect to server.

IMAP4.sort(sort_criteria, charset, search_criterion[, ...]):The sort command is a variant of search with sorting semantics for the results. Returned data contains a space separated list of matching message numbers.

IMAP4.status(mailbox, names):Request named status conditions for mailbox.

IMAP4.store(message_set, command, flag_list):Alters flag dispositions for messages in mailbox. command is specified by section 6.4.6 of RFC 2060 as being one of “FLAGS”, “+FLAGS”, or “-FLAGS”, optionally with a suffix of ”.SILENT”.

IMAP4.thread(threading_algorithm, charset, search_criterion[, ...]):The thread command is a variant of search with threading semantics for the results. Returned data contains a space separated list of thread members.

IMAP4.uid(command, arg[, ...]):Execute command args with messages identified by UID, rather than message number. Returns response appropriate to command. At least one argument must be supplied; if none are provided, the server will return an error and an exception will be raised.

IMAP4.unsubscribe(mailbox):Unsubscribe from old mailbox.

IMAP4.xatom(name[, arg[, ...]]):Allow simple extension commands notified by server in CAPABILITY response.

IMAP4_SSL.ssl():Returns SSLObject instance used for the secure connection with the server.

IMAP4.PROTOCOL_VERSION:The most recent supported protocol in the CAPABILITY response from the server.

IMAP4.debug:Integer value to control debugging output. The initialize value is taken from the module variable Debug. Values greater than three trace each command.

2、imap 命令詳解

CREATE <folder>:CREATE可以建立指定名字的新郵箱。郵箱名稱通常是帶路徑的資料夾全名。(有些IMAP客戶機使用郵件夾稱呼新郵箱)
C: A003 CREATE owatagusiam/                 /*建立一個新目錄owatagusiam*/
S: A003 OK CREATE completed
C: A004 CREATE owatagusiam/blurdybloop 
/* 在建立的目錄owatagusiam下建立一個名為blurdybloop 的郵箱,當然可以省略第一步,直接A004 CREATE owatagusiam/blurdybloop ,表示在新的目錄owatagusiam 下建立了一個名為blurdybloop 的郵箱*/        
S: A004 OK CREATE completed

DELETE <folder>:DELETE命令刪除指定名字的資料夾。資料夾名字通常是帶路徑的資料夾全名,當郵箱被刪除後,其中的郵件也不復存在。
C: A683 DELETE blurdybloop
S: A683 OK DELETE completed
C: A684 DELETE foo
S: A684 NO Name "foo" has inferior hierarchical names
C: A685 DELETE foo/bar
S: A685 OK DELETE Completed

RENAME <old folder><new folder>:RENAME命令可以修改資料夾的名稱,它使用兩個引數:當前郵箱名和新郵箱名,兩個引數的命名符合標準路徑命名規則。
C: A683 RENAME blurdybloop sarasoop
S: A683 OK RENAME completed
C: A684 RENAME stuff/junk newbox         /*把stuff目錄(資料夾)下的郵箱junk改名為newbox*/
S: A684 OK RENAME Completed

LIST <BASE><template>:LIST命令用於列出郵箱中已有的資料夾,有點像作業系統的列目錄命令,有兩個引數,郵箱路徑引數BASE:表示使用者登陸目錄;第二個引數template:表示希望顯示的郵箱名。這個命令可以包含起始的路徑位置和需要列出的資料夾所符合的特徵,可以使用萬用字元"*"。
C: A101 LIST "" ""
S: * LIST (\Noselect) "/" ""
S: A101 OK LIST Completed
C: A102 LIST #news.comp.mail.misc ""
S: * LIST (\Noselect) "." #news.
S: A102 OK LIST Completed
C: A103 LIST /usr/staff/jones ""
S: * LIST (\Noselect) "/" /
S: A103 OK LIST Completed
C: A202 LIST ~/Mail/ %
S: * LIST (\Noselect) "/" ~/Mail/foo
S: * LIST () "/" ~/Mail/meetings
S: A202 OK LIST completed

APPEND <folder><attributes><date/time><size><mail data>:APPEND命令允許Client上載一個郵件到指定的Folder(資料夾/郵箱)中。命令中包含了新郵件的屬性、日期/時間、大小,隨後是郵件資料。
C: A003 APPEND saved-messages (\Seen) {310}
C: Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
C: From: Fred Foobar <[email protected]>
C: Subject: afternoon meeting
C: To: [email protected]
C: Message-Id: <[email protected]>
C: MIME-Version: 1.0
C: Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
C:
C: Hello Joe, do you think we can meet at 3:30 tomorrow?
C:
S: A003 OK APPEND completed

SELECT <folder>:SELECT命令讓Client選定某個郵箱(Folder),表示即將對該郵箱(Folder)內的郵件作操作。郵箱標誌的當前狀態也返回給了使用者,同時返回的還有一些關於郵件和郵箱的附加資訊。
C: A142 SELECT INBOX
S: * 172 EXISTS
S: * 1 RECENT
S: * OK [UNSEEN 12] Message 12 is first unseen
S: * OK [UIDVALIDITY 3857529045] UIDs valid
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
S: A142 OK [READ-WRITE] SELECT completed

FETCH <mail id><datanames>:FETCH 命令用於讀取郵件的文字資訊,且僅用於顯示的目的。包含兩個引數,messageset:表示希望讀取的郵件號列表,IAMP伺服器郵箱中的每個郵件都有 一個唯一的ID標識,(郵件號列表引數可以是一個郵件號,也可以是由逗號分隔的多個郵件號,或者由冒號間隔的一個範圍),IMAP伺服器返回郵件號列表中 全部郵件的指定資料項內容。
資料名引數確定能夠被獨立返回的郵件的一部分,下面我們看看各引數返回的郵件資訊:
ALL:只返回按照一定格式的郵件摘要,包括郵件標誌、RFC822.SIZE、自身的時間和信封資訊。IMAP客戶機能夠將標準郵件解析成這些資訊並顯示出來。
BODY:只返回郵件體文字格式和大小的摘要資訊。IMAP客戶機可以識別這些細膩,並向用戶顯示詳細的關於郵件的資訊。其實是一些非擴充套件的BODYSTRUCTURE的資訊。
FAST:只返回郵件的一些摘要,包括郵件標誌、RFC822.SIZE、和自身的時間。
FULL:同樣的還是一些摘要資訊,包括郵件標誌、RFC822.SIZE、自身的時間和BODYSTRUCTURE的資訊。
BODYSTRUCTUR: 是郵件的[MIME-IMB]的體結構。這是伺服器通過解析[RFC-2822]頭中的[MIME-IMB]各欄位和[MIME-IMB]頭資訊得出來 的。包括的內容有:郵件正文的型別、字符集、編碼方式等和各附件的型別、字符集、編碼方式、檔名稱等等。
ENVELOPE:資訊的信封結構。是伺服器通過解析[RFC-2822]頭中的[MIME-IMB]各欄位得出來的,預設各欄位都是需要的。主要包括:自身的時間、附件數、收件人、發件人等。
FLAGS:此郵件的標誌。
INTERNALDATE:自身的時間。
RFC822.SIZE:郵件的[RFC-2822]大小
RFC822.HEADER:在功能上等同於BODY.PEEK[HEADER],
RFC822:功能上等同於BODY[]。
RFC822.TEXT:功能上等同於BODY[TEXT]
UID:返回郵件的UID號,UID號是唯一標識郵件的一個號碼。
BODY[section] <<partial>>:返回郵件的中的某一指定部分,返回的部分用section來表示,section部分包含的資訊通常是 代表某一部分的一個數字或者是下面的某一個部分:HEADER, HEADER.FIELDS, HEADER.FIELDS.NOT, MIME, and TEXT。如果section部分是空的話,那就代表返回全部的資訊,包括頭資訊。
BODY[HEADER]返回完整的檔案頭資訊。
BODY[HEADER.FIELDS ()]:在小括號裡面可以指定返回的特定欄位。
BODY[HEADER.FIELDS.NOT ()]:在小括號裡面可以指定不需要返回的特定欄位。
BODY[MIME]:返回郵件的[MIME-IMB]的頭資訊,在正常情況下跟BODY[HEADER]沒有區別。
BODY[TEXT]:返回整個郵件體,這裡的郵件體並不包括郵件頭。

STORE <mail id><new attributes>:STORE 命令用於修改指定郵件的屬性,包括給郵件打上已讀標記、刪除標記,等等。STORE命令當前只有兩個資料項型別可用,FLAGS:表示郵件的一組標誌; FLAGS.SLIENT,表示一組郵件的標誌,通過在兩種資料項前加上加號或者減號可以進一步改變它們的執行情況,加號表示資料項的值新增到郵件中,減 號表示將資料項的值從郵件中刪除。
C: A003 STORE 2:4 +FLAGS (\Deleted)      /*冒號表示間隔的一個範圍:給從2到4的郵件設定Deleted屬性*/
S: * 2 FETCH FLAGS (\Deleted \Seen)
S: * 3 FETCH FLAGS (\Deleted)
S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
S: A003 OK STORE completed
同時改命令還可以用於把郵件標記為未讀等等。在web上可以對郵件進行的操作在imap中都可以實現。

CLOSE:CLOSE命令表示Client結束對當前Folder(資料夾/郵箱)的訪問,關閉郵箱該郵箱中所有標誌為、DELETED的郵件就被從物理上刪除。CLOSE沒有命令引數。隨後可以SELECT另一Folder。
C: A341 CLOSE
S: A341 OK CLOSE completed


EXPUNGE:EXPUNGE命令在不關閉郵箱的情況下刪除所有的標誌為、DELETED的郵件。EXPUNGE刪除的郵件將不可以恢復。
C: A202 EXPUNGE
S: * 3 EXPUNGE
S: * 3 EXPUNGE
S: * 5 EXPUNGE
S: * 8 EXPUNGE
S: A202 OK EXPUNGE completed

LOGOUT:LOGOUT命令結束本次IMAP會話。
C: A023 LOGOUT
S: * BYE IMAP4rev1 Server logging out
S: A023 OK LOGOUT completed
(Server and client then close the connection)

EXAMINE <mailbox>:
EXAMINE命令以只讀方式開啟郵箱,引數是需要開啟的郵箱的名字,使用EXAMINE命令開啟的郵箱不允許對郵件進行改動,因此不能增加或刪除郵件的標誌。

SUBSCRIBE <mailbox>:SUBSCRIBE命令用來在客戶機的活動郵箱列表中增加一個郵箱,該命令只有一個引數,希望新增的郵箱名。
C: A114 SUBSCRIBE new/anotherbox
S: A114 OK SUBSCRIBE completed

UNSUBSCRIBE <mailbox>:UNSUBSCRIBE命令用來從活動列表中去掉一個郵箱,一個引數:希望去掉的郵箱名。
C: A115 UNSUBSCRIBE new/anotherbox
S: A115 OK SUBSCRIBE completed

LSUB <folder><mailbox>:LSUB命令修正了LIST命令,LIST返回使用者$HOME目錄下所有的檔案,但LSUB命令只顯示那些使用SUBSCRIBE命令設定為活動郵箱的檔案。兩個引數:郵箱路徑和郵箱名。
C: A116 LSUB “” *
S:* LSUB () “/” stuff/junk
S:* LSUB () “/” neebox
S:* LSUB () “/” new/anotherbox
S: A116 OK LSUB completed

STATUS <mailbox>(<parameter1>  < parameter2>  ……<parameter5>):STATUS命令查詢郵箱的當前狀態。第一個引數是需要查詢的郵箱名,第二個引數是客戶機需要查詢的專案列表(要查詢顯示的資訊),當在圓括號中。STATUS可以在不使用SELECT命令(開啟郵箱)或者EXAMINE(以只讀方式開啟郵箱)前提下獲取郵箱的資訊。
STATUS命令可以獲得的資料項
項 目                 說  明
MESSAGE         郵箱中的郵件總數
RECENT         郵箱中標誌為\RECENT的郵件數
UIDNEXT         可以分配給新郵件的下一個UID
UIDVALIDITY         郵箱的UID有效性標誌
UNSEEN         郵箱中沒有被標誌為\UNSEEN的郵件數
C: A117 STATUS inbox  (message recent unseen)
S:* STATUS inbox (MESSAGE 1 RECENT 0 UNSENN 0)
S: A117 OK STATUS completed
C: A118 STATUS newbox  (message recent unseen)
S:* STATUS inbox (MESSAGE 1 RECENT 0 UNSENN 2)
S: A118 OK STATUS completed

CHECK :CHECK命令用來在郵箱設定一個檢查點。沒有引數。就是IMAP中的sync命令。任何未完成的操作,例如從伺服器記憶體向硬碟寫資料,都將會被做完以保持郵箱的一致性狀態。該命令確保乃村中的磁碟緩衝資料都被寫到了磁碟上。

SEARCH [CHARSET specification] (search criteria):命 令可以根據搜尋條件在處於活動狀態的郵箱中搜索郵件,然後顯示匹配的郵件編號。字符集標誌引數[CHARSET specification]由CHARSET和註冊的字符集標誌符組成,預設的標誌符是US-ASCⅡ,所以該引數長省略。search criteria:查詢條件引數,明確查詢的關鍵字和值。查詢關鍵字有幾十種。
C: A119 SEARCH header subject another
S: SEARCH 1 2
S:* A119 OK SEARCH completed
C: A120 SEARCH header subject another
S: *SEARCH 2
S: A120 OK SEARCH completed
C: A121 SEARCH UNSEEN
S: *SEARCH 1 2
S: A120 OK SEARCH completed
以上每個例子都在郵件頭的Subject:欄位中查詢一個不同的單詞。伺服器返回條件的郵件號列表,如果沒有匹配郵件則返回不帶UID的SEARCH單詞。

COPY <mail id><mailboxname>:COPY命令可以把郵件從一個郵箱複製到另一個郵箱,兩個引數:mail id是希望從活動郵箱中複製的郵件的標號,mailboxname是希望郵件被複制到的郵箱。
IAMP沒有定義移動郵件的命令,移動操作相當於先把郵件複製到新郵箱中,然後對源郵箱中的郵件設定\DELETED標誌。下一次執行檢查點過後,新郵箱中的郵件被刪除,新郵件就被顯示出來。

UID:UID 命令和FETCH、COPY、STORE命令或者SEARCH命令一起使用,它允許這些命令使用郵件的UID號而不是在郵箱中的順序號。UID號是唯一標 識郵件系統中郵件的32位證書。通常這些命令都使用順序號來標識郵箱中的郵件,使用UID可以使IMAP客戶機記住不同IMAP會話中的郵件。

CAPABILITY:CAPABILITY命令請求返回IMAP伺服器支援的功能列表,伺服器收到客戶機發送的CAPABILITY命令後將返回該伺服器所支援的功能。無引數。
C: A122 CAPABILITY
S:*A122 CAPABILITY IMAP4 IMAP4REVl NAMESPACE IDLE SCAN SORT   MAILBOX
--REFERRALS [ic:ccc] LOGIN-REFERRALS AUTH=LOGIN THREAD=
ORDERDSUBJECT
S: A122 OK CAPABILITY completed

NOOP:NOOP命令什麼也不做,用來向伺服器傳送自動命令,防止因長時間處於不活動狀態而導致連線中斷,伺服器對該命令的響應始終為肯定。無引數。

LOGOUT:LOGOUT命令使當前登陸使用者退出登陸並關閉所有開啟的郵箱,任何做了\DELETED標誌的郵件都將在這個時候被刪除。

二、以yahoo郵箱為例進行偽無痕收信
    要做到郵件狀態不發生變化,實現上關鍵在fetch的引數上。如果我們僅是讀取郵件頭BODY.PEEK[HEADER],那麼郵件的狀態是不發生變化的。如果我們要讀取全部郵件內容,那麼必須使用BODY.PEEK[],這樣才能保證不發生變化。如下面的例子:

複製程式碼
#-*- coding:UTF-8 -*-
#@小五義 http://www.cnblogs.com/xiaowuyi

import imaplib, string, email
import os
M = imaplib.IMAP4_SSL("imap.mail.yahoo.com","993")
t=0
try:
    try:
        M.login('[email protected]','YYYY')####YYYY為密碼
    except Exception,e:
        #print "wrong!"
        print 'login error: %s' % e
        M.close()
    
    M.select('INBOX',False)
    
   # result, message = M.select()
    typ, data = M.search(None, 'ALL')
    for num in string.split(data[0]):
        try:
            typ, data = M.fetch(num, '(UID BODY.PEEK[])')
            msg = email.message_from_string(data[0][1])
            t=t+1
            filename=str(t)+".eml"
            f=open(filename,'wb')
            f.write(str(msg))
            f.close
        except Exception,e:
            print 'got msg error: %s' % e            
    print "OK!"
    M.logout()
except Exception, e:
    print 'imap error: %s' % e
    M.close()
複製程式碼

前面說的有些抽象,typ, data = M.fetch(num, '(UID BODY.PEEK[])')在這一句中,可以償試著將UID BODY.PEEK[HEADER]、UID BODY[]、RFC822、RFC822.HEADER等進行收信比較,將會更加直觀。這裡就不再一一解釋。