2010-08-20 67 views

回答

33

沒有爲IMAP沒有明確的移動命令。你將不得不執行COPY後跟一個STORE(用合適的標誌,表示刪除),最後expunge。下面給出的例子適用於將消息從一個標籤移動到另一個標籤。儘管你可能想添加更多的錯誤檢查。

import imaplib, getpass, re 
pattern_uid = re.compile('\d+ \(UID (?P<uid>\d+)\)') 

def connect(email): 
    imap = imaplib.IMAP4_SSL("imap.gmail.com") 
    password = getpass.getpass("Enter your password: ") 
    imap.login(email, password) 
    return imap 

def disconnect(imap): 
    imap.logout() 

def parse_uid(data): 
    match = pattern_uid.match(data) 
    return match.group('uid') 

if __name__ == '__main__': 
    imap = connect('<your mail id>') 
    imap.select(mailbox = '<source folder>', readonly = False) 
    resp, items = imap.search(None, 'All') 
    email_ids = items[0].split() 
    latest_email_id = email_ids[-1] # Assuming that you are moving the latest email. 

    resp, data = imap.fetch(latest_email_id, "(UID)") 
    msg_uid = parse_uid(data[0]) 

    result = imap.uid('COPY', msg_uid, '<destination folder>') 

    if result[0] == 'OK': 
     mov, data = imap.uid('STORE', msg_uid , '+FLAGS', '(\Deleted)') 
     imap.expunge() 

    disconnect(imap) 
+2

上移動多條消息有什麼想法?你是否必須執行另一個搜索並使用email_ids [-1]接收最新消息? – ewalk 2010-09-16 19:25:23

+3

當您將郵件複製到「[Gmail] /垃圾箱」時,Gmail IMAP *會自動*爲您執行'\ Deleted' /'EXPUNGE'。 – dkarp 2011-03-01 23:37:44

+0

@dkarp感謝您提供的信息。我在過去的一週裏一直在努力。 – 2011-06-15 10:15:21

4

我想一個人的電子郵件將被移動。

import imaplib 
obj = imaplib.IMAP4_SSL('imap.gmail.com', 993) 
obj.login('username', 'password') 
obj.select(src_folder_name) 
apply_lbl_msg = obj.uid('COPY', msg_uid, desti_folder_name) 
if apply_lbl_msg[0] == 'OK': 
    mov, data = obj.uid('STORE', msg_uid , '+FLAGS', '(\Deleted)') 
    obj.expunge() 
4

作爲Gmail的基礎上,其api working with labels,你要做的就是加入DEST標籤和刪除SRC標籤的唯一的事情:

import imaplib 
obj = imaplib.IMAP4_SSL('imap.gmail.com', 993) 
obj.login('username', 'password') 
obj.select(src_folder_name) 
typ, data = obj.uid('STORE', msg_uid, '+X-GM-LABELS', desti_folder_name) 
typ, data = obj.uid('STORE', msg_uid, '-X-GM-LABELS', src_folder_name) 
+0

這不適合我。它添加了desti_folder_name標籤,但它並未刪除src_folder_name標籤。雖然上面的Manoj Govindan的解決方案對我來說確實有效。 – mernst 2012-10-28 05:25:02

+0

我可以確認一致,但爲何刪除不起作用?什麼是正確的解決方案? – sorin 2013-06-23 17:23:52

+0

@sorin這對我有用,你可能做錯了什麼。我現在按照所有步驟按照行... – scraplesh 2013-06-26 13:47:28

3

以前的解決方案都沒有爲我工作。我無法從選定文件夾中刪除郵件,並且無法在標籤爲選定文件夾時刪除該文件夾的標籤。這是什麼結束了爲我工作:

import email, getpass, imaplib, os, sys, re 

user = "[email protected]" 
pwd = "password" #getpass.getpass("Enter your password: ") 

m = imaplib.IMAP4_SSL("imap.gmail.com") 
m.login(user,pwd) 

from_folder = "Notes" 
to_folder = "food" 

m.select(from_folder, readonly = False) 

response, emailids = imap.search(None, 'All') 
assert response == 'OK' 

emailids = emailids[0].split() 

errors = [] 
labeled = [] 
for emailid in emailids: 
    result = m.fetch(emailid, '(X-GM-MSGID)') 
    if result[0] != 'OK': 
     errors.append(emailid) 
     continue 

    gm_msgid = re.findall(r"X-GM-MSGID (\d+)", result[1][0])[0] 

    result = m.store(emailid, '+X-GM-LABELS', to_folder) 

    if result[0] != 'OK': 
     errors.append(emailid) 
     continue 

    labeled.append(gm_msgid) 

m.close() 
m.select(to_folder, readonly = False) 

errors2 = [] 

for gm_msgid in labeled: 
    result = m.search(None, '(X-GM-MSGID "%s")' % gm_msgid) 

    if result[0] != 'OK': 
     errors2.append(gm_msgid) 
     continue 

    emailid = result[1][0] 
    result = m.store(emailid, '-X-GM-LABELS', from_folder) 

    if result[0] != 'OK': 
     errors2.append(gm_msgid) 
     continue 

m.close() 
m.logout() 

if errors: print >>sys.stderr, len(errors), "failed to add label", to_folder 
if errors2: print >>sys.stderr, len(errors2), "failed to remove label", from_folder 
0

我知道這是一個非常古老的問題,但任何方式。由Manoj Govindan提出的解決方案可能完美的作品(我還沒有測試過,但它看起來像它。我遇到的問題,我必須解決的是如何複製/移動多個電子郵件!!!

所以我來

步驟很簡單,我連接到我的電子郵件(GMAIL)帳戶選擇要處理的文件夾(例如INBOX)獲取所有的uids,而不是電子郵件( s)list number。這是一個需要注意的地方,如果我們提取了郵件列表的數量,然後我們處理了這個列表,我們最終會遇到一個問題,當我們移動一個郵件時,這個過程很簡單(複製到目的地文件夾並刪除每個當前位置的電子郵件)。如果您有列表,則會出現問題的電子郵件,例如收件箱中有4封電子郵件,我們在列表中處理第2封電子郵件,然後第3封和第4封不同,它們不是我們認爲會是的電子郵件,這將導致錯誤,因爲列表項目編號4不會自從名單下移一位以來,因爲2位是空的而存在。

因此,唯一可能的解決這個問題是使用的UID。每個電子郵件都是唯一的號碼。所以不管電子郵件如何改變,這個號碼都會被電子郵件綁定。

所以在下面的例子中,我取的第一步的UID,檢查文件夾爲空,不進行處理的文件夾中找到的所有郵件的文件夾其他迭代的點。接下來獲取每個電子郵件標題。標題將幫助我們獲取主題並將電子郵件的主題與我們正在搜索的主題進行比較。如果主題匹配,則繼續複製並刪除電子郵件。然後你就完成了。就那麼簡單。

#!/usr/bin/env python 

import email 
import pprint 
import imaplib 

__author__ = 'author' 


def initialization_process(user_name, user_password, folder): 
    imap4 = imaplib.IMAP4_SSL('imap.gmail.com') # Connects over an SSL encrypted socket 
    imap4.login(user_name, user_password) 
    imap4.list() # List of "folders" aka labels in gmail 
    imap4.select(folder) # Default INBOX folder alternative select('FOLDER') 
    return imap4 


def logout_process(imap4): 
    imap4.close() 
    imap4.logout() 
    return 


def main(user_email, user_pass, scan_folder, subject_match, destination_folder): 
    try: 
     imap4 = initialization_process(user_email, user_pass, scan_folder) 
     result, items = imap4.uid('search', None, "ALL") # search and return uids 
     dictionary = {} 
     if items == ['']: 
      dictionary[scan_folder] = 'Is Empty' 
     else: 
      for uid in items[0].split(): # Each uid is a space separated string 
       dictionary[uid] = {'MESSAGE BODY': None, 'BOOKING': None, 'SUBJECT': None, 'RESULT': None} 
       result, header = imap4.uid('fetch', uid, '(UID BODY[HEADER])') 
       if result != 'OK': 
        raise Exception('Can not retrieve "Header" from EMAIL: {}'.format(uid)) 
       subject = email.message_from_string(header[0][1]) 
       subject = subject['Subject'] 
       if subject is None: 
        dictionary[uid]['SUBJECT'] = '(no subject)' 
       else: 
        dictionary[uid]['SUBJECT'] = subject 
       if subject_match in dictionary[uid]['SUBJECT']: 
        result, body = imap4.uid('fetch', uid, '(UID BODY[TEXT])') 
        if result != 'OK': 
         raise Exception('Can not retrieve "Body" from EMAIL: {}'.format(uid)) 
        dictionary[uid]['MESSAGE BODY'] = body[0][1] 
        list_body = dictionary[uid]['MESSAGE BODY'].splitlines() 
        result, copy = imap4.uid('COPY', uid, destination_folder) 
        if result == 'OK': 
         dictionary[uid]['RESULT'] = 'COPIED' 
         result, delete = imap4.uid('STORE', uid, '+FLAGS', '(\Deleted)') 
         imap4.expunge() 
         if result == 'OK': 
          dictionary[uid]['RESULT'] = 'COPIED/DELETED' 
         elif result != 'OK': 
          dictionary[uid]['RESULT'] = 'ERROR' 
          continue 
        elif result != 'OK': 
         dictionary[uid]['RESULT'] = 'ERROR' 
         continue 
       else: 
        print "Do something with not matching emails" 
        # do something else instead of copy 
      dictionary = {scan_folder: dictionary} 
    except imaplib.IMAP4.error as e: 
     print("Error, {}".format(e)) 
    except Exception as e: 
     print("Error, {}".format(e)) 
    finally: 
     logout_process(imap4) 
     return dictionary 

if __name__ == "__main__": 
    username = '[email protected]' 
    password = 'examplePassword' 
    main_dictionary = main(username, password, 'INBOX', 'BOKNING', 'TMP_FOLDER') 
    pprint.pprint(main_dictionary) 
    exit(0) 

關於imaplib Python — imaplib IMAP example with Gmailimaplib documentation有用的信息。

相關問題