如何用Python实现毫秒级定时发送Gmail并解决认证失败问题
Gmail SMTP认证失败的解决办法
问题背景
需要毫秒级精度定时发送Gmail用于院校申请(接收时间影响候选人排序),Gmail自带定时发送存在延迟,用Python脚本实现时遇到smtplib.SMTPSenderRefused认证错误——原因是Google已禁用非授权应用访问,且关闭了“不太安全的应用”设置。
解决方法
方法一:使用应用专用密码(需开启两步验证)
这是个人账号最简便的解决方案:
- 先为你的Google账号开启两步验证(2FA)
- 登录Google账号安全设置,找到「应用专用密码」选项,选择「邮件」应用与对应设备,生成一个16位的专用密码
- 修改代码,在初始化SMTP服务器后添加登录步骤,用该专用密码替代原账号密码:
import smtplib gmail_user = "your-email@gmail.com" gmail_app_password = "your-16-digit-app-password" # 替换为生成的应用专用密码 def send_mail(): try: server_ssl = smtplib.SMTP_SSL('smtp.gmail.com', 465) server_ssl.ehlo() # 添加认证登录步骤 server_ssl.login(gmail_user, gmail_app_password) print('Server initialized and authenticated') sent_from = gmail_user to = ['recipient@example.com'] subject = 'my subject' body = 'my body' email_text = """\ From: %s To: %s Subject: %s %s """ % (sent_from, ", ".join(to), subject, body) server_ssl.sendmail(sent_from, to, email_text) server_ssl.close() print('Email sent successfully') except Exception as inst: print('Something went wrong') print(type(inst)) print(inst.args) print(inst)
方法二:使用OAuth2认证(开发者规范方案)
如果不想使用应用专用密码,或需要更安全的认证方式,可采用OAuth2:
- 前往Google Cloud Console创建新项目,启用Gmail API
- 创建OAuth客户端ID,选择「桌面应用」类型,下载
credentials.json到项目目录 - 安装依赖库:
pip install google-api-python-client oauth2client - 使用以下代码发送邮件:
import base64 from email.mime.text import MIMEText from googleapiclient.discovery import build from googleapiclient.errors import HttpError from oauth2client.file import Storage from oauth2client.client import OAuth2WebServerFlow from oauth2client.tools import run_flow # OAuth2配置(从credentials.json提取对应字段) CLIENT_ID = 'your-client-id' CLIENT_SECRET = 'your-client-secret' SCOPES = ['https://www.googleapis.com/auth/gmail.send'] REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob' def get_credentials(): storage = Storage('gmail-credentials.json') credentials = storage.get() if not credentials or credentials.invalid: flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, SCOPES, REDIRECT_URI) credentials = run_flow(flow, storage) return credentials def send_mail(): try: credentials = get_credentials() service = build('gmail', 'v1', credentials=credentials) sent_from = 'your-email@gmail.com' to = 'recipient@example.com' subject = 'my subject' body = 'my body' message = MIMEText(body) message['to'] = to message['from'] = sent_from message['subject'] = subject raw = base64.urlsafe_b64encode(message.as_bytes()).decode() message_body = {'raw': raw} service.users().messages().send(userId='me', body=message_body).execute() print('Email sent successfully') except HttpError as error: print(f'An error occurred: {error}')
首次运行时会弹出浏览器要求授权应用访问Gmail,授权后生成gmail-credentials.json,后续运行无需重复授权。
内容的提问来源于stack exchange,提问作者crag.hack
相关产品推荐
相关产品推荐

