Python连接Gmail读取邮件报认证失败及端口配置问题
故障成因
- 你碰到的
[AUTHENTICATIONFAILED] Invalid credentials (Failure)报错和端口配置无关,核心原因是Gmail已全面禁止第三方客户端直接使用账号日常登录密码做IMAP/SMTP认证,即使输入的账号密码完全正确也会被拦截。 - 现有代码存在基础配置错误:读取邮件走IMAP协议,和发信用的SMTP协议是两套独立服务,你当前把SMTP服务地址
smtp.gmail.com传给了imaplib.IMAP4_SSL()用于建立收信连接,配置本身就不匹配;且你定义的SMTP_PORT变量在当前收信逻辑中完全没有被调用。
官方标准服务端口配置
- IMAP(收信/读邮件用):服务地址
imap.gmail.com,SSL加密端口993 - SMTP(发信用):服务地址
smtp.gmail.com,SSL加密端口465,STARTTLS加密端口587 - POP3(收信用,不推荐):服务地址
pop.gmail.com,SSL加密端口995
认证问题修复步骤
- 登录Gmail网页端,进入设置-「转发和POP/IMAP」页面,开启IMAP访问权限后保存设置。
- 进入对应Google账号的安全中心,开启账号两步验证,之后在安全设置页生成16位的应用专用密码,将代码中
FROM_PWD字段的值替换为这个应用专用密码,不要使用账号日常登录密码。
注意:如果是企业/教育版G Suite账号,个人无法生成应用专用密码时,需要联系组织管理员在后台开启对应账号的IMAP访问权限、配置应用访问白名单。
修正后可运行代码(含CSV附件提取逻辑)
import imaplib import email import os import traceback # 基础配置 ORG_EMAIL = "@gmail.com" FROM_EMAIL = "myemail" + ORG_EMAIL FROM_PWD = "你生成的16位应用专用密码" # 不要填日常登录密码 # IMAP收信配置 IMAP_SERVER = "imap.gmail.com" IMAP_PORT = 993 # SMTP发信配置(当前读邮件逻辑用不到,后续发信可直接调用) SMTP_SERVER = "smtp.gmail.com" SMTP_PORT_SSL = 465 SMTP_PORT_STARTTLS = 587 # 附件保存路径,可自行修改 ATTACH_SAVE_PATH = "./gmail_csv_attachments" os.makedirs(ATTACH_SAVE_PATH, exist_ok=True) def read_email_from_gmail(): try: # 建立IMAP SSL连接 mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT) mail.login(FROM_EMAIL, FROM_PWD) mail.select('inbox') data = mail.search(None, 'ALL') mail_ids = data[1] id_list = mail_ids[0].split() first_email_id = int(id_list[0]) latest_email_id = int(id_list[-1]) for i in range(latest_email_id, first_email_id, -1): data = mail.fetch(str(i), '(RFC822)') for response_part in data: arr = response_part[0] if isinstance(arr, tuple): msg = email.message_from_bytes(arr[1]) email_subject = msg['subject'] email_from = msg['from'] print('From : ' + email_from) print('Subject : ' + email_subject + '\n') # 提取CSV附件逻辑 for part in msg.walk(): if part.get_content_disposition() is None: continue file_name = part.get_filename() if file_name and file_name.lower().endswith('.csv'): file_path = os.path.join(ATTACH_SAVE_PATH, file_name) # 重名文件自动加序号避免覆盖 counter = 1 while os.path.exists(file_path): name, ext = os.path.splitext(file_name) file_path = os.path.join(ATTACH_SAVE_PATH, f"{name}_{counter}{ext}") counter += 1 with open(file_path, 'wb') as f: f.write(part.get_payload(decode=True)) print(f"已保存CSV附件: {file_path}") mail.close() mail.logout() except Exception as e: traceback.print_exc() print(str(e)) if __name__ == "__main__": read_email_from_gmail()
- 代码修正了原有的IMAP服务地址配置错误,用
message_from_bytes替代了原来容易出现编码异常的message_from_string,内置了CSV附件自动识别、去重保存的逻辑,运行后会自动在脚本同级目录创建文件夹存储提取到的CSV文件。
内容的提问来源于stack exchange,提问作者gwc
相关产品推荐
相关产品推荐

