Python记录键盘鼠标敲击次数
Idea
作为一个每天有一半时间都在电脑旁的人,无时无刻不在敲击着键盘,点击着鼠标。有一天,我突然很想知道在一天的时间内,在我轻盈的指法下面,键盘被我狂敲了多少下,鼠标又被我点击了多少次。甚至更具体一些,键盘上哪些键挨的敲击次数更多呢?想想也觉得挺有意思的。
Learing
有了想法,接着就是上(寻)网(找)学(代)习(码)了。既然要记录键盘敲击和鼠标点击的次数,那就得监听键盘和鼠标的事件。在搜索过程中,了解到了钩子函数这个概念。想要学习的同学可以看下这篇博客
毕竟我只是想实现一下功能,也就没太深入学习。对比了一些各种语言对于监听事件的实现代码,发现Python简直不能再简洁了,果断使用Python。
Coding(Copying)
现在想法、概念知识和所用工具都具备了,剩下的就是用代码去实现。Python环境自然不用多说,除此之外还需要几个第三方的库。主要参考这篇博客,自己的想法其实别人早就已经实现了。
当然别人的代码并不完全符合自己的需求,我不需要记录键盘、鼠标点击事件过于详细的信息,我需要记录的仅仅是次数。在前人的代码基础上修改一番即可。
#!/usr/bin/env python # -*- coding: utf-8 -*- import pythoncom import pyHook import time import win32api """ def onMouseEvent(event): "处理鼠标事件" fobj.writelines('-' * 20 + 'MouseEvent Begin' + '-' * 20 + '\n') fobj.writelines("Current Time:%s\n" % time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())) fobj.writelines("MessageName:%s\n" % str(event.MessageName)) fobj.writelines("Message:%d\n" % event.Message) fobj.writelines("Time_sec:%d\n" % event.Time) fobj.writelines("Window:%s\n" % str(event.Window)) fobj.writelines("WindowName:%s\n" % str(event.WindowName)) fobj.writelines("Position:%s\n" % str(event.Position)) fobj.writelines('-' * 20 + 'MouseEvent End' + '-' * 20 + '\n') return True """ def onMouse_rightup(event): # 监听鼠标左键按下事件 次数加1 global right_up_num right_up_num += 1 return True def onMouse_leftup(event): # 监听鼠标左键弹起事件 次数加1 global left_up_num left_up_num += 1 return True def onKeyboardEvent(event): # 处理键盘事件 定义各个键位全局变量,记录敲击次数 global key_a_num global key_b_num global key_c_num global key_d_num global key_e_num global key_f_num global key_g_num global key_h_num global key_i_num global key_j_num global key_k_num global key_l_num global key_m_num global key_n_num global key_o_num global key_p_num global key_q_num global key_r_num global key_s_num global key_t_num global key_u_num global key_v_num global key_w_num global key_x_num global key_y_num global key_z_num global key_enter_num global key_back_num global key_1_num global key_2_num global key_3_num global key_4_num global key_5_num global key_6_num global key_7_num global key_8_num global key_9_num global key_0_num global key_oem_3_num #~ global key_oem_minus_num #- global key_oem_plus_num #+ global key_tab_num #tab global key_cap_num #caps global key_lshift_num #left shift global key_lctrl_num #left ctrl global key_lwin_num global key_lalt_num global key_space_num global key_rshift_num #left shift global key_rctrl_num #left ctrl global key_rwin_num global key_ralt_num global key_oem_comma_num #, global key_oem_period_num #. global key_oem_2_num #/ global key_oem_1_num #; global key_oem_7_num #' global key_oem_4_num #[ global key_oem_5_num #] global key_oem_6_num #\ global key_left_num #左 global key_right_num #右 global key_up_num #上 global key_down_num #下 global key_delete_num #delete global key_end_num #end global key_next_num #page down global key_insert_num #insert global key_home_num #home global key_prior_num #page up global key_snapshot_num #print screen global key_scroll_num #scroll lock global key_pause_num #pause global key_escape_num #esc global key_f1_num global key_f2_num global key_f3_num global key_f4_num global key_f5_num global key_f6_num global key_f7_num global key_f8_num global key_f9_num global key_f10_num global key_f11_num global key_f12_num global key_numpad0_num global key_numpad1_num global key_numpad2_num global key_numpad3_num global key_numpad4_num global key_numpad5_num global key_numpad6_num global key_numpad7_num global key_numpad8_num global key_numpad9_num global key_numlock_num global key_divide_num global key_multiply_num global key_subtract_num global key_add_num global key_decimal_num global key_total_num #总敲击次数 fobj.write("%s" % str(event.Key)+" ") s=str(event.Key) if s=='A': key_a_num+=1 key_total_num+=1 elif s=='B': key_b_num+=1 key_total_num+=1 elif s=='C': key_c_num+=1 key_total_num+=1 elif s=='D': key_d_num+=1 key_total_num+=1 elif s=='E': key_e_num+=1 key_total_num+=1 elif s=='F': key_f_num+=1 key_total_num+=1 elif s=='G': key_g_num+=1 key_total_num+=1 elif s=='H': key_h_num+=1 key_total_num+=1 elif s=='I': key_i_num+=1 key_total_num+=1 elif s=='J': key_j_num+=1 key_total_num+=1 elif s=='K': key_k_num+=1 key_total_num+=1 elif s=='L': key_l_num+=1 key_total_num+=1 elif s=='M': key_m_num+=1 key_total_num+=1 elif s=='N': key_n_num+=1 key_total_num+=1 elif s=='O': key_o_num+=1 key_total_num+=1 elif s=='P': key_p_num+=1 key_total_num+=1 elif s=='Q': key_q_num+=1 key_total_num+=1 elif s=='R': key_r_num+=1 key_total_num+=1 elif s=='S': key_s_num+=1 key_total_num+=1 elif s=='T': key_t_num+=1 key_total_num+=1 elif s=='U': key_u_num+=1 key_total_num+=1 elif s=='V': key_v_num+=1 key_total_num+=1 elif s=='W': key_w_num+=1 key_total_num+=1 elif s=='X': key_x_num+=1 key_total_num+=1 elif s=='Y': key_y_num+=1 key_total_num+=1 elif s=='Z': key_z_num+=1 key_total_num+=1 elif s=='Return': key_enter_num+=1 key_total_num+=1 elif s=='Back': key_back_num+=1 key_total_num+=1 elif s=='1': key_1_num+=1 key_total_num+=1 elif s=='2': key_2_num+=1 key_total_num+=1 elif s=='3': key_3_num+=1 key_total_num+=1 elif s=='4': key_4_num+=1 key_total_num+=1 elif s=='5': key_5_num+=1 key_total_num+=1 elif s=='6': key_6_num+=1 key_total_num+=1 elif s=='7': key_7_num+=1 key_total_num+=1 elif s=='8': key_8_num+=1 key_total_num+=1 elif s=='9': key_9_num+=1 key_total_num+=1 elif s=='0': key_0_num+=1 key_total_num+=1 elif s=='Oem_3': key_oem_3_num+=1 key_total_num+=1 elif s=='Oem_Minus': key_oem_minus_num+=1 key_total_num+=1 elif s=='Oem_Plus': key_oem_plus_num+=1 key_total_num+=1 elif s=='Tab': key_tab_num+=1 key_total_num+=1 elif s=='Capital': key_cap_num+=1 key_total_num+=1 elif s=='Lshift': key_lshift_num+=1 key_total_num+=1 elif s=='Lcontrol': key_lctrl_num+=1 key_total_num+=1 elif s=='Lwin': key_lwin_num+=1 key_total_num+=1 elif s=='Lmenu': key_lalt_num+=1 key_total_num+=1 elif s=='Space': key_space_num+=1 key_total_num+=1 elif s=='Rshift': key_rshift_num+=1 key_total_num+=1 elif s=='Rcontrol': key_rctrl_num+=1 key_total_num+=1 elif s=='Rwin': key_rwin_num+=1 key_total_num+=1 elif s=='Rmenu': key_ralt_num+=1 key_total_num+=1 elif s=='Oem_Comma': key_oem_comma_num+=1 key_total_num+=1 elif s=='Oem_Period': key_oem_period_num+=1 key_total_num+=1 elif s=='Oem_2': key_oem_2_num+=1 key_total_num+=1 elif s=='Oem_1': key_oem_1_num+=1 key_total_num+=1 elif s=='Oem_7': key_oem_7_num+=1 key_total_num+=1 elif s=='Oem_4': key_oem_4_num+=1 key_total_num+=1 elif s=='Oem_5': key_oem_5_num+=1 key_total_num+=1 elif s=='Oem_6': key_oem_6_num+=1 key_total_num+=1 elif s=='Left': key_left_num+=1 key_total_num+=1 elif s=='Right': key_right_num+=1 key_total_num+=1 elif s=='Up': key_up_num+=1 key_total_num+=1 elif s=='Down': key_down_num+=1 key_total_num+=1 elif s=='Delete': key_delete_num+=1 key_total_num+=1 elif s=='End': key_end_num+=1 key_total_num+=1 elif s=='Next': key_next_num+=1 key_total_num+=1 elif s=='Insert': key_insert_num+=1 key_total_num+=1 elif s=='Home': key_home_num+=1 key_total_num+=1 elif s=='Prior': key_prior_num+=1 key_total_num+=1 elif s=='Snapshot': key_snapshot_num+=1 key_total_num+=1 elif s=='Scroll': key_scroll_num+=1 key_total_num+=1 elif s=='Pause': key_pause_num+=1 key_total_num+=1 elif s=='Escape': key_escape_num+=1 key_total_num+=1 elif s=='F1': key_f1_num+=1 key_total_num+=1 elif s=='F2': key_f2_num+=1 key_total_num+=1 elif s=='F3': key_f3_num+=1 key_total_num+=1 elif s=='F4': key_f4_num+=1 key_total_num+=1 elif s=='F5': key_f5_num+=1 key_total_num+=1 elif s=='F6': key_f6_num+=1 key_total_num+=1 elif s=='F7': key_f7_num+=1 key_total_num+=1 elif s=='F8': key_f8_num+=1 key_total_num+=1 elif s=='F9': key_f9_num+=1 key_total_num+=1 elif s=='F10': key_f10_num+=1 key_total_num+=1 elif s=='F11': key_f11_num+=1 key_total_num+=1 elif s=='F12': key_f12_num+=1 key_total_num+=1 elif s=='Numpad0': key_numpad0_num+=1 key_total_num+=1 elif s=='Numpad1': key_numpad1_num+=1 key_total_num+=1 elif s=='Numpad2': key_numpad2_num+=1 key_total_num+=1 elif s=='Numpad3': key_numpad3_num+=1 key_total_num+=1 elif s=='Numpad4': key_numpad4_num+=1 key_total_num+=1 elif s=='Numpad5': key_numpad5_num+=1 key_total_num+=1 elif s=='Numpad6': key_numpad6_num+=1 key_total_num+=1 elif s=='Numpad7': key_numpad7_num+=1 key_total_num+=1 elif s=='Numpad8': key_numpad8_num+=1 key_total_num+=1 elif s=='Numpad9': key_numpad9_num+=1 key_total_num+=1 elif s=='Numlock': key_numlock_num+=1 key_total_num+=1 elif s=='Divide': key_divide_num+=1 key_total_num+=1 elif s=='Multiply': key_multiply_num+=1 key_total_num+=1 elif s=='Subtract': key_subtract_num+=1 key_total_num+=1 elif s=='Add': key_add_num+=1 key_total_num+=1 elif s=='Decimal': key_decimal_num+=1 key_total_num+=1 #定义一个退出的按键,并将记录的信息写入txt if str(event.Key)=='Pause': fobj.write("\n") fobj.write("鼠标右键点击量: %d\n" % right_up_num) fobj.write("鼠标左键点击量: %d\n" % left_up_num) fobj.write("键盘总点击量: %d\n" % key_total_num) fobj.write("a: %d\n" % key_a_num) fobj.write("b: %d\n" % key_b_num) fobj.write("c: %d\n" % key_c_num) fobj.write("d: %d\n" % key_d_num) fobj.write("e: %d\n" % key_e_num) fobj.write("f: %d\n" % key_f_num) fobj.write("g: %d\n" % key_g_num) fobj.write("h: %d\n" % key_h_num) fobj.write("i: %d\n" % key_i_num) fobj.write("j: %d\n" % key_j_num) fobj.write("k: %d\n" % key_k_num) fobj.write("l: %d\n" % key_l_num) fobj.write("m: %d\n" % key_m_num) fobj.write("n: %d\n" % key_n_num) fobj.write("o: %d\n" % key_o_num) fobj.write("p: %d\n" % key_p_num) fobj.write("q: %d\n" % key_q_num) fobj.write("r: %d\n" % key_r_num) fobj.write("s: %d\n" % key_s_num) fobj.write("t: %d\n" % key_t_num) fobj.write("u: %d\n" % key_u_num) fobj.write("v: %d\n" % key_v_num) fobj.write("w: %d\n" % key_w_num) fobj.write("x: %d\n" % key_x_num) fobj.write("y: %d\n" % key_y_num) fobj.write("z: %d\n" % key_z_num) fobj.write("enter: %d\n" % key_enter_num) fobj.write("back: %d\n" % key_back_num) fobj.write("0: %d\n" % key_0_num) fobj.write("1: %d\n" % key_1_num) fobj.write("2: %d\n" % key_2_num) fobj.write("3: %d\n" % key_3_num) fobj.write("4: %d\n" % key_4_num) fobj.write("5: %d\n" % key_5_num) fobj.write("6: %d\n" % key_6_num) fobj.write("7: %d\n" % key_7_num) fobj.write("8: %d\n" % key_8_num) fobj.write("9: %d\n" % key_9_num) fobj.write("~: %d\n" % key_oem_3_num) fobj.write("r-: %d\n" % key_oem_minus_num) fobj.write("r+: %d\n" % key_oem_plus_num) fobj.write("tab: %d\n" % key_tab_num) fobj.write("caps: %d\n" % key_cap_num) fobj.write("Lshift: %d\n" % key_lshift_num) fobj.write("Lctrl: %d\n" % key_lctrl_num) fobj.write("Lwin: %d\n" % key_lwin_num) fobj.write("Lalt: %d\n" % key_lalt_num) fobj.write("space: %d\n" % key_space_num) fobj.write("Rshift: %d\n" % key_rshift_num) fobj.write("Rctrl: %d\n" % key_rctrl_num) fobj.write("Rwin: %d\n" % key_rwin_num) fobj.write("Ralt: %d\n" % key_ralt_num) fobj.write(",<: %d\n" % key_oem_comma_num) fobj.write(".>: %d\n" % key_oem_period_num) fobj.write("/?: %d\n" % key_oem_2_num) fobj.write(";: %d\n" % key_oem_1_num) fobj.write("双引号: %d\n" % key_oem_7_num) fobj.write("[{: %d\n" % key_oem_4_num) fobj.write("]}: %d\n" % key_oem_5_num) fobj.write("\|: %d\n" % key_oem_6_num) fobj.write("左: %d\n" % key_left_num) fobj.write("右: %d\n" % key_right_num) fobj.write("上: %d\n" % key_up_num) fobj.write("下: %d\n" % key_right_num) fobj.write("delete: %d\n" % key_delete_num) fobj.write("end: %d\n" % key_end_num) fobj.write("pagedown: %d\n" % key_next_num) fobj.write("insert: %d\n" % key_insert_num) fobj.write("pageup: %d\n" % key_prior_num) fobj.write("home: %d\n" % key_home_num) fobj.write("print screen: %d\n" % key_snapshot_num) fobj.write("scroll lock: %d\n" % key_scroll_num) fobj.write("pause: %d\n" % key_pause_num) fobj.write("esc: %d\n" % key_escape_num) fobj.write("f1: %d\n" % key_f1_num) fobj.write("f2: %d\n" % key_f2_num) fobj.write("f3: %d\n" % key_f3_num) fobj.write("f4: %d\n" % key_f4_num) fobj.write("f5: %d\n" % key_f5_num) fobj.write("f6: %d\n" % key_f6_num) fobj.write("f7: %d\n" % key_f7_num) fobj.write("f8: %d\n" % key_f8_num) fobj.write("f9: %d\n" % key_f9_num) fobj.write("f10: %d\n" % key_f10_num) fobj.write("f11: %d\n" % key_f11_num) fobj.write("f12: %d\n" % key_f12_num) fobj.write("numpad0: %d\n" % key_numpad0_num) fobj.write("numpad1: %d\n" % key_numpad1_num) fobj.write("numpad2: %d\n" % key_numpad2_num) fobj.write("numpad3: %d\n" % key_numpad3_num) fobj.write("numpad4: %d\n" % key_numpad4_num) fobj.write("numpad5: %d\n" % key_numpad5_num) fobj.write("numpad6: %d\n" % key_numpad6_num) fobj.write("numpad7: %d\n" % key_numpad7_num) fobj.write("numpad8: %d\n" % key_numpad8_num) fobj.write("numpad9: %d\n" % key_numpad9_num) fobj.write("numlock: %d\n" % key_numlock_num) fobj.write("divide: %d\n" % key_divide_num) fobj.write("multiply: %d\n" % key_multiply_num) fobj.write("subtract: %d\n" % key_subtract_num) fobj.write("add: %d\n" % key_add_num) fobj.write("decimal: %d\n" % key_decimal_num) fobj.close() win32api.PostQuitMessage() return True #主函数 if __name__ == "__main__": key_a_num=0 key_b_num=0 key_c_num=0 key_d_num=0 key_e_num=0 key_f_num=0 key_g_num=0 key_h_num=0 key_i_num=0 key_j_num=0 key_k_num=0 key_l_num=0 key_m_num=0 key_n_num=0 key_o_num=0 key_p_num=0 key_q_num=0 key_r_num=0 key_s_num=0 key_t_num=0 key_u_num=0 key_v_num=0 key_w_num=0 key_x_num=0 key_y_num=0 key_z_num=0 key_enter_num=0 key_back_num=0 key_1_num=0 key_2_num=0 key_3_num=0 key_4_num=0 key_5_num=0 key_6_num=0 key_7_num=0 key_8_num=0 key_9_num=0 key_0_num=0 key_oem_3_num=0 key_oem_minus_num=0 key_oem_plus_num=0 key_tab_num=0 key_cap_num=0 key_lshift_num=0 key_lctrl_num=0 key_lwin_num=0 key_lalt_num=0 key_space_num=0 key_rshift_num=0 key_rctrl_num=0 key_rwin_num=0 key_ralt_num=0 key_oem_comma_num=0 key_oem_period_num=0 key_oem_2_num=0 key_oem_1_num=0 key_oem_7_num=0 key_oem_4_num=0 key_oem_5_num=0 key_oem_6_num=0 key_left_num=0 key_right_num=0 key_up_num=0 key_down_num=0 key_delete_num=0 #delete key_end_num=0 #end key_next_num=0 #page down key_insert_num=0 #insert key_home_num=0 #home key_prior_num=0 #page up key_snapshot_num=0 #print screen key_scroll_num=0 #scroll lock key_pause_num=0 #pause key_escape_num=0 key_f1_num=0 key_f2_num=0 key_f3_num=0 key_f4_num=0 key_f5_num=0 key_f6_num=0 key_f7_num=0 key_f8_num=0 key_f9_num=0 key_f10_num=0 key_f11_num=0 key_f12_num=0 key_numpad0_num=0 key_numpad1_num=0 key_numpad2_num=0 key_numpad3_num=0 key_numpad4_num=0 key_numpad5_num=0 key_numpad6_num=0 key_numpad7_num=0 key_numpad8_num=0 key_numpad9_num=0 key_numlock_num=0 key_divide_num=0 key_multiply_num=0 key_subtract_num=0 key_add_num=0 key_decimal_num=0 key_total_num=0 right_up_num=0 left_up_num=0 #打开日志文件 file_name = "D:\\keyboard_recoder\\2018-01-26.txt" fobj = open(file_name, 'w') #创建hook句柄 hm = pyHook.HookManager() #监控鼠标 hm.MouseRightUp=onMouse_rightup hm.MouseLeftUp=onMouse_leftup hm.HookMouse() #监控键盘 hm.KeyUp = onKeyboardEvent hm.HookKeyboard() #循环获取消息 pythoncom.PumpMessages() #关闭日志文件 fobj.close()
上述代码记录了键盘上的每一个按钮敲击的次数,当然不同的键盘所包含的键数不同,还得根据实际情况进行改进。将这段代码保存为.py文件,这样每天在打开电脑后双击运行。在结束使用电脑后按下Pause键退出,即可看到一天的键盘和鼠标点击次数。
data visualization
利用上述程序,我记录了20天鼠标和键盘的敲击的次数,并对数据进行稍微的处理,得到一个Excel表格。
20天内鼠标左键点击了44035下,右键点击了1228下,键盘总共敲击了91960次。Excel表格数据看起来不是很直观,为了更加直观地展示数据,采用Echarts对数据进行简单的可视化处理,即用图表来表示数据。这里选择层叠柱状图来展现20天内每个键位点击的数量,同时也能展现总体的数量。
最后利用热力图最直观地展现敲击次数的键位。
热力图的制作首先从网上找到高清的键盘图作为热力图的地图,然后用像素横纵坐标定义每个键位大概的位置,但是最后结果不是特别好。这里推荐一个网址,可以在线根据文本实时生成键盘键位图,但是似乎只能记录能在屏幕上能打出符号的键位,空格、换行等都无法记录,不过效果的确不错。代码是开源的,大家可以去GitHub下载。实现键盘热力图的大神还有许多有意思的项目,有兴趣的同学可以研究下。
-
https://www.patrick-wied.at/
我的Backspace敲击次数排在第三位,看来准确率有些低呀。大家快去记录一下自己每天要狂敲多少次键盘吧。