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

Python中Outlook IMAP报“用户已认证但未连接”错误的解决求助

解决Outlook IMAP报错:User is authenticated but not connected

可能的原因及解决方案

1. 启用两步验证后需使用应用密码

如果你的Outlook账号开启了两步验证,直接用账号密码登录IMAP会失败,必须前往微软账户中心创建应用专用密码,替换代码里的password字段。

2. 避免频繁重复登录(核心问题)

原代码每次循环都logout再重新login,Office365的IMAP服务器会限制短时间内的重复登录请求,导致会话被标记为异常。解决方案是复用连接,不要每次循环都断开重连,同时定期发送NOOP命令维持会话:

修改后的代码示例:

import time
from email.policy import default
from itertools import chain
import email
import imaplib
import base64
import sys

imap_ssl_host = 'outlook.office365.com'
imap_ssl_port = 993
username = 'EMAIL@outlook.fr'
# 如果开启两步验证,这里替换为应用密码
password = '你的应用密码或原密码'

criteria ={
    'FROM':    'donotreply@COMPANY.com',
    # 尽量缩小搜索范围,避免*匹配所有
    'SUBJECT': "",
}

uid_max = 0

def search_string(uid_max, criteria):
    c = list(map(lambda t: (t[0], '"'+str(t[1])+'"'), criteria.items())) + [('UID', '%d:*' % (uid_max+1))]
    return '(%s)' % ' '.join(chain(*c))

def get_first_text_block(msg):
    type = msg.get_content_maintype()
    if type == 'multipart':
        for part in msg.get_payload():
            if part.get_content_maintype() == 'text':
                return part.get_payload()
    elif type == 'text':
        return msg.get_payload()

# 初始化连接,只登录一次
server = imaplib.IMAP4_SSL(imap_ssl_host, imap_ssl_port)
server.login(username, password)
server.select('INBOX')

# 初始搜索获取uid_max
result, data = server.uid('search', None, search_string(uid_max, criteria))
uids = [int(s) for s in data[0].split()]
if uids:
    uid_max = max(uids)

try:
    while True:
        # 发送NOOP维持连接,避免服务器断开
        server.noop()
        
        result, data = server.uid('search', None, search_string(uid_max, criteria))
        uids = [int(s) for s in data[0].split()]
        
        for uid in uids:
            if uid > uid_max:
                result, data = server.uid('fetch', str(uid), 'BODY.PEEK[1]')
                msg = email.message_from_bytes(data[0][1], policy=default)
                uid_max = uid
                
                text = get_first_text_block(msg)
                print ('New message :::::::::::::::::::::')
                
                try:
                    ijij = base64.b64decode(text.encode("utf8")).decode("utf8")
                except:
                    # 处理非base64编码的邮件内容
                    ijij = text
                
                substring = "unique est"
                if substring in ijij:
                    otp = ijij.split("unique est")[1].split()[0].replace(".", "")
                    print(otp)
                else:
                    otp = ijij.split("Your OTP is")[1].split()[0].replace(".", "")
                    print(ijij)
                    print(otp)
                
                # 写入文件,用with语句更安全
                with open(r'C:\Users\Administrator\Desktop\otp\otp4.txt','w') as myText:
                    myText.write(otp)
        
        time.sleep(10)  # 适当延长间隔,避免过于频繁请求
except Exception as e:
    print(f"连接异常: {e}")
    # 异常时重新连接
    server = imaplib.IMAP4_SSL(imap_ssl_host, imap_ssl_port)
    server.login(username, password)
    server.select('INBOX')
finally:
    server.logout()

3. 检查IMAP权限及账号状态

  • 登录Outlook网页版,进入设置->邮件->同步电子邮件,确认IMAP已启用,且允许从所有设备连接。
  • 检查账号是否有异常登录记录,是否被微软限制了IMAP访问。

4. 缩小搜索范围

原代码中SUBJECT: "*"和BODY: "*"会匹配所有邮件,导致服务器返回大量数据,容易触发限流。建议根据实际需求缩小搜索条件,比如指定主题关键词,避免使用通配符。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:10:50