Python imaplib 无法通过发件人地址搜索

Python imaplib can't search by from address

我正在尝试查找与特定发件人地址匹配的邮件。我看过 ,但它对我不起作用。

相关代码如下:

import imaplib

conn = imaplib.IMAP4_SSL(IMAPserver)
conn.login(IMAPuserName, IMAPpassword)
retVal, data = conn.select("INBOX")
    if retVal != "OK":
        <PRINT SOME ERROR MESSAGE>
        sys.exit(1)

这一切都有效。以下是一些不起作用的搜索命令变体:

retVal, data = conn.search(None, 'UNSEEN HEADER FROM "foo@example.com"')

retVal, data = conn.search(None, 'UNSEEN FROM "foo@example.com"')

retVal, data = conn.search(None, 'FROM "foo@example.com"')

retVal, data = conn.search(None, 'HEADER FROM "foo@example.com"')

所有这些都会导致如下错误:

    imaplib.error: SEARCH command error: BAD ['Error in IMAP command SEARCH: 
Unexpected string as search key: FROM "foo@example.com"']

我已经参考了 IMAP v4 RFC 的相关部分,但我无法弄清楚我到底做错了什么。任何帮助将不胜感激。

如文档中的示例所示,IMAP.search() 期望搜索参数是单独的位置参数,而不是单个字符串:

conn.search(None, 'UNSEEN', 'HEADER', 'FROM', 'foo@example.com')
conn.search(None, 'UNSEEN', 'FROM', 'foo@example.com')
conn.search(None, 'FROM', 'foo@example.com')
conn.search(None, 'HEADER', 'FROM', 'foo@example.com')

如果您传入单个参数,imaplib 会将其作为单引号参数传递给 SEARCH 命令。

但是,您不能依赖它,因为引用只发生在 Python 2.x imaplib 上。 Python 3.x imaplib 不会为您引用 that particular bug is still open.

一种解决方法——如文档所述——是"pre-quote"将参数作为列表:

conn.search(None, '(UNSEEN HEADER FROM foo@example.com)')
conn.search(None, '(UNSEEN FROM foo@example.com)')
conn.search(None, '(FROM foo@example.com)')
conn.search(None, '(HEADER FROM foo@example.com)')

但正如@Max 所指出的,某些 IMAP 服务器不支持此功能。

我设法从管理 IMAP 服务器的人那里获得了信息。这是服务器问题,与代码无关。

有问题的 IMAP 服务器是 Dovecot 的自定义版本。它实际上 indexes 所有邮箱使搜索等更快。在这种特殊情况下,我邮箱的索引已损坏。重新编制索引解决了问题。