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")
关键修改说明
- 调整函数结构:将
send_one_email()移到循环外部,改为接收参数的形式,避免硬编码,提升代码复用性 - 支持用户输入:在主逻辑中获取登录账号、密码,每次循环单独获取收件人、邮件主题和内容
- 修复循环逻辑:外层循环控制是否发送下一封,内层循环处理用户输入异常,确保只有有效指令才会执行对应操作
- 优化SMTP会话:每次发送完成后主动调用
QUIT关闭会话,下一次发送重新建立连接,符合SMTP协议规范
内容的提问来源于stack exchange,提问作者Corroxin Gaming
相关产品推荐
相关产品推荐

