【问题标题】:python imaplib returns only half the messages from exchange 2013python imaplib 仅返回来自 Exchange 2013 的一半消息
【发布时间】:2015-10-30 22:58:20
【问题描述】:

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

问题:我一次只能从收件箱收到一半的消息。当我再次运行时,它会收到另一半的消息,依此类推,直到没有消息为止。

设置:我正在尝试在 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

ERROR: '指定的消息集无效。'

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

【问题讨论】:

  • mailcount = sum(1 for num in mailcount.split()) 很傻。 len(mailcount.split()) 更短,而且 select() 的返回值是邮箱中的邮件数量,所以如果使用序列号,则根本不需要搜索。

标签: python exchange-server imap


【解决方案1】:

这里有两个问题共同表明了这种行为:

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

因此,代码下载消息 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

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

【讨论】:

  • FWIW 此代码在 python 3.5 上比 2.7 运行得更好,因为 3.5 对搜索响应的大小限制比早期版本更合理。
猜你喜欢
  • 1970-01-01
  • 2011-09-01
  • 2022-12-12
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
  • 1970-01-01
  • 2015-03-22
  • 2014-11-15
相关资源
最近更新 更多