python smtp发送邮件 Python利用SMTP发送邮件的常见问题与解决
目录
- 引言
- 1. 难题背景
- 2. 常见错误及解决方案
- 3. 优化后的邮件发送代码
- 4. SMTP调试技巧
- 5. 拓展资料与最佳操作
- 最佳操作
引言
在自动化办公和体系开发中,邮件发送功能是常见的需求。无论是发送通知、报告,还是传输文件,Python的smtplib和email库提供了便捷的实现方式。然而,在实际开发中,开发者常会遇到各种SMTP错误,如(-1, b&039;x00x00x00&039;)、AttributeError(&039;characters_written&039;)等,这些难题往往让人束手无策。
这篇文章小编将从实际案例出发,分析常见的SMTP错误,并提供完整的解决方案,帮助开发者快速定位和难题解决。同时,我们还会优化代码,使其更健壮、更易于维护。
1. 难题背景
在Python中,使用smtplib
发送邮件时,通常会遇到两类难题:
- 连接与认证难题(如授权码错误、SMTP服务器拒绝连接)
- 数据编码与协议难题(如SSL/TLS握手失败、附件编码错误)
下面内容一个典型的邮件发送代码,它可能会触发上述错误:
import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.mime.application import MIMEApplicationimport osimport logginglogger = logging.getLogger(__name__)def send_email_with_attachment(filepath, receiver_email): sender_email = “your_email@qq.com” password = “your_authorization_code” QQ邮箱授权码 smtp_server = “smtp.qq.com” smtp_port = 465 QQ邮箱SSL端口 msg = MIMEMultipart() msg[‘From’] = sender_email msg[‘To’] = receiver_email msg[‘Subject’] = “文件处理结局通知” 邮件 msg.attach(MIMEText(“请查收附件”, ‘plain’)) 添加附件 try: with open(filepath, “rb”) as f: part = MIMEApplication(f.read(), Name=os.path.basename(filepath)) part[‘Content-Disposition’] = f’attachment; filename=”os.path.basename(filepath)}”‘ msg.attach(part) except FileNotFoundError: logger.error(“附件文件不存在”) return False 发送邮件 try: with smtplib.SMTP_SSL(smtp_server, smtp_port) as server: server.login(sender_email, password) server.sendmail(sender_email, receiver_email, msg.as_string()) return True except Exception as e: logger.error(f”发送邮件失败: e}”, exc_info=True) return False
运行此代码时,可能会遇到下面内容错误:
2. 常见错误及解决方案
错误1:SMTPResponseException: (-1, b&039;x00x00x00&039;)
错误缘故
- 授权码错误或已过期。
- SMTP服务器(如QQ邮箱)检测到异常登录,拒绝连接。
- 网络或防火墙拦截了SMTP请求。
解决方案
1.检查授权码
登录QQ邮箱 → 设置 → 账户 → 生成新的授权码,并替换代码中的password。
2.更换SMTP端口(推荐使用587+TLS)
QQ邮箱支持465(SSL)和587(TLS),后者更稳定:
smtp_port = 587 改用TLS端口with smtplib.SMTP(smtp_server, smtp_port) as server: server.starttls() 启用TLS加密 server.login(sender_email, password)
3.检查网络环境
关闭防火墙或切换网络(如使用手机热点测试)。
错误2:AttributeError(&039;characters_written&039;)
错误缘故
- Python 3.10+ 与 SMTP_SSL 的兼容性难题。
- SSL/TLS握手失败,可能是由于OpenSSL版本不匹配。
解决方案
1.改用starttls()(推荐)
避免使用SMTP_SSL,改用SMTP + starttls():
with smtplib.SMTP(smtp_server, 587) as server: server.starttls() 显式启用TLS server.login(sender_email, password)
2.降级Python或升级依赖库
如果仍报错,尝试降级到Python 3.9,或更新pyopenssl:
pip install –upgrade pyopenssl
3. 优化后的邮件发送代码
结合上述解决方案,优化后的代码如下:
import smtplibfrom email.mime.text import MIMETextfrom email.mime.multipart import MIMEMultipartfrom email.mime.application import MIMEApplicationimport osimport loggingimport base64logger = logging.getLogger(__name__)def send_email_with_attachment(filepath, receiver_email): “””发送带附件的邮件(支持QQ邮箱)””” sender_email = “your_email@qq.com” password = “your_authorization_code” 替换为最新授权码 smtp_server = “smtp.qq.com” smtp_port = 587 使用TLS端口 检查附件是否存在 if not os.path.exists(filepath): logger.error(f”附件文件不存在: filepath}”) return False 创建邮件内容 msg = MIMEMultipart() msg[‘From’] = sender_email msg[‘To’] = receiver_email msg[‘Subject’] = “文件处理结局通知” msg.attach(MIMEText(“请查收附件”, ‘plain’)) 添加附件 try: with open(filepath, “rb”) as f: part = MIMEApplication(f.read(), Name=os.path.basename(filepath)) part[‘Content-Disposition’] = f’attachment; filename=”os.path.basename(filepath)}”‘ msg.attach(part) except Exception as e: logger.error(f”附件处理失败: e}”) return False 发送邮件(使用TLS) try: with smtplib.SMTP(smtp_server, smtp_port) as server: server.starttls() 启用TLS加密 server.login(sender_email, password) server.sendmail(sender_email, receiver_email, msg.as_string()) logger.info(“邮件发送成功”) return True except smtplib.SMTPException as e: logger.error(f”SMTP错误: e}”) except Exception as e: logger.error(f”未知错误: e}”, exc_info=True) return False
优化点
1.更健壮的异常处理
区分SMTPException和其他异常,便于排查难题。
2.附件预检查
发送前验证附件是否存在。
3.日志记录
使用logging记录详细错误信息。
4. SMTP调试技巧
手动测试SMTP连接
使用openssl命令行工具测试SMTP服务是否可用:
openssl s_client -connect smtp.qq.com:587 -starttls smtp -crlf
输入下面内容命令(替换为你的邮箱和授权码):
EHLO test
AUTH LOGIN
<base64编码的邮箱> 示例:echo -n "your_email@qq.com" | base64
<base64编码的授权码>
QUIT
如果返回235 Authentication successful,说明SMTP配置正确。
检查防火墙
在Windows上,运行下面内容命令放行SMTP端口:
netsh advfirewall firewall add rule name=”SMTP” dir=in action=allow protocol=TCP localport=587
5. 拓展资料与最佳操作
常见难题拓展资料
错误 | 缘故 | 解决方案 |
---|---|---|
(-1, b&039;x00x00x00&039;) |
授权码错误/SMTP拒绝 | 更新授权码,改用starttls() |
AttributeError(&039;characters_written&039;) |
Python 3.10+兼容性难题 | 降级Python或改用SMTP +starttls() |
SSL: WRONG_VERSION_NUMBER |
SSL/TLS配置错误 | 使用starttls() + 端口587 |
最佳操作
- 使用TLS(端口587)代替SSL(端口465),兼容性更好。
- 定期更新授权码,避免因过期导致发送失败。
- 添加日志记录,便于排查难题。
- 手动测试SMTP连接,确保服务器可用。
通过这篇文章小编将的分析和优化,你应该能够解决大多数Python邮件发送难题。如果你的场景涉及更复杂的需求(如批量发送、HTML邮件),可以进一步扩展代码逻辑。
到此这篇关于Python利用SMTP发送邮件的常见难题与解决方案详解的文章就介绍到这了,更多相关Python SMTP发送邮件内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
无论兄弟们可能感兴趣的文章:
- Python使用smtplib库发送电子邮件
- Python 发送SMTP邮件的简单教程
- Python基于SMTP发送邮件的技巧
- 基于python SMTP实现自动发送邮件教程解析
- Python SMTP发送邮件遇到的一些难题及解决办法
- 详细讲解用Python发送SMTP邮件的教程