使用Python和imaplib在GMail中移动电子邮件

Dan*_*Dan 25 python gmail imap imaplib

我希望能够使用Python将GMail中的电子邮件从收件箱移动到另一个文件夹.我使用imaplib,无法弄清楚如何做到这一点.

Man*_*dan 39

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)
Run Code Online (Sandbox Code Playgroud)

  • 实际上IMAP确实有一个移动命令,而gmail支持它.RFC 6851.使用gmail,您只需在代码示例底部附近将"COPY"更改为"MOVE",然后删除"STORE"并删除行. (4认同)
  • 当您向"[Gmail] /垃圾箱""复制"消息时,Gmail IMAP*会自动*为您执行`\ Deleted` /`EXPUNGE`. (3认同)
  • 有关移动多条消息的任何想法?你是否必须执行另一次搜索并使用email_ids [-1]获取最新消息? (2认同)
  • 无论出于何种原因,Python 2.7.14 imaplib 都不允许 MOVE 命令。以下是如何安全地修补它: imaplib.Commands.setdefault('MOVE', ('SELECTED',)) (2认同)

scr*_*esh 5

对于Gmail,基于其使用标签的api,您唯一要做的就是添加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)
Run Code Online (Sandbox Code Playgroud)

  • 我正在确认@mernst所说的。标签被添加 (+X-GM-LABELS),但 (-X-GM-LABELS) STORE 没有效果。原因是_隐式_选择的文件夹(在给定的示例中为“src_folder_name”)不会显示为标签。也就是说,`server.uid("FETCH", msg_uids, r'X-GM-LABELS')`永远不会显示`src_folder_name`。 (2认同)