设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间09 现在时间09 缓存数据 我们所有的努力所有的奋斗,都是为了拥有一个美好的未来。和遇见更好的自己。请把努力当成一种习惯,而不是三分钟热度。每一个你羡慕的收获,都是努力用心拼来的。早安!

我们所有的努力所有的奋斗,都是为了拥有一个美好的未来。和遇见更好的自己。请把努力当成一种习惯,而不是三分钟热度。每一个你羡慕的收获,都是努力用心拼来的。早安!

查看: 187|回复: 1

Python利用SMTP发送邮件的常见问题与解决方案详解

[复制链接]

  离线 

TA的专栏

  • 打卡等级:即来则安
  • 打卡总天数:24
  • 打卡月天数:1
  • 打卡总奖励:329
  • 最近打卡:2025-06-03 23:51:43
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
256
主题
206
精华
0
金钱
1040
积分
512
注册时间
2023-1-26
最后登录
2025-6-3

发表于 2025-5-31 05:50:03 | 显示全部楼层 |阅读模式
引言

在自动化办公和系统开发中,邮件发送功能是常见的需求。无论是发送通知、报告,还是传输文件,Python的smtplib和email库提供了便捷的实现方式。然而,在实际开发中,开发者常会遇到各种SMTP错误,如(-1, b'\x00\x00\x00')、AttributeError('characters_written')等,这些问题往往让人束手无策。
本文将从实际案例出发,分析常见的SMTP错误,并提供完整的解决方案,帮助开发者快速定位和解决问题。同时,我们还会优化代码,使其更健壮、更易于维护。

1. 问题背景

在Python中,使用
  1. smtplib
复制代码
发送邮件时,通常会遇到两类问题:

  • 连接与认证问题(如授权码错误、SMTP服务器拒绝连接)
  • 数据编码与协议问题(如SSL/TLS握手失败、附件编码错误)
以下是一个典型的邮件发送代码,它可能会触发上述错误:
  1. import smtplib
  2. from email.mime.text import MIMEText
  3. from email.mime.multipart import MIMEMultipart
  4. from email.mime.application import MIMEApplication
  5. import os
  6. import logging

  7. logger = logging.getLogger(__name__)

  8. def send_email_with_attachment(filepath, receiver_email):
  9.     sender_email = "your_email@qq.com"
  10.     password = "your_authorization_code"  # QQ邮箱授权码
  11.     smtp_server = "smtp.qq.com"
  12.     smtp_port = 465  # QQ邮箱SSL端口

  13.     msg = MIMEMultipart()
  14.     msg['From'] = sender_email
  15.     msg['To'] = receiver_email
  16.     msg['Subject'] = "文件处理结果通知"

  17.     # 邮件正文
  18.     msg.attach(MIMEText("请查收附件", 'plain'))

  19.     # 添加附件
  20.     try:
  21.         with open(filepath, "rb") as f:
  22.             part = MIMEApplication(f.read(), Name=os.path.basename(filepath))
  23.             part['Content-Disposition'] = f'attachment; filename="{os.path.basename(filepath)}"'
  24.             msg.attach(part)
  25.     except FileNotFoundError:
  26.         logger.error("附件文件不存在")
  27.         return False

  28.     # 发送邮件
  29.     try:
  30.         with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
  31.             server.login(sender_email, password)
  32.             server.sendmail(sender_email, receiver_email, msg.as_string())
  33.         return True
  34.     except Exception as e:
  35.         logger.error(f"发送邮件失败: {e}", exc_info=True)
  36.         return False
复制代码
运行此代码时,可能会遇到以下错误:

2. 常见错误及解决方案

错误1:SMTPResponseException: (-1, b'\x00\x00\x00')
错误原因

  • 授权码错误或已过期。
  • SMTP服务器(如QQ邮箱)检测到异常登录,拒绝连接。
  • 网络或防火墙拦截了SMTP请求。
解决方案
1.检查授权码
登录QQ邮箱 → 设置 → 账户 → 生成新的授权码,并替换代码中的password。
2.更换SMTP端口(推荐使用587+TLS)
QQ邮箱支持465(SSL)和587(TLS),后者更稳定:
  1. smtp_port = 587  # 改用TLS端口
  2. with smtplib.SMTP(smtp_server, smtp_port) as server:
  3.     server.starttls()  # 启用TLS加密
  4.     server.login(sender_email, password)
复制代码
3.检查网络环境
关闭防火墙或切换网络(如使用手机热点测试)。
错误2:AttributeError('characters_written')
错误原因

  • Python 3.10+ 与 SMTP_SSL 的兼容性问题。
  • SSL/TLS握手失败,可能是由于OpenSSL版本不匹配。
解决方案
1.改用starttls()(推荐)
避免使用SMTP_SSL,改用SMTP + starttls():
  1. with smtplib.SMTP(smtp_server, 587) as server:
  2.     server.starttls()  # 显式启用TLS
  3.     server.login(sender_email, password)
复制代码
2.降级Python或升级依赖库
如果仍报错,尝试降级到Python 3.9,或更新pyopenssl:
  1. pip install --upgrade pyopenssl
复制代码
3. 优化后的邮件发送代码

结合上述解决方案,优化后的代码如下:
  1. import smtplib
  2. from email.mime.text import MIMEText
  3. from email.mime.multipart import MIMEMultipart
  4. from email.mime.application import MIMEApplication
  5. import os
  6. import logging
  7. import base64

  8. logger = logging.getLogger(__name__)

  9. def send_email_with_attachment(filepath, receiver_email):
  10.     """发送带附件的邮件(支持QQ邮箱)"""
  11.     sender_email = "your_email@qq.com"
  12.     password = "your_authorization_code"  # 替换为最新授权码
  13.     smtp_server = "smtp.qq.com"
  14.     smtp_port = 587  # 使用TLS端口

  15.     # 检查附件是否存在
  16.     if not os.path.exists(filepath):
  17.         logger.error(f"附件文件不存在: {filepath}")
  18.         return False

  19.     # 创建邮件内容
  20.     msg = MIMEMultipart()
  21.     msg['From'] = sender_email
  22.     msg['To'] = receiver_email
  23.     msg['Subject'] = "文件处理结果通知"
  24.     msg.attach(MIMEText("请查收附件", 'plain'))

  25.     # 添加附件
  26.     try:
  27.         with open(filepath, "rb") as f:
  28.             part = MIMEApplication(f.read(), Name=os.path.basename(filepath))
  29.             part['Content-Disposition'] = f'attachment; filename="{os.path.basename(filepath)}"'
  30.             msg.attach(part)
  31.     except Exception as e:
  32.         logger.error(f"附件处理失败: {e}")
  33.         return False

  34.     # 发送邮件(使用TLS)
  35.     try:
  36.         with smtplib.SMTP(smtp_server, smtp_port) as server:
  37.             server.starttls()  # 启用TLS加密
  38.             server.login(sender_email, password)
  39.             server.sendmail(sender_email, receiver_email, msg.as_string())
  40.         logger.info("邮件发送成功")
  41.         return True
  42.     except smtplib.SMTPException as e:
  43.         logger.error(f"SMTP错误: {e}")
  44.     except Exception as e:
  45.         logger.error(f"未知错误: {e}", exc_info=True)
  46.     return False
复制代码
优化点
1.更健壮的异常处理
区分SMTPException和其他异常,便于排查问题。
2.附件预检查
发送前验证附件是否存在。
3.日志记录
使用logging记录详细错误信息。

4. SMTP调试技巧

手动测试SMTP连接
使用openssl命令行工具测试SMTP服务是否可用:
  1. openssl s_client -connect smtp.qq.com:587 -starttls smtp -crlf
复制代码
输入以下命令(替换为你的邮箱和授权码):
  1. EHLO testAUTH LOGIN<base64编码的邮箱>  # 示例:echo -n "your_email@qq.com" | base64<base64编码的授权码>QUIT
复制代码
如果返回235 Authentication successful,说明SMTP配置正确。
检查防火墙
在Windows上,运行以下命令放行SMTP端口:
  1. netsh advfirewall firewall add rule name="SMTP" dir=in action=allow protocol=TCP localport=587
复制代码
5. 总结与最佳实践

常见问题总结
错误原因解决方案
  1. (-1, b'\x00\x00\x00')
复制代码
授权码错误/SMTP拒绝更新授权码,改用
  1. starttls()
复制代码
  1. AttributeError('characters_written')
复制代码
Python 3.10+兼容性问题降级Python或改用
  1. SMTP
复制代码
+
  1. starttls()
复制代码
  1. SSL: WRONG_VERSION_NUMBER
复制代码
SSL/TLS配置错误使用
  1. starttls()
复制代码
+ 端口587
最佳实践


  • 使用TLS(端口587)代替SSL(端口465),兼容性更好。
  • 定期更新授权码,避免因过期导致发送失败。
  • 添加日志记录,便于排查问题。
  • 手动测试SMTP连接,确保服务器可用。
通过本文的分析和优化,你应该能够解决大多数Python邮件发送问题。如果你的场景涉及更复杂的需求(如批量发送、HTML邮件),可以进一步扩展代码逻辑。
到此这篇关于Python利用SMTP发送邮件的常见问题与解决方案详解的文章就介绍到这了,更多相关Python SMTP发送邮件内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
20
积分
20
注册时间
2022-12-26
最后登录
2022-12-26

发表于 3 天前 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表