python imaplib returns 只有 exchange 2013 消息的一半

python imaplib returns only half the messages from exchange 2013

我试图找出这里的问题所在。我不明白。

问题:我在一台 运行 上的收件箱中只收到了一半的邮件。当我再次 运行 时,它会收到另一半的消息,依此类推,直到剩下 none。

设置:我正在尝试在 Debian 7 上使用 python 2.7.3(我知道它很旧)从 Exchange Server 2013 中使用 imaplib.fetch 获取消息。

def fetch_mails():
    messages = []
    mailbox = IMAP4_SSL(host = mail_host, port = mail_port)
    mailbox.login(mail_user, mail_password)
    mailbox.select()
    mailcount = mailbox.search(None, 'ALL')[1][0]
    mailcount = sum(1 for num in mailcount.split())
    for i in xrange(1, mailcount+1):
        mailbox.select()
        status, data = mailbox.fetch(str(i), '(RFC822)')
        current = email.message_from_string(data[0][1])
        messages.append(current)
        mailbox.store(i, '+FLAGS', r'\Deleted')
    return messages

错误:'The specified message set is invalid.'

有人知道为什么会这样吗?最后我可以处理所有邮件,但不能处理一个 运行。 在此先感谢您的帮助!

你这里有两个问题,它们共同导致了这种行为:

  1. 您正在使用消息序号。消息从 1-n 连续编号,其中 N 是邮箱中消息的数量。每当删除消息时,所有序列号都会发生变化。
  2. 您正在重新SELECT-ing 每封邮件之间的邮箱。这使服务器有机会删除已删除的消息,从而将所有序列号向下移动。

因此,代码下载消息 1,将其标记为已删除,然后重新选择邮箱,允许服务器删除它,将消息 2-N 向下移动到消息 1 - (N-1)。然后您下载第二条消息(之前是第三条消息),然后重复。因此,您只能下载每隔一条消息。

有两种修复方法:

  1. 从循环中删除 mailbox.select()。
  2. 改用 UID,即使在删除消息时也是稳定的。

这是您的代码,其中包含两项更改:

def fetch_mails():
    messages = []
    mailbox = IMAP4_SSL(host = mail_host, port = mail_port)
    mailbox.login(mail_user, mail_password)
    mailbox.select()
    uids = mailbox.uid('SEARCH', 'ALL')[1][0].split()
    for uid in uids:
        status, data = mailbox.uid('FETCH', uid, '(RFC822)')
        current = email.message_from_string(data[0][1])
        messages.append(current)
        mailbox.uid('STORE', uid, '+FLAGS', r'\Deleted')
    return messages

我没有测试过代码,所以你可能需要做一些小的改动。