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
相关产品推荐
相关产品推荐

