You need to enable JavaScript to run this app. Python命令行邮件发送工具如何实现附件上传百分比进度条
优惠活动
大模型
产品
解决方案
定价
更多

Python命令行邮件发送工具如何实现附件上传百分比进度条

可行性结论
  • 附件上传百分比进度的展示需求完全可以实现,但smtplib没有提供内置的进度回调方法,需要通过改造现有全量发送的逻辑自主统计进度。
  • 你当前代码的实现方式存在进度感知的根本限制:server.sendmail()会一次性把全部组装好的邮件内容(含所有附件)交给底层网络连接传输,程序完全拿不到分块发送的实时字节数。
实现思路
  • 提前将组装完成的MIME消息序列化为字节流,统计总长度作为进度计算的分母。
  • 绕开sendmail()的全量传输封装,按照SMTP协议的会话流程,把完整的邮件字节流拆成固定大小的分块,逐块写入底层网络连接;每写完一个分块就累计已发送的字节数,实时计算上传百分比并输出。
  • 传输过程中的SMTP协议特殊字符转义、会话状态校验直接复用smtplib的内置能力,不需要手动实现协议细节。
参考实现代码

替换原有sendmail逻辑的可运行示例:

# 提前序列化全量邮件内容并统计大小
total_email_content = message.as_bytes()
total_email_size = len(total_email_content)
sent_size = 0
# 常规选择4KB-16KB的分块大小,兼顾传输效率和进度刷新频率
CHUNK_SIZE = 4096

context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
    server.login(sender_email, password)
    # 按SMTP协议流程推进会话状态
    server.mail(sender_email)
    server.rcpt(receiver_email)
    # 进入数据传输阶段
    server.data(b"", first=True)
    # 分块发送内容
    for offset in range(0, total_email_size, CHUNK_SIZE):
        chunk = total_email_content[offset:offset+CHUNK_SIZE]
        server.send(chunk)
        sent_size += len(chunk)
        # 单行刷新进度,避免控制台重复刷屏
        progress = sent_size / total_email_size * 100
        print(f"\r上传进度: {progress:.2f}%", end="", flush=True)
    # 发送数据结束标记,完成邮件提交
    server.data(b".\r\n")

print("\n邮件发送成功")
关键提示
  • 上述统计的是整个邮件内容的传输进度,由于附件经过base64编码后通常占邮件总大小的90%以上,最终的进度数值和附件实际的上传完成度高度匹配,完全符合需求。
  • 不要跳过SMTP的会话状态校验直接写socket内容,否则会触发服务器的协议报错,导致发送失败。
  • 如果需要单独区分正文和附件的上传进度,可以在组装MIME消息时提前记录附件编码内容在全量字节流中的起始、结束偏移量,在进度计算时单独映射对应区间的进度。

内容的提问来源于stack exchange,提问作者Nimrod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 09:24:03