当前位置:   article > 正文

【Python】实现键盘鼠标动作录制和执行的小工具_python录制鼠标动作

python录制鼠标动作

        突发奇想做一个可以实现鼠标键盘操作录制,并可以回放操作的小工具。依托于pynput模块来实现鼠标键盘的控制,tkinter来实现图形界面的绘制。分为以下几个步骤:

一 录制(记录过程,并将用户的操作保存为json文件)

  1. def on_key_press(key): #当按键按下时记录
  2. if key==pynput.keyboard.Key.esc: #如果是esc
  3. global isRunning
  4. isRunning=False #通知监听鼠标的线程
  5. mouse=pynput.mouse.Controller() #获取鼠标的控制器
  6. mouse.click(pynput.mouse.Button.left) #通过模拟点击鼠标以执行鼠标的线程,然后退出监听.
  7. return False #监听函数return False表示退出监听12
  8. command_list.append((
  9. "press", #操作模式
  10. (str(key).strip("'"),), #具体按下的键,传进来的参数并不是一个字符串,而是一个对象,如果按下的是普通的键,会记录下键对应的字符,否则会使一个"Key.xx"的字符串
  11. time.time()-startTime #操作距离程序开始运行的秒数
  12. ))
  13. def on_key_release(key): #但按键松开时记录
  14. command_list.append((
  15. "release", #操作模式
  16. (str(key).strip("'"),), #键信息,参见on_key_press中的相同部分
  17. time.time()-startTime #操作距离程序开始运行的秒数
  18. ))
  19. def on_mouse_click(x,y,button,pressed):
  20. global mouse_x_old
  21. global mouse_y_old
  22. global mouse_t_old
  23. if not isRunning: #如果已经不在运行了
  24. return False #退出监听
  25. if not pressed: #如果是松开事件
  26. return True #不记录
  27. if mouse_x_old == x and mouse_y_old == y:
  28. if time.time() - mouse_t_old > 0.3: #如果两次点击时间小于0.3秒就会判断为双击 否则就是单击
  29. command_list.append((
  30. "click", # 操作模式
  31. (x, y, str(button)), # 分别是鼠标的坐标和按下的按键
  32. time.time() - startTime # 操作距离程序开始运行的秒数
  33. ))
  34. else:
  35. command_list.pop(0) #删除前一个
  36. command_list.append((
  37. "double-click", # 操作模式
  38. (x, y, str(button)), # 分别是鼠标的坐标和按下的按键
  39. time.time() - startTime # 操作距离程序开始运行的秒数
  40. ))
  41. else:
  42. command_list.append((
  43. "click", # 操作模式
  44. (x, y, str(button)), # 分别是鼠标的坐标和按下的按键
  45. time.time() - startTime # 操作距离程序开始运行的秒数
  46. ))
  47. mouse_x_old = x
  48. mouse_y_old = y
  49. mouse_t_old = time.time()
  50. def start_key_listen(): #用于开始按键的监听
  51. # 进行监听
  52. with pynput.keyboard.Listener(on_press=on_key_press,on_release=on_key_release) as listener:
  53. listener.join()
  54. def start_mouse_listen(): #用于开始鼠标的监听
  55. # 进行监听
  56. with pynput.mouse.Listener(on_click=on_mouse_click) as listener:
  57. listener.join()
  58. def toFile(command_list,path): #保存为文件,参数分别为操作记录和保存位置
  59. with open(path,"w") as f:
  60. f.write(json.dumps(command_list)) #使用json格式写入

二 回放(解析之前记录的json文件,并通过pynput模块控制操作)

  1. def unicode_convert(input_data):
  2. #将unicode转换成str
  3. if isinstance(input_data, dict):
  4. return {unicode_convert(key): unicode_convert(value) for key, value in input_data.iteritems()}
  5. elif isinstance(input_data, list):
  6. return [unicode_convert(element) for element in input_data]
  7. elif isinstance(input_data, str):
  8. return input_data
  9. else:
  10. return input_data
  11. def ExecuteCommandsFile(path):
  12. # 如果命令行传入了参数,则使用命令行参数,否则提示用户输入,此变量表示操作记录文件的路径
  13. # 第二个不是:,也就代表路径是相对路径
  14. path = unicode_convert(path)
  15. if path[2] != ":":
  16. # 将其解析为从本文件开始的路径
  17. path = os.path.join(os.path.dirname(__file__), path)
  18. # 打开文件
  19. with open(path) as f:
  20. # 将记录的命令写入命令列表
  21. command_read = json.loads(f.read())
  22. command_read = unicode_convert(command_read)
  23. # 创建鼠标和键盘的执行器,用于模拟键盘和鼠标的操作
  24. mouse = pynput.mouse.Controller()
  25. keyboard = pynput.keyboard.Controller()
  26. # 鼠标的两个按钮
  27. buttons = {
  28. "Button.left": pynput.mouse.Button.left,
  29. "Button.right": pynput.mouse.Button.right
  30. }
  31. # 开始后已经经过的时间
  32. sTime = 0
  33. # 执行每一条记录
  34. for command in command_read:
  35. # 如果是点击记录
  36. print(command[0])
  37. print(command[1])
  38. print(command[2])
  39. # 如果是单击
  40. if command[0] == "click":
  41. # 将鼠标移动到记录中的位置
  42. mouse.position = (command[1][0], command[1][1])
  43. # 等待一下
  44. time.sleep(0.1)
  45. # 点击
  46. mouse.click(buttons[command[1][2]])
  47. # 如果是双击
  48. elif command[0] == "double-click":
  49. # 将鼠标移动到记录中的位置
  50. mouse.position = (command[1][0], command[1][1])
  51. # 等待一下
  52. time.sleep(0.1)
  53. # 双击
  54. mouse.click(buttons[command[1][2]], 2)
  55. # 如果是按键按下
  56. elif command[0] == "press":
  57. # 如果是特殊按键,会记录成Key.xxx,这里判断是不是特殊按键
  58. if command[1][0][:3] == "Key":
  59. # 按下按键
  60. keyboard.press(eval(command[1][0], {}, {
  61. "Key": pynput.keyboard.Key
  62. }))
  63. else:
  64. # 如果是普通按键,直接按下
  65. if "<255>" == command[1][0]:
  66. continue
  67. print(command[1][0])
  68. # print(command[1][0].split("'")[1])
  69. # keyboard.press(command[1][0].split("'")[1])
  70. keyboard.press(command[1][0])
  71. # 如果是按键释放
  72. elif command[0] == "release":
  73. # 如果是特殊按键
  74. if command[1][0][:3] == "Key":
  75. # 按下按键
  76. keyboard.release(eval(command[1][0], {}, {
  77. "Key": pynput.keyboard.Key
  78. }))
  79. else:
  80. # 普通按键直接按下
  81. if "<255>" == command[1][0]:
  82. continue
  83. print(command[1][0])
  84. # print(command[1][0].split("'")[1])
  85. # keyboard.release(command[1][0].split("'")[1])
  86. keyboard.release(command[1][0])
  87. # command[2]代表此操作距离开始操作所经过的时间,用它减去已经经过的时间就是距离下一次操作的时间
  88. time.sleep(command[2] - sTime)
  89. # 更新时间
  90. sTime = command[2]

【3】图形界面(通过tkinter绘制简易的操作界面)

  1. import os # 用于文件操作
  2. import time #用于记录每一项操作的时间
  3. import json #用于保存导出我们记录的操作
  4. import threading #由于键盘和鼠标事件的监听都是阻塞的,所以用两个线程实现
  5. import tkinter #绘制操作界面
  6. from tkinter import messagebox
  7. import pynput #用于记录用户事件
  8. import ctypes
  9. PROCESS_PER_MONITOR_DPI_AWARE = 2 #解决由于屏幕分辨率缩放导致的,pynput监听鼠标位置不准的问题
  10. ctypes.windll.shcore.SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)
  11. command_list=[] #用来存储用户的操作
  12. command_read=[] #用来读取录制的操作
  13. isRunning=True #是否在运行,用于实现在按esc后退出的功能
  14. startTime=0 #开始时间,会在之后main函数中进行初始化
  15. mouse_x_old = 0
  16. mouse_y_old = 0
  17. mouse_t_old = 0
  18. #插入录制部分代码
  19. #插入执行部分代码
  20. class TKDemo:
  21. def __init__(self):
  22. self.top = tkinter.Tk()
  23. self.top.title('鼠标宏录制工具')
  24. self.top.geometry('500x250')
  25. frame1 = tkinter.Frame(self.top)
  26. frame1.pack(side='top')
  27. l1 = tkinter.Label(frame1,
  28. text='【1----录制操作】\n注意:按Esc退出录制,暂不支持键盘组合键')
  29. l1.pack()
  30. b1 = tkinter.Button(frame1,
  31. text='录制',
  32. width=15, height=2,
  33. command=self.recordOp)
  34. b1.pack()
  35. frame2 = tkinter.Frame(self.top)
  36. frame2.pack(side='bottom')
  37. l2 = tkinter.Label(frame2,
  38. text='【2----执行操作】')
  39. l2.pack()
  40. b2 = tkinter.Button(frame2,
  41. text='执行',
  42. width=15, height=2,
  43. command=self.execOp)
  44. b2.pack()
  45. l3 = tkinter.Label(frame2,
  46. text='请输入执行次数,默认为1次')
  47. l3.pack()
  48. self.count = tkinter.StringVar()
  49. e1= tkinter.Entry(frame2, textvariable=self.count)
  50. e1.pack()
  51. self.top.mainloop()
  52. def recordOp(self):
  53. self.top.iconify() #窗口隐藏
  54. global startTime
  55. startTime = time.time() # 初始化开始时间
  56. key_listen_thread = threading.Thread(target=start_key_listen) # 创建用于监听按键的线程
  57. mouse_listen_thread = threading.Thread(target=start_mouse_listen) # 创建用于监听鼠标的线程
  58. # 运行线程
  59. key_listen_thread.start()
  60. mouse_listen_thread.start()
  61. # 等待线程结束,也就是等待用户按下esc
  62. key_listen_thread.join()
  63. mouse_listen_thread.join()
  64. # 记录成功之后执行下列操作
  65. toFile(command_list, "./commands.json")# 保存文件
  66. global isRunning
  67. isRunning = True # 初始化记录状态
  68. command_list.clear() # 清空列表
  69. self.top.deiconify() # 窗口显现
  70. print("记录成功!")
  71. tkinter.messagebox.showinfo('提示', '记录成功!')
  72. def execOp(self):
  73. self.top.iconify() # 窗口隐藏
  74. path = 'commands.json'
  75. count = self.count.get()
  76. if count.isdigit():
  77. for i in range(int(count)):
  78. ExecuteCommandsFile(path)
  79. print("执行成功%d次!" % (int(count)))
  80. tkinter.messagebox.showinfo('提示', "执行完毕!\n共%d次!" % (int(count)))
  81. elif len(count) == 0:
  82. ExecuteCommandsFile(path)
  83. print("执行成功1次!")
  84. tkinter.messagebox.showinfo('提示', '执行完毕!\n共1次!')
  85. else:
  86. print("执行失败!请键入数字")
  87. tkinter.messagebox.showerror('提示', '执行失败!\n请键入数字!')
  88. self.top.deiconify() # 窗口显现
  89. def main(): #主函数
  90. TKDemo()
  91. if __name__=="__main__":
  92. main()

        综上,即可实现该简单的功能。

四 附录

【1】开源库地址:Python_MouseClick: 通过python tkinter构建界面,录制鼠标和键盘的操作,并执行n次操作回放

【2】参考文章地址:

python3实现鼠标键盘动作录制,并还原执行过程_momo131422的博客-CSDN博客_python录制鼠标动作

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/272496?site
推荐阅读
相关标签
  

闽ICP备14008679号