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

Python SMTP多邮件发送:循环交互与账号输入优化求助

问题修复:SMTP邮件发送循环与用户输入优化

原代码问题点

  • 函数send_one_email()被定义在while循环内部,语法错误且无法正常触发循环逻辑
  • 登录账号、收件人邮箱等信息硬编码,未支持用户输入
  • 循环控制变量未正确更新,无法实现「发送另一封/退出」的交互需求

修改后的完整代码

from socket import *
import ssl
import base64

# 全局配置
SMTP_MAIL_SERVER = 'smtp-mail.outlook.com'
SMTP_TLS_PORT = 587
END_MESSAGE = '\r\n.\r\n'

client_socket = None
ssl_context = None


def send_line(line):
    global client_socket
    print('CLIENT: ' + line.strip())
    client_socket.send(line.encode())
    response = client_socket.recv(1024).decode()
    return response


def get_code(response):
    return int(response[:3])


def connect():
    global client_socket
    global ssl_context
    print('CLIENT: Connecting to ' + SMTP_MAIL_SERVER)
    client_socket = socket(AF_INET, SOCK_STREAM)
    client_socket.connect((SMTP_MAIL_SERVER, SMTP_TLS_PORT))
    response = client_socket.recv(1024).decode()
    return response


def send_ehlo():
    helo = 'ehlo smtp-mail.outlook.com\r\n'
    return send_line(helo)


def send_helo():
    helo = 'helo smtp-mail.outlook.com\r\n'
    return send_line(helo)


def start_tls():
    global client_socket
    global ssl_context
    response = send_line('STARTTLS\r\n')
    ssl_context = ssl._create_stdlib_context()
    client_socket = ssl_context.wrap_socket(client_socket, server_hostname=SMTP_MAIL_SERVER)
    return response


def send_auth_request():
    return send_line('auth login\r\n')


def send_username(username):
    as_bytes = username.encode('ascii')
    as_b64 = base64.b64encode(as_bytes)
    as_utf8 = as_b64.decode('utf-8')
    return send_line(as_utf8 + '\r\n')


def send_password(password):
    as_bytes = password.encode('ascii')
    as_b64 = base64.b64encode(as_bytes)
    as_utf8 = as_b64.decode('utf-8')
    return send_line(as_utf8 + '\r\n')


def send_mail_from(sender):
    mail_from = 'MAIL FROM: <' + sender + '>\r\n'
    return send_line(mail_from)


def send_rcpt_to(recipient):
    rcpt_to = 'RCPT TO: <' + recipient + '>\r\n'
    return send_line(rcpt_to)


def send_begin_data():
    return send_line('DATA\r\n')


def send_message(subject, message):
    subject_line = 'Subject: ' + subject + '\r\n'
    body = '\nMessage:' + message + '\r\n'
    return send_line(subject_line + body + END_MESSAGE)


def send_quit():
    return send_line('QUIT\r\n')


def send_one_email(sender, password, recipient, subject, content):
    # 建立连接
    reply = connect()
    print('SERVER: ' + reply)
    # EHLO握手
    reply = send_ehlo()
    print('SERVER: ' + reply)
    # 启动TLS加密
    reply = start_tls()
    print('SERVER: ' + reply)
    # 加密后HELO握手
    reply = send_helo()
    print('SERVER: ' + reply)
    # 认证请求
    reply = send_auth_request()
    print('SERVER: ' + reply)
    # 发送用户名
    reply = send_username(sender)
    print('SERVER: ' + reply)
    # 发送密码
    reply = send_password(password)
    print('SERVER: ' + reply)
    # 发件人
    reply = send_mail_from(sender)
    print('SERVER: ' + reply)
    # 收件人
    reply = send_rcpt_to(recipient)
    print('SERVER: ' + reply)
    # 开始发送数据
    reply = send_begin_data()
    print('SERVER: ' + reply)
    # 发送邮件内容
    reply = send_message(subject, content)
    print('SERVER: ' + reply)
    # 退出会话
    reply = send_quit()
    print('SERVER: ' + reply)


if __name__ == '__main__':
    # 获取用户基础登录信息
    sender_email = input("请输入Outlook登录账号: ")
    sender_pwd = input("请输入Outlook登录密码: ")
    
    while True:
        # 获取本次邮件的目标信息
        recipient_email = input("请输入收件人邮箱地址: ")
        email_subject = input("请输入邮件主题: ")
        email_content = input("请输入邮件内容: ")
        
        # 执行发送逻辑
        send_one_email(sender_email, sender_pwd, recipient_email, email_subject, email_content)
        
        # 处理用户后续选择,兼容输入异常
        while True:
            try:
                choice = int(input("是否发送另一封邮件?输入1继续,0退出: "))
                if choice == 0:
                    print("已退出邮件发送程序")
                    exit()
                elif choice == 1:
                    break
                else:
                    print("输入无效,请输入1或0")
            except ValueError:
                print("输入无效,请输入数字1或0")

关键修改说明

  1. 调整函数结构:将send_one_email()移到循环外部,改为接收参数的形式,避免硬编码,提升代码复用性
  2. 支持用户输入:在主逻辑中获取登录账号、密码,每次循环单独获取收件人、邮件主题和内容
  3. 修复循环逻辑:外层循环控制是否发送下一封,内层循环处理用户输入异常,确保只有有效指令才会执行对应操作
  4. 优化SMTP会话:每次发送完成后主动调用QUIT关闭会话,下一次发送重新建立连接,符合SMTP协议规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:00:08