2015-04-03 116 views
1

我從IMAP郵件下載與imaplib到MBOX(與mailbox模塊):保存IMAP郵件與Python郵箱模塊

import imaplib, mailbox 
svr = imaplib.IMAP4_SSL('imap.gmail.com') 
svr.login('[email protected]', 'mypaswword') 
resp, [countstr] = svr.select("[Gmail]/All Mail", True) 

mbox = mailbox.mbox('mails.mbox') 

for n in range(...): 
    resp, lst1 = svr.fetch(n, 'UID') # the UID of the message 
    resp, lst2 = svr.fetch(n, '(RFC822)') # the message itself 
    mbox.add(lst2[0][1])  # add the downloaded message to the mbox 
    # 
    # how to store the UID of this current mail inside mbox? 
    # 

讓我們下載郵件與UID = 1 .. 1000。下一次,我想從第1001條消息開始,而不是從第1條開始。但是,mailbox.mbox不存儲UID任何。所以下次我打開這個mbox文件,就不可能知道我們停止了什麼。

模塊mailbox是否有自然的方式來存儲電子郵件的UID

或者,也許我不使用mailbox + imaplib它的方式?

回答

1

要回答你的問題:在長時間盯着文檔後,我沒有看到任何干淨的方式來做你正在尋找的東西。如果是的UID存儲在MBOX文件的絕對要求,那麼我會建議增加一個自定義的UID頭,你是存儲電子郵件:

message = email.message_from_string(lst2[0][1]) 
message.add_header("my_internal_uid_header", lst1[0][1]) 
mbox.add(message) 

現在當然是一個巨大的痛苦,以獲取最大的已保存UID,因爲您必須遍歷所有消息。我想這將是真的很差。如果可能的話,將這些信息存儲在其他地方會更好。

祝你好運!

+0

確實,獲得最大的已保存UID是非常重要的,因爲必須進行迭代...您會做什麼@JosiahDaniels? – Basj 2015-04-12 21:21:14

+0

我不確定你有什麼要求。例如,你可以將它存儲在同一個文件夾中的單獨的json文件中嗎?或者是否將UID保存在mmox文件中很重要? – JosiahDaniels 2015-04-12 21:31:41

+0

所有我想要的是能夠不重新下載兩次相同的消息到mbox中。我希望這隻適用於mbox而不需要外部文件。我正在尋找一個不錯的pythonic解決方案;)但是如果外部JSON是強制性的,讓我們這樣做......即使這是一種恥辱;) – Basj 2015-04-12 21:56:29

1

我希望這將是有益的:

1)庫和環境的Win7 Anaconda3-4.3.1-Windows的x86_64.exe(新是有的,但我已經用什麼

2)要列出所有郵箱:

import getpass, imaplib, sys 

def main(): 
     hostname = 'my.mail.server' 
     username = 'my_user_name' 
     m = imaplib.IMAP4_SSL(hostname) 
     m.login(username, 'passowrd') 

    try: 
     print('Capabilities:', m.capabilities) 
     print('Listing mailboxes ') 
     status, data = m.list() 
     print('Status:', repr(status)) 
     print('Data:') 
     for datum in data: 
     print(repr(datum)) 

    finally: 
     m.logout() 

if __name__ == '__main__': 
    main() 

3)上述信息用生成的,我們可以轉儲從郵件服務器的所有電子郵件消息的目錄:

import getpass, imaplib, sys, email, os , io 
import codecs 

BASE_NAME = 'msg_no_' 
BASE_DIR = 'D:/my_email/' 

def writeTofile(mailDir, partOfName, msg): 

    ## no need of dos backslash -- newDir = BASE_DIR + mailDir.replace('/', '\\') 

    newDir = BASE_DIR + mailDir 

    if not os.path.exists(newDir): 
     os.makedirs(newDir) 

    os.chdir(newDir) 

    # print('Dir:' + os.getcwd()) 

    file_name = BASE_NAME + partOfName + '.eml' 

    # print('Write:' + file_name) 

    fw = open(newDir + '/' + file_name,'w', encoding="utf-8") 
    fw.write(msg) 
    fw.close() 

    return 


def processMailDir(m, mailDir): 

    print('MailDIR:' + mailDir) 

    m.select(mailbox=mailDir, readonly=True) 
    typ, data = m.search(None, 'ALL') 

    for num in data[0].split(): 
     typ, data = m.fetch(num, '(RFC822)') 
     msg = email.message_from_bytes(data[0][1]) 

     smsg = msg.as_bytes().decode(encoding='ISO-8859-1') 

     writeTofile(mailDir, num.decode(), smsg) 

    m.close() 

    return 


def main(): 

    if len(sys.argv) != 3: 
     hostname = 'my.mail.server' 
     username = 'my_username' 
     m = imaplib.IMAP4_SSL(hostname) 
     m.login(username, 'password') 

    else: 
     hostname, username = sys.argv[1:] 
     m = imaplib.IMAP4_SSL(hostname) 
     m.login(username, getpass.getpass()) 

    try: 
     print('Start...') 

     processMailDir(m, 'INBOX') 
     processMailDir(m, 'Sent') 
     processMailDir(m, 'archive/2013/201301') 
     processMailDir(m, 'archive/2013/201302') 
# etc.. etc.. simple as it can be but not simpler 
     print('Done...') 

    finally: 
     m.logout() 

if __name__ == '__main__': 
    main() 

上面會甩掉你的電子郵件到: d:\ MY_EMAIL \收件箱\ msg_no_1.eml ... msg_no203.eml

,那麼你需要這個祕密打開EML對窗口:

Administrator: cmd.com: 

assoc .eml=Outlook.File.eml 
ftype Outlook.File.eml="C:\Program Files (x86)\Microsoft Office\Office12\OUTLOOK.EXE" /eml "%1" 

尊敬stockoverflow censor - 請大發慈悲,我會發現上面有用;例如:smsg = msg.as_bytes()。decode(encoding ='ISO-8859-1')花了很長時間才弄清楚。