Python记录以及模拟键盘鼠标事情
分两部分:
- 记录所有的鼠标操作和键盘操作
- 根据记录的结果,用程序来重现一遍.
之所以做这个事情,是看到有人用python来实现自动玩网页游戏.并且里面还使用到了图像匹配.来使鼠标操作更加准确.这里先简单点完全复制鼠标和键盘的操作,但如果初始的界面不一样会导致程序重现的效果和原始的效果完全不同.这个问题后面再来想办法解决吧.
- 记录鼠标和键盘输入操作
需要用到的库: pyHook ,这里有点小麻烦,pyHook现在只能支持2.7及以下的版本,现在已经停止更新了.但是目前还没找到其他可以替代的库.
代码比较简单:
# -*- coding: utf-8 -*- # ''' 模块功能: 截取电脑的按键操作和鼠标操作,保存为文件形式 按下键盘的Scroll键保存缓存中的数据,终止记录时可以用这样的操作来保存完整的数据 '''
import pythoncom import pyHook import sys import datetime
# make a copy of original stdout route stdout_backup = sys.stdout
# define the log file that receives your log info str_now = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") log_filename = 'msg' + str_now + '.log' log_file = open(log_filename, "w") # redirect print output to log file sys.stdout = log_file
key_value = 0
def onMouseEvent(event): ''' Message ID: 513 - mouse left down 514 - mouse left up 516 - mouse right down 517 - mouse right up 519 - mouse middle down 520 - mouse middle up 522 - mouse wheel 输出格式 : [事件ID , 发生的时间, 坐标x ,坐标y , 滚轮值] 其中滚轮值为[-1,0,1] ,当事件为鼠标滚轮时,值为1或-1,其他情况下均为0 ''' print "%3d,%8d,%4d,%4d,%2d" % (event.Message, event.Time, event.Position[0], event.Position[1], event.Wheel)
# 返回 True 以便将事件传给其它处理程序 # 注意,这儿如果返回 False ,则鼠标事件将被全部拦截 # 也就是说你的鼠标看起来会僵在那儿,似乎失去响应了 return True
def onKeyboardEvent(event): ''' Message ID: 256 - key down 257 - key up 输出格式 : [事件ID , 发生的时间, ASCII , VK , EXTEND] 其中滚轮值为[-1,0,1] ,当事件为鼠标滚轮时,值为1或-1,其他情况下均为0 ''' print "%3d,%8d,%3d,%3d,%d" % (event.Message, event.Time, event.Ascii, event.KeyID, event.Extended)
if event.KeyID == 0x91: log_file.flush() # 同鼠标事件监听函数的返回值 return True
def main(): # 创建一个"钩子"管理对象 hm = pyHook.HookManager() # 监听所有键盘事件 hm.KeyDown = onKeyboardEvent hm.KeyUp = onKeyboardEvent # 设置键盘"钩子" hm.HookKeyboard() # 监听所有鼠标按键事件 hm.MouseAllButtons = onMouseEvent hm.MouseWheel = onMouseEvent # MouseWheel # 设置鼠标"钩子" hm.HookMouse() # 进入循环,如不手动关闭,程序将一直处于监听状态 pythoncom.PumpMessages()
if __name__ == "__main__": main() |
关于pyHook的用法,可以参考安装目录下的example.py文件,比较详细.
- 程序重新鼠标和键盘操作
需要用到的库文件: pywin32.
代码如下:
# _*_ coding:UTF-8 _*_ ''' 根据鼠标和键盘操作记录, 以程序的方式重现一遍 '''
import win32api import win32con import win32gui from ctypes import * import time import string
event_to_win32ID = { 513: win32con.MOUSEEVENTF_LEFTDOWN, 514: win32con.MOUSEEVENTF_LEFTUP, 516: win32con.MOUSEEVENTF_RIGHTDOWN, 517: win32con.MOUSEEVENTF_RIGHTUP, 519: win32con.MOUSEEVENTF_MIDDLEDOWN, 520: win32con.MOUSEEVENTF_MIDDLEUP, 522: win32con.MOUSEEVENTF_WHEEL, 256: 0, 257: win32con.KEYEVENTF_KEYUP, }
def mouse_move(x, y): windll.user32.SetCursorPos(x, y)
def mouse_click(event, x=None, y=None, wheel=0): if not x is None and not y is None: mouse_move(x, y) win32api.mouse_event(event_to_win32ID[event], 0, 0, wheel, 0)
def key_input_ASCII(code, event): win32api.keybd_event(code, 0, event_to_win32ID[event], 0)
def key_input_VK(v_code, event): win32api.keybd_event(v_code, 0, event_to_win32ID[event], 0)
def readfile_mk(): # record file name filename = "msg.log" f = open(filename, 'r') last_time_stamp = 0 # read lines for lineStr in f.xreadlines(): line_data = map(string.atoi, lineStr.split(',')) # check if the data len is 5 if len(line_data) == 5: # get the time
sleeptime = (line_data[1] - last_time_stamp)/2000.0 if sleeptime < 0 or sleeptime > 2: sleeptime = 1 time.sleep(sleeptime)
last_time_stamp = line_data[1]
if event_to_win32ID.has_key(line_data[0]): # mouse operation if line_data[0] > 500: mouse_click(line_data[0], line_data[2], line_data[3], line_data[4]) # Key operation else: key_input_VK(line_data[3], line_data[0]) # read next line
if __name__ == '__main__': readfile_mk() |
Pywin32的帮助文档可以上google找到,能实现的功能很多,这里需要用到的函数很少.