如何在Python中通过IMAP/POP3识别Outlook邮件ID并获取对应邮件?
嘿,我来帮你捋清楚这个问题!首先直接给你结论:你手里的那个Logic App里的「邮件唯一标识符」(也就是类似AQMkADAwATM3ZmYAZS0yNTYwLWNkZAAzLTAwAi0wMAoARgAAA-U4TGbG56lEtdoXy_23gW0HAKhWKDtf5AJErHyhh_b9NYQAAAIBDAAAAKhWKDtf5AJErHyhh_b9NYQAAAIFfgAAAA==的字符串),没办法直接通过IMAP协议获取对应邮件——原因很简单:
为什么你在EML里找不到这个ID?
这个长串ID是Exchange/Office 365专属的EWS(Exchange Web Services)邮件标识符,它是Exchange系统内部用来唯一标识邮件的ID,并不是邮件本身的标准头字段。而你下载的EML文件里的Message-ID是遵循RFC 5322协议的邮件头(格式通常是<xxxx@domain.com>),这俩完全不是一个东西,所以你在EML里找不到那个Logic App里的ID是正常的。
那怎么解决这个需求?
分两种情况给你方案:
方案1:换用Exchange专属API(推荐)
既然这个ID是Exchange系统的专属标识,那直接用EWS或者Microsoft Graph API来获取邮件是最直接的。比如用Microsoft Graph的话,只需要调用GET /me/messages/{message-id}(把{message-id}替换成你手里的那个长串ID),就能直接拿到对应的邮件,比IMAP更高效准确。
方案2:坚持用IMAP?做个ID映射
如果你一定要用IMAP,那得先在Logic App里做一步额外处理,建立两个ID的映射关系:
- 在Logic App处理邮件的环节,同时提取出邮件的标准
Message-ID头字段(这个字段能在EML里找到,格式是<xxx@xxx.com>); - 把Logic App的专属ID和这个标准
Message-ID一起存到某个存储服务里(比如Azure Table Storage、SQL数据库); - 之后需要用IMAP获取邮件时,先从存储里根据Logic App的ID查到对应的标准
Message-ID,再用IMAP的SEARCH命令搜索这个字段。
比如修改你现有的Python代码,让它能提取并使用标准Message-ID:
import imaplib import email # 登录IMAP服务器 mail = imaplib.IMAP4_SSL("outlook.office365.com", 993) mail.login(email_user, email_pass) mail.select('Inbox') # 搜索所有邮件 typ, data = mail.search(None, 'ALL') for num in data[0].split(): # 获取邮件原始内容 typ, data = mail.fetch(num, '(RFC822)') # 解析邮件头 msg = email.message_from_bytes(data[0][1]) # 提取标准Message-ID,没有的话用序号兜底 message_id = msg.get('Message-ID', f'unknown-{num}') # 清理文件名里的特殊字符(避免保存失败) clean_msg_id = message_id.replace('<', '').replace('>', '').replace('/', '_').replace('\\', '_') # 保存EML文件 with open(f'/my/path/{clean_msg_id}.eml', 'wb') as f: f.write(data[0][1]) mail.close() mail.logout()
之后你就可以用这个标准Message-ID在IMAP里搜索邮件了,比如:
# 假设你从存储里拿到了标准Message-ID,比如target_msg_id = "<abc123@outlook.com>" typ, data = mail.search(None, f'(HEADER Message-ID "{target_msg_id}")') # 然后用fetch获取搜索到的邮件
最后再划个重点
- Logic App的专属ID是Exchange内部用的,IMAP不识别,直接搜肯定找不到;
- 优先用EWS/Graph API,适配性最好;
- 非要用IMAP的话,必须做标准
Message-ID的映射。
内容的提问来源于stack exchange,提问作者Esben Eickhardt




