You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止SMTP连接超时?Python smtplib无限运行脚本密码安全处理

嘿,我正好做过类似的需求,给你整理一套靠谱的解决方案👇

针对无限运行脚本+每日发确认邮件的完整方案

一、密码安全处理:仅初始化时输入

你用getpass.getpass()的思路完全正确!这是Python标准库提供的安全输入方式,输入时不会显示明文,而且只在脚本启动时输入一次,之后密码会存在内存里供后续发送邮件使用——只要脚本不重启,就不用重复输入,完美符合你不想写死密码的需求。

二、实现每日定时发送逻辑

既然要脚本无限运行且每日执行,推荐用schedule这个轻量定时任务库,比自己写time.sleep()判断时间要直观好维护。当然如果你不想额外装库,也可以用系统级定时任务(比如Linux的cron、Windows任务计划),但脚本内定时更贴合你“无限运行”的要求。

三、防止SMTP连接超时的核心技巧

SMTP连接超时大多是因为长连接被服务器闲置断开,或者网络波动,这几个方法能有效解决:

  • 每次发信重建连接:别保持长连接,每次发送邮件前重新初始化SMTP连接,发完就关闭(用with语句自动管理连接最省心),避免长时间闲置被踢。
  • 设置连接超时参数:在smtplib.SMTP()或SMTP_SSL()初始化时加上timeout参数,比如smtplib.SMTP_SSL('smtp.example.com', 465, timeout=30),避免程序无限等待卡死。
  • 添加重试机制:用try-except捕获超时、连接失败等异常,重试2-3次,提升容错率。

四、完整可运行示例代码

import smtplib
import getpass
import schedule
import time
from email.mime.text import MIMEText
from email.header import Header

# 初始化邮箱信息,仅启动时输入一次密码
def init_email_config():
    global sender_addr, auth_code, receiver_addr
    sender_addr = "your_sender@example.com"
    # 安全输入授权码/密码,不显示明文
    auth_code = getpass.getpass("请输入邮箱授权码/密码: ")
    receiver_addr = "your_receiver@example.com"

# 发送确认邮件的核心函数
def send_daily_confirmation():
    try:
        # 构建邮件内容
        email_content = "今日任务指定步骤已完成,请查收确认!"
        msg = MIMEText(email_content, 'plain', 'utf-8')
        msg['From'] = Header("任务自动化通知", 'utf-8')
        msg['To'] = Header("负责人", 'utf-8')
        msg['Subject'] = Header("每日任务完成确认", 'utf-8')

        # 每次发信重建连接,避免长连接超时
        with smtplib.SMTP_SSL('smtp.example.com', 465, timeout=30) as smtp_server:
            smtp_server.login(sender_addr, auth_code)
            smtp_server.sendmail(sender_addr, receiver_addr, msg.as_string())
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 确认邮件发送成功")
    except smtplib.SMTPException as e:
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 邮件发送失败: {str(e)}")
        # 重试2次,每次间隔5秒
        for retry_count in range(2):
            time.sleep(5)
            try:
                with smtplib.SMTP_SSL('smtp.example.com', 465, timeout=30) as smtp_server:
                    smtp_server.login(sender_addr, auth_code)
                    smtp_server.sendmail(sender_addr, receiver_addr, msg.as_string())
                print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 第{retry_count+1}次重试成功")
                break
            except smtplib.SMTPException as retry_err:
                print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 第{retry_count+1}次重试失败: {str(retry_err)}")
    except Exception as general_err:
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] 发生未知错误: {str(general_err)}")

# 主程序:初始化+启动定时任务
def main():
    init_email_config()
    # 设置每日发送时间,比如早上9点
    schedule.every().day.at("09:00").do(send_daily_confirmation)
    
    print("脚本已启动,将每日09:00自动发送任务确认邮件...")
    # 无限循环运行定时任务
    while True:
        schedule.run_pending()
        time.sleep(60)  # 每分钟检查一次任务状态

if __name__ == "__main__":
    main()

额外提醒

  • 如果你用的是QQ、163等第三方邮箱,记得开启POP3/SMTP服务,并且用授权码代替登录密码(授权码在邮箱设置里生成),比直接用密码更安全,也能避免一些登录限制。
  • 如果需要脚本后台运行,Linux可以用nohup python your_script.py &,Windows可以把脚本打包成服务或者用后台运行工具,防止终端关闭后脚本停止。
  • 定时任务精度:示例里每分钟检查一次任务,完全满足每日定时的需求,要是需要更高精度,可以把time.sleep(60)改成time.sleep(10)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:08:01