文章附件下载:https://www.pan38.com/dow/share.php?code=JCnzE 提取密码:4329
这个Python脚本实现了一个完整的鼠标键盘录制工具,具有以下功能特点:
可以录制鼠标移动、点击和键盘按键操作
支持保存和加载录制文件(JSON格式)
可以调整回放速度
使用多线程实现平滑的鼠标移动录制
提供简单的命令行界面控制录制和回放
记录操作的时间戳,实现精确回放
源码部分:
import pyautogui
import keyboard
import time
import json
from datetime import datetime
import threading
class ActionRecorder:
def init(self):
self.recording = False
self.playing = False
self.actions = []
self.start_time = None
self.stop_event = threading.Event()
def record_mouse_movement(self):
last_pos = pyautogui.position()
while self.recording and not self.stop_event.is_set():
current_pos = pyautogui.position()
if current_pos != last_pos:
timestamp = time.time() - self.start_time
self.actions.append({
'type': 'mouse_move',
'x': current_pos[0],
'y': current_pos[1],
'timestamp': timestamp
})
last_pos = current_pos
time.sleep(0.01)
def on_key_event(self, e):
if self.recording and e.event_type in ('down', 'up'):
timestamp = time.time() - self.start_time
self.actions.append({
'type': 'key_' + e.event_type,
'key': e.name,
'timestamp': timestamp
})
def on_mouse_click(self, x, y, button, pressed):
if self.recording:
timestamp = time.time() - self.start_time
self.actions.append({
'type': 'mouse_' + ('down' if pressed else 'up'),
'button': str(button),
'x': x,
'y': y,
'timestamp': timestamp
})
def start_recording(self):
if not self.recording:
self.actions = []
self.recording = True
self.start_time = time.time()
# Start mouse movement recording thread
mouse_thread = threading.Thread(target=self.record_mouse_movement)
mouse_thread.daemon = True
mouse_thread.start()
# Setup keyboard and mouse listeners
keyboard.hook(self.on_key_event)
pyautogui.onMouseDown = lambda x, y, button, pressed: self.on_mouse_click(x, y, button, pressed)
pyautogui.onMouseUp = lambda x, y, button, pressed: self.on_mouse_click(x, y, button, pressed)
def stop_recording(self):
if self.recording:
self.recording = False
self.stop_event.set()
keyboard.unhook_all()
self.stop_event.clear()
def play_actions(self, speed=1.0):
if not self.playing and self.actions:
self.playing = True
start_time = time.time()
last_timestamp = 0
for action in self.actions:
while self.playing:
current_time = time.time() - start_time
expected_time = action['timestamp'] / speed
if current_time >= expected_time:
break
time.sleep(0.001)
if not self.playing:
break
if action['type'] == 'mouse_move':
pyautogui.moveTo(action['x'], action['y'])
elif action['type'] == 'mouse_down':
pyautogui.mouseDown(x=action['x'], y=action['y'], button=action['button'])
elif action['type'] == 'mouse_up':
pyautogui.mouseUp(x=action['x'], y=action['y'], button=action['button'])
elif action['type'] == 'key_down':
pyautogui.keyDown(action['key'])
elif action['type'] == 'key_up':
pyautogui.keyUp(action['key'])
self.playing = False
def stop_playing(self):
self.playing = False
def save_recording(self, filename):
with open(filename, 'w') as f:
json.dump({
'actions': self.actions,
'created_at': datetime.now().isoformat(),
'screen_size': pyautogui.size()
}, f, indent=2)
def load_recording(self, filename):
with open(filename, 'r') as f:
data = json.load(f)
self.actions = data['actions']
return data['screen_size']
def main():
recorder = ActionRecorder()
print("鼠标键盘录制工具")
print("命令: record, stop, play, save , load , exit")
while True:
cmd = input("> ").strip().lower().split(' ', 1)
action = cmd[0]
if action == 'record':
recorder.start_recording()
print("开始录制... 按Ctrl+C停止")
elif action == 'stop':
recorder.stop_recording()
print("停止录制")
elif action == 'play':
speed = 1.0
if len(cmd) > 1:
try:
speed = float(cmd[1])
except ValueError:
pass
print(f"开始播放 (速度: {speed}x)... 按Ctrl+C停止")
recorder.play_actions(speed)
elif action == 'save' and len(cmd) > 1:
filename = cmd[1]
if not filename.endswith('.json'):
filename += '.json'
recorder.save_recording(filename)
print(f"录制已保存到 {filename}")
elif action == 'load' and len(cmd) > 1:
filename = cmd[1]
if not filename.endswith('.json'):
filename += '.json'
try:
recorder.load_recording(filename)
print(f"从 {filename} 加载录制")
except FileNotFoundError:
print("文件未找到")
elif action == 'exit':
break
else:
print("未知命令")
if name == 'main':
main()