python获取outlook邮件

更新: 使用explorer获取的token在不到半天就过期了,官方说明令牌的有效期是一小时。可能还是需要通过app配置得到一个持久化的token
image
请求授权的文档:
https://learn.microsoft.com/en-us/graph/auth-v2-user?tabs=http

委托和应用程序的区别:
https://learn.microsoft.com/en-us/graph/auth/auth-concepts


用两天时间折腾了下outlook邮件抓取的程序,微软也太恶心了,文档可读性也很差,跟机翻一样。不像其他邮箱直接拿到授权码就能连接imap,所以也踩了几个坑:

  1. 使用账号密码连接imap出现登录失败的错误;
  2. 尝试使用outlook桌面端,但需要切换到经典版outlook,不知道为什么切换后需要收费,变成了试用版,最后也尝试导出成eml;
  3. 尝试使用outlook网页版导出,网页版可以实现导出,但无法实现批量导出;
  4. 尝试使用Microsoft Graph sdk导出,官方文档弯弯绕绕,放弃继续研究;
  5. 尝试使用Microsoft Graph的api,成功抓到数据。直接在网站获取到token,而不是通过app程序那些参数(client、secrect)构造得到token,省得需要配置app。
    image

当然也尝试其他方案,比如搜索有没有导出邮件的浏览器插件、能不能网页api抓包,这两者方案都没找到,网页版outlook没有直接能拿到所有邮件数据的接口,只能走自动化。
虽然google有相同问题,但都是通过创建app、添加api授权去解决的,鲜少用sdk或api解决的。

踩坑记录:

https://support.microsoft.com/zh-hk/office/outlook-com-的-pop-imap-和-smtp-設定-d088b986-291d-42b8-9564-9c414e2aa040

  1. imap 配置参数:

image

尝试使用以下脚本连接会报错:error: b'LOGIN failed.'


import imaplib
import email
from email.header import decode_header

imap_server = 'imap-mail.outlook.com'
username = 'wsoutlook.com'
password = ' Hong12345'

mail = imaplib.IMAP4_SSL(imap_server)
mail.login(username, password)

搜到其他方案是将用户名@的后缀去掉,尝试后显示:
error: b'Server Unavailable. 15'

经查找发现,需要使用oauth登陆

image

官方文档:
https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth

  1. 创建app
  2. 开放mail的权限
  3. 在证书和密码中创建client_secret
import imaplib
import msal
import base64
import jwt  # For debugging

tenant_id = '44a21-45fc-47c0-aefa-1003edce6'
authority = f'https://login.microsoftonline.com/{tenant_id}'
client_id = 'bfb1a7-e6ce-4c84-b357-346d7250ce37'
client_secret = 'wCI8Q~Ug7lx.IKQvTP4Ki1ZPSeFIMcOd'

scope = ["https://outlook.office365.com/.default"]

def generate_auth_string(user, token):
    return f"user={user}\x01auth=Bearer {token}\x01\x01".encode("utf-8")

# Acquire token
app = msal.ConfidentialClientApplication(
    client_id, authority=f"https://login.microsoftonline.com/{tenant_id}", client_credential=client_secret
)
result = app.acquire_token_silent(scope, account=None)
# print(result)
if not result:
    result = app.acquire_token_for_client(scopes=scope)
print(result)
# Debug token
if "access_token" in result:
    decoded = jwt.decode(result["access_token"], options={"verify_signature": False})
    print("Token claims:", decoded)
else:
    print("Token acquisition failed:", result.get("error"))


# IMAP Authentication
try:
    account = 'wsj@outlook.com'
    imap = imaplib.IMAP4("outlook.office365.com",port=993,timeout=300000)
    # imap.starttls()
    auth_str = generate_auth_string("wsjda5s@outlook.com", result["access_token"])
    imap.authenticate("XOAUTH2",lambda x:auth_str)
    print("Authentication successful!")
except Exception as e:
    import traceback
    traceback.print_exc()
    print("IMAP error:", e)
	

运行日志,能够成功获取到设备名称、

Token claims: {'aud': 'https://outlook.office365.com', 'iss': 'https://sts.windows.net/44ac6821-45fc-47c0-aefa-10f1703edce6/', 'iat': 1740708856, 'nbf': 1740708856, 'exp': 1740712756, 'aio': 'k2RgYHgmsHJF1hv3K3ZlHA37215cAwA=', 'app_displayname': 'python-imap-test', 'appid': 'bfb1ac57-e6ce-4c84-7-347250ce37', 'appidacr': '1', 'idp': 'https://sts.windows.net/44ac6821-45fc-47c0-aefa-10f1703edce6/', 'idtyp': 'app', 'oid': '4ad7e987-5885-4737-84cf-fd7604704745', 'rh': '1.AcYAIWisRPxFwEeu-hDxcD7c5gIAAAAAAPEPzgAAAAAAAADGAADGAA.', 'sid': '0022d229-7989-24b8-037a-b15076fcff20', 'sub': '4ad7e987-5885-4737-84cf-fd7604704745', 'tid': '44ac6821-45fc-47c0-aefa-10f1703edce6', 'uti': 'X8umqv1YG06aLE9fAlBTAQ', 'ver': '1.0', 'wids': ['0997a1d0-0d1d-4acb-b408-d5ca73121e90'], 'xms_aud_guid': '00000002-0000-0ff1-ce00-000000000000', 'xms_idrel': '7 20', 'xms_rd': '0.42LjYBJiOsYoJMLBKSTAgAaAouxCAttEqn14sjLcFvyct2JKt_geAA'}

但是显示IMAP error: socket error: EOF,连接的时候连不上

折腾了好久还是没找到解决方法,不知道是不是api权限的问题,还是重定向url的问题。但明明权限都开放了,也可能是开放委托权限而不是应用权限。
后面另外通过microsoft graph sdk进行读取邮件,解决了邮件抓包的问题。
https://developer.microsoft.com/en-us/graph/graph-explorer

先在 Graph Explorer 进行了测试:
graph explorer 使用指南见:https://learn.microsoft.com/en-us/graph/graph-explorer/graph-explorer-overview
image

一些可能有用的其他参考:
https://gitcode.com/gh_mirrors/ms/msgraph-sdk-python/blob/main/docs/authentication_samples.md

https://stackoverflow.com/questions/78977131/microsoft-graph-api-read-email-from-not-signed-in-user

https://github.com/microsoftgraph/microsoft-graph-docs-contrib/blob/main/includes/snippets/python/v1/message-get-reply-python-snippets.md

作者:Gim

出处:https://www.cnblogs.com/Gimm/p/18742667

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   踩坑大王  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
more_horiz
keyboard_arrow_up light_mode palette
选择主题
点击右上角即可分享
微信分享提示