如何不启用Google账号低安全性应用访问权限即可运行IMAP收信代码
不开启低安全性应用权限的两种可行方案
方案1:使用应用专用密码(无代码改动,适配最快)
- 适用前提:你的谷歌账号已开启两步验证
- 操作步骤:
- 进入谷歌账号管理页面的「安全性」板块
- 确认「两步验证」处于开启状态
- 进入两步验证设置页面,拉到最下方找到「应用专用密码」入口
- 应用类型选择「其他」,自定义名称(例如Python IMAP脚本),生成16位无空格的专用密码
- 运行原有代码时,输入密码的步骤直接填入生成的专用密码即可,不需要修改任何代码逻辑
方案2:使用OAuth2认证(官方推荐,适用所有场景,无需开启两步验证)
这是谷歌官方指定的第三方应用访问Gmail接口的标准认证方式,安全性最高,且不受账号两步验证设置限制。
前置准备
- 前往谷歌云控制台创建新项目,启用Gmail API,创建桌面应用类型的OAuth2客户端ID,将生成的凭据文件下载到本地,重命名为
credentials.json放在脚本同级目录 - 安装依赖库:
pip install google-auth google-auth-oauthlib google-auth-httplib2 imaplib2
适配后的代码示例
from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request import imaplib import os import email # 作用域可根据需求调整,只读邮件可以用https://www.googleapis.com/auth/gmail.readonly SCOPES = ['https://www.googleapis.com/auth/gmail.imap_admin'] username = input("Target Mail: ") creds = None # 加载已保存的授权凭据 if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) # 凭据无效时重新授权 if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # 保存凭据,后续运行无需重复授权 with open('token.json', 'w') as token: token.write(creds.to_json()) # OAuth2方式连接IMAP服务器 imap_conn = imaplib.IMAP4_SSL('imap.gmail.com') auth_string = f'user={username}\x01auth=Bearer {creds.token}\x01\x01' imap_conn.authenticate('XOAUTH2', lambda x: auth_string) # 后续逻辑和原有代码一致 imap_conn.select('INBOX') _, msg_ids = imap_conn.search(None, 'ALL') first_msg_id = msg_ids[0].split()[-1] _, email_data = imap_conn.fetch(first_msg_id, '(RFC822)') msg = email.message_from_bytes(email_data[0][1]) # 按原有格式输出邮件内容 print("\n<|From|> " + msg["From"] + " <|From|>") print("<|Title|> " + msg["Subject"] + " <|Title|>\n") print("\n<|Title|> MESSAGES <|Title|>\n") if msg.is_multipart(): for part in msg.walk(): if part.get_content_type() == "text/plain": print(part.get_payload(decode=True).decode()) else: print(msg.get_payload(decode=True).decode())
注意事项
- 首次运行脚本会自动弹出浏览器窗口,登录对应谷歌账号完成授权即可,后续运行会自动读取已保存的
token.json,无需重复授权 - 如果调整接口作用域,需要删除本地已有的
token.json重新授权
内容的提问来源于stack exchange,提问作者PythonCodexR
相关产品推荐
相关产品推荐

