使用SMTP无法向Gmail账户发送邮件问题求助
邮件机器人无法给Gmail账户发送邮件的解决方案
核心问题分析
你的代码能给abv.bg域名账户发邮件但Gmail不行,主要是两个关键问题:
- Gmail对发件人身份验证更严格,你用显示名称
name作为sendmail的发件人参数,不符合SMTP协议要求,导致发送被拦截。 - Gmail的密码认证机制限制,普通密码可能无法通过SMTP验证,尤其是开启两步验证的账户。
具体修复步骤
1. 修正SMTP发件人参数
smtplib.SMTP.sendmail()的第一个参数必须是实际的发件邮箱地址,而不是显示名称。同时规范邮件头的From字段:
# 原代码 EMAIL['From'] = name server.sendmail(name, sender, EMAIL.as_string()) # 修改后 EMAIL['From'] = f"{name} <{username}>" # 规范发件人格式:显示名称+实际邮箱 server.sendmail(username, sender, EMAIL.as_string()) # 用实际邮箱作为发件人参数
2. 配置Gmail的SMTP认证权限
- 如果你的Gmail账户开启了两步验证:必须创建应用专用密码,替换代码里的
password。创建路径:Google账号设置 > 安全 > 应用专用密码 > 生成对应密码。 - 如果未开启两步验证:需要在Google账号设置中开启"不太安全的应用访问"(注意:此方式Google已逐步淘汰,优先推荐应用专用密码)。
3. 添加异常捕获排查问题
原代码没有错误处理,发送失败也看不到日志,建议加上异常捕获,方便定位问题:
context = ssl.create_default_context() try: with smtplib.SMTP('smtp.gmail.com', 587) as server: server.starttls(context=context) server.login(username, password) server.sendmail(username, sender, EMAIL.as_string()) print(f"邮件已成功发送到 {sender}") except Exception as e: print(f"发送邮件失败: {str(e)}")
4. 优化SMTP连接复用(可选)
原代码每次发送都新建SMTP连接,效率低,可以把连接放在循环外:
# 把SMTP连接放在循环外,避免重复创建 context = ssl.create_default_context() with smtplib.SMTP('smtp.gmail.com', 587) as server: server.starttls(context=context) server.login(username, password) while True: to_answer = [] for msg in inbox.search(unseen=True): msg_body = msg.text_body.strip().lower() if msg_body == wanted_msg: to_answer.append(msg.from_) for sender in to_answer: # 构建邮件逻辑...
修复后的完整代码示例
import smtplib, ssl from email.mime.multipart import MIMEMultipart from email.mime.image import MIMEImage from redbox import EmailBox username = 'begichal66@gmail.com' password = '你的应用专用密码或授权密码' # 替换为正确的密码 server = 'imap.gmail.com' port = 993 box = EmailBox( username=username, password=password, host=server, port=port ) inbox = box['INBOX'] name = "Kompot" wanted_msg = "купон" # 复用SMTP连接 context = ssl.create_default_context() with smtplib.SMTP('smtp.gmail.com', 587) as smtp_server: smtp_server.starttls(context=context) smtp_server.login(username, password) while True: to_answer = [] for msg in inbox.search(unseen=True): msg_body = msg.text_body.strip().lower() if msg_body == wanted_msg: to_answer.append(msg.from_) for sender in to_answer: EMAIL = MIMEMultipart() EMAIL['From'] = f"{name} <{username}>" EMAIL['To'] = sender EMAIL['Subject'] = "Твоят купон" with open("image.png", 'rb') as f: img_data = f.read() EMAIL.attach(MIMEImage(img_data, name="image.png")) try: smtp_server.sendmail(username, sender, EMAIL.as_string()) print(f"邮件已发送至 {sender}") except Exception as e: print(f"发送至 {sender} 失败: {str(e)}")
内容的提问来源于stack exchange,提问作者maybrother
相关产品推荐
相关产品推荐

