You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python无Outlook环境下不通过Graph API凭账号密码读Outlook邮件

无本地Outlook、不调用Graph API时通过账号密码读取Outlook邮件的Python实现

本方案完全不依赖本地Outlook客户端、不需要调用Graph API,仅通过标准邮件协议实现,可直接运行在无桌面环境的Linux/Windows服务器上,仅需邮箱账号及对应鉴权密码即可使用。

核心原理

直接通过IMAP(推荐)/POP3标准协议连接Outlook/Exchange邮箱服务,使用Python标准库内置的协议客户端完成鉴权、邮件拉取、内容解析,无额外重型依赖。

前置确认项:

  1. 个人Outlook/微软365邮箱默认开启IMAP服务,企业托管Exchange/365租户需提前确认账号已开放IMAP/POP3密码鉴权权限,部分企业安全策略默认会关闭该权限,需联系管理员开通。
  2. 如果账号开启了双重验证(MFA),不可直接使用账号登录密码,需在微软账号安全中心生成应用专用密码用于协议鉴权。

服务连接参数

邮箱类型IMAP服务器地址IMAP SSL端口POP3服务器地址POP3 SSL端口
个人Outlook/微软365imap-mail.outlook.com993pop-mail.outlook.com995
企业本地部署Exchange请向管理员索取对应参数993(默认)请向管理员索取对应参数995(默认)

可直接运行的实现代码

以功能更完善的IMAP协议为例,实现登录、拉取未读邮件、解析主题/发件人/正文的逻辑,所有依赖均为Python标准库,无需额外安装第三方包:

import imaplib
import email
from email.header import decode_header

# 替换为自己的账号配置
EMAIL_ACCOUNT = "your_email@outlook.com"
EMAIL_PASSWORD = "your_password_or_app_password"
IMAP_SERVER = "imap-mail.outlook.com"
IMAP_PORT = 993

def decode_mime_str(s):
    """处理邮件MIME编码内容,解决乱码问题"""
    decoded_parts = decode_header(s)
    result = ""
    for part, charset in decoded_parts:
        if isinstance(part, bytes):
            result += part.decode(charset if charset else "utf-8", errors="replace")
        else:
            result += part
    return result

# 建立SSL加密连接
imap_conn = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT)
# 账号鉴权
imap_conn.login(EMAIL_ACCOUNT, EMAIL_PASSWORD)

# 选择收件箱,readonly=True表示只读模式,不会自动把未读邮件标记为已读
imap_conn.select("INBOX", readonly=True)

# 邮件筛选规则:ALL=所有邮件 UNSEEN=未读邮件 FROM "xxx@xx.com"=指定发件人 可按需组合
status, search_data = imap_conn.search(None, "UNSEEN")
mail_id_list = search_data[0].split()

# 示例:遍历最新10封符合条件的邮件
for mail_id in mail_id_list[-10:]:
    status, fetch_data = imap_conn.fetch(mail_id, "(RFC822)")
    for response_item in fetch_data:
        if isinstance(response_item, tuple):
            mail_msg = email.message_from_bytes(response_item[1])
            # 解析基础头信息
            subject = decode_mime_str(mail_msg["Subject"])
            sender = decode_mime_str(mail_msg.get("From"))
            print(f"=== 新邮件 ===")
            print(f"发件人: {sender}")
            print(f"主题: {subject}")

            # 解析纯文本正文
            if mail_msg.is_multipart():
                for part in mail_msg.walk():
                    part_disp = str(part.get("Content-Disposition"))
                    # 跳过附件部分
                    if "attachment" in part_disp:
                        continue
                    if part.get_content_type() == "text/plain":
                        charset = part.get_content_charset()
                        body = part.get_payload(decode=True).decode(charset if charset else "utf-8", errors="replace")
                        print(f"正文预览: {body[:300]}...\n")
            else:
                if mail_msg.get_content_type() == "text/plain":
                    charset = mail_msg.get_content_charset()
                    body = mail_msg.get_payload(decode=True).decode(charset if charset else "utf-8", errors="replace")
                    print(f"正文预览: {body[:300]}...\n")

# 释放连接
imap_conn.close()
imap_conn.logout()

常见问题处理

  • 鉴权报错:优先检查密码是否正确,开启MFA的账号必须使用应用专用密码;其次确认账号未被管理员禁用IMAP基础鉴权权限,微软365租户开启安全默认值时会默认禁用该能力,需单独开通。
  • 连接超时:检查服务器出站防火墙规则,确认已放通对应IMAP/POP3服务器地址和端口,可通过telnet imap-mail.outlook.com 993命令测试网络连通性。
  • 需要下载附件:遍历邮件multipart节点时,识别Content-Disposition为attachment的部分,解码文件名后将二进制payload直接写入本地文件即可。
  • 需要操作其他文件夹:可通过imap_conn.list()获取邮箱下所有文件夹名称,传入select()方法即可切换到已发送、草稿箱、自定义文件夹等目录操作。

内容的提问来源于stack exchange,提问作者Puneeth C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:54:26