从特定日期下载POP3头信息(Python)
我正在尝试用Python写一个POP3和IMAP的客户端,利用现有的库来下载邮件的标题(之后还会下载整个邮件内容),然后把这些信息保存到MongoDB数据库里。现在我遇到的问题是,这个客户端会下载邮件,而用户的常规邮件客户端也会下载邮件。所以我假设用户在用自己的邮件客户端下载邮件时,可能会选择把邮件留在服务器上,也可能会删除。为了避免每次都把整个邮箱里的邮件都抓取下来,我想只获取某个日期之后的邮件标题。
从我所了解的情况来看,POP3的列表调用会把服务器上所有的邮件都获取到,即使那些我可能已经下载过的邮件。而IMAP就没有这个问题。
那么,邮件客户端在处理POP3服务器时是如何应对这种情况的呢?
1 个回答
Outlook会登录到一个POP3服务器,然后发出STAT
、LIST
和UIDL
这几个命令。如果它判断用户没有新邮件,就会退出。我在监测客户端和我的DBMail POP3服务器之间的网络流量时观察到Outlook是这样做的。我见过Outlook用这种方法无法检测到新邮件。Thunderbird的行为也差不多,但我从未见过它无法检测到新邮件。
登录后,向服务器发出LIST
和UIDL
命令。LIST
会给你一个索引号(邮件在邮箱中的位置)和每封邮件的大小。UIDL
则会提供相同的索引号和每封邮件的计算哈希值。
对于每个用户,你可以存储LIST
和UIDL
提供的大小和哈希值。如果你看到相同的大小和哈希值,就可以认为是同一封邮件。当某封邮件不再出现在这个列表中时,就可以认为它被删除了,并从你的本地记忆中清除。
为了确保完全准确,记住邮件列表中大小/哈希对的相对位置,以便支持它们可能会重复的情况。(我猜Outlook无法检测新邮件的原因是,有时这些值确实会重复,至少在DBMail中是这样,但Outlook即使在邮件被删除后也会记住这些值,并永远认为它们不是新邮件。如果是我,我会尽量避免这种情况。)
附注:记住,邮件头是邮件的一部分。不要信任邮件头中的任何信息,原因是:日期、发件人,甚至服务器转交的信息都很容易被伪造,不能假设它们是唯一的。