§ 0.0.0 前言

监听、操作鼠标、键盘是实现自动化的捷径,比如我实现自动化签到用到了模拟键盘操作。

pynput是监听、操控鼠标和键盘的跨平台第三方python库。

你可以通过pip insnall pynput来安装。安装时会自动下载依赖库。

pypi链接在此。

接下来我会按

“鼠标按键”“监听鼠标”“控制鼠标”,“键盘按键”“监听键盘”“控制键盘”

的顺序介绍它的用法。



  • 以下为正文。


§1.0.0 鼠标按键

鼠标的按键在pynput.mouse.Button中,

liftrightmiddle还有unknown四种。

每一个按键都有两个有意义的属性:namevalue

name是该按键的名称,比如 Button.left.name == 'left';

value是记录上一次点击位置的元组。



§1.1.0 监听鼠标

有两种方法,一种是函数式、非阻塞型,另一种是语句式、阻塞型。

先说第一种,这种是常见的教程所说的方法。

§1.1.1 pynput.mouse.Listener

以下是官网的说明示例:

import pynput, time

def on_move(x, y):
print('Pointer moved to {0}'.format((x, y))) def on_click(x, y, button, pressed):
print('{0} at {1}'.format(
'Pressed' if pressed else 'Released',
(x, y)))
if not pressed:
# Stop listener
return False def on_scroll(x, y, dx, dy):
print('Scrolled {0} at {1}'.format(
'down' if dy < 0 else 'up',
(x, y))) # Collect events until released
with pynput.mouse.Listener(
on_move=on_move,
on_click=on_click,
on_scroll=on_scroll) as listener:
listener.join()

运行这段代码时,移动鼠标会显示其坐标,

按下鼠标按键并松开后,程序结束。

  • 当三个函数任意一个返回False((还有就是释放Exception或继承自Exception的异常)时,就会结束进程。
  • 可以用listener.start()listener.stop()代替with语句。

§1.1.2 pynput.mouse.Events

个人认为,这个方法比上一个更直观。

import pynput

with pynput.mouse.Events() as event:

    for i in event:
#迭代用法。
if isinstance(i, pynput.mouse.Events.Move):
#鼠标移动事件。
print(i.x, i.y)
#不要直接打印`i`,模块这里有问题,会报错。 elif isinstance(i, pynput.mouse.Events.Click):
#鼠标点击事件。
print(i.x, i.y, i.button, i.pressed)
#这个i.button就是上文所说的“鼠标按键”中的一个,用is语句判断即可。 elif isinstance(i, pynput.mouse.Events.Scroll):
#鼠标滚轮。
print(i.x, i.y, i.dx, i.dy) break i = event.get(1)
#另一种用法。
#默认值是None。
#这个`1`就是最长等待时间,超过这个时间没有事件,
#就会报错。错误类型是queue模块的Empty,而非TimeoutError。


§1.2.0 控制鼠标

  • § 1.2.1

    先执行pynput.mouse.Controller()获取控件。

    以下方法都是该控件的所属方法。

如下:

import pynput

ctr = pynput.mouse.Controller()

  • § 1.2.2

动态属性position返回鼠标位置坐标的元组(像这样: (x, y) ),

通过定义来改变鼠标位置,比如ctr.position = (500, 500)


  • § 1.2.3

当然,也有move方法,用于移动鼠标

用法是ctr.move(dx, dy)


  • § 1.2.4

使用方法click进行模拟点击,需提供点击的按钮,

按钮在pynput.mouse.Button里,有leftrightmiddle

还有可选参数count,是点击次数,默认为1。

示例:

import pynput

ctr = pynput.mouse.Controller()

ctr.click(pynput.mouse.Button.left)
#左键单击。 ctr.click(pynput.mouse.Button.left, 2)
#左键双击。 ctr.click(pynput.mouse.Button.right)
#右键单击。

  • § 1.2.5

使用press(button)按下button键;

方法release(button)释放键,如果操作时按键并没有被按下,也不会报错。

示例:

import pynput

ctr = pynput.mouse.Controller()

ctr.press(pynput.mouse.Button.left)
#按下左键。 ctr.move(50, 0)
#右移50单位。 ctr.move(0, 50)
#下移50单位。 ctr.release(pynput.mouse.Button.left)
#释放左键。

  • § 1.2.6

模拟滚轮,使用的方法是scroll,提供参数dxdy

例:

import pynput

ctr = pynput.mouse.Controller()

ctr.scroll(0, 50)
#向上滚动50单位。 ctr.scroll(0, -50)
#向下滚动50单位。


  • 以上是鼠标操作,
  • 以下是键盘操作。


§ 2.0.0 键盘按键

键盘的按键获取比鼠标的麻烦些,但是没有鼠标用得多。

因此我先说给常用的使用方法,再说获取


§ 2.0.1 使用方法

首先,当获取事件后,要判断按键是“特殊按键”还是“普通按键”,

需判断其是否具有name属性,有则是特殊按键

这个属性记录属性的名称,比如ctrl对应着'ctrl''ctrl_l'或是'ctrl_r'

普通按键中,取而代之的是.char

注:大写字母与小写字母有不同的按键。

还有其他功能。这里就不多说了。

§ 2.0.2 获取

首先,特殊按键pynput.keyboard.Key“模块”中可以直接找到。

比如ctrl对应pynput.keyboard.Key.ctrl还有.ctrl_l以及.ctrl_r

然后,普通按键可以通过pynput.keyboard.KeyCode.from_char取得(特殊按键不可以,使用时会出现ArgumentError)。

a可以运行pynput.keyboard.KeyCode.from_char('a')获得。

二者都可以用pynput.keyboard.KeyCode.from_vk通过按键的映射码取得。



§ 2.1.0 监听键盘

主要有两种方法,类似于鼠标的,我的讲述顺序同前文。

还有一种是对Listener的封装,用于快捷键,我放在最后一个说。

§ 2.1.1 pynput.keyboard.Listener

注:如果你只想关注个别按键而非所有事件,可以使用GlobalHotKeys。我会在后文说。

官网示例:

from pynput import keyboard

def on_press(key):
'按下按键时执行。'
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
#通过属性判断按键类型。 def on_release(key):
'松开按键时执行。'
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False # Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
  • 当两个函数中任意一个返回False(还有就是释放Exception或继承自Exception的异常)时,就会结束进程。
  • 可以用listener.start()listener.stop()代替with语句。

§ 2.1.2 pynput.keyboard.Events


import pynput with pynput.keyboard.Events() as event: for i in event:
#迭代用法。
key_event = i
break key_event = event.get()
#get用法。
#可以提供一个实数作为最长等待时间(单位秒),超过这个时间没有事件,
#就会报错。错误类型是queue模块的Empty,而非TimeoutError。 #判断事件情况: if isinstance(key_event, pynput.keyboard.Events.Press):
print('按下按键', end = '')
elif isinstance(key_event, pynput.keyboard.Events.Release):
print('松开按键', end = '') #判断按键: #*这个事件的`key`属性*对应才是*Listener方法获得的按键`'key'`*。 try:
print(key_event.key.name)
except AttributeError:
#说明这个是普通按键。
print(key_event.key.char)
else:
#两种判断方式,第一种是我自创的,第二种是官网上的。
if (key_event.key.name).startswith('ctrl'):
#通过名称判断。
print('发生了ctrl键事件。')
elif key_event.key is pynput.keyboard.Key.esc:
print('发生了esc键事件。')

§ 2.1.3 pynput.keyboard.GlobalHotKeys

(还有'pynput.keyboard.HotKey'可以实现相似功能,但很麻烦)

官网示例,esc那个是我写的。

from pynput import keyboard

def on_activate_h():
print('<ctrl>+<alt>+h pressed') def on_activate_i():
print('<ctrl>+<alt>+i pressed') def esc():
print('<esc> pressed')
return False def esc_shift():
print('<esc>+<shift> pressed')
raise Exception with keyboard.GlobalHotKeys({
'<ctrl>+<alt>+h': on_activate_h,
'<ctrl>+<alt>+i': on_activate_i,
'<esc>': esc,
'<esc>+<shift>': esc_shift}) as h:
h.join()

当按下esc键时,函数被触发,但运行未停止。

观察源码,发现虽然该类继承自Listener,但会对执行的函数有封装,封装后只返回None。

所以无法通过return False结束进程。

设置单个普通按键(比如“a”)也是可以的。

不能分辨按键顺序如“<ctrl>+a”与“a+<ctrl>”。



§ 2.2.0 控制键盘

  • § 2.2.1

先获取控件 :ctr = pynput.keyboard.Controller()

以下所说的方法均是指该控件的方法。


  • § 2.2.2

通过方法press按下按键

你需要提供一个“长度为1的字符”或是“前文所说的按键对象”。

温馨提示,此方法测试有风险,如果发现电脑打字、操作异常,

很可能是因为模拟按下了某个键未松开。

可以重启控制台或电脑。


  • § 2.2.3

通过release释放按键

和press方法一样,需要提供一个“长度为1的字符”或是“前文所说的按键对象”。

示例:

'''
这段程序会按“下ctrl+shilf+s”快捷键,停顿3秒后按下esc键。
简单模拟了“另存为”操作。
''' import pynput, time ctr = pynput.keyboard.Controller() ctr.press(pynput.keyboard.KeyCode.from_vk(17))
#通过按键的映射码 按下ctrl键。 ctr.press(pynput.keyboard.Key.shift)
#通过按键对象 按下shift键。 ctr.press('s')
#通过长度为1的字符 按下s键。 #扫尾,释放刚才按下的键。后面我会说更简单、优雅的办法。
ctr.release(pynput.keyboard.Key.ctrl)
ctr.release(pynput.keyboard.Key.shift)
ctr.release('s') time.sleep(0.3) ctr.press(pynput.keyboard.Key.esc)
ctr.release(pynput.keyboard.Key.esc)

  • § 2.2.4

pressed方法就是我说的“更简单、优雅”的方法。

使用时提供要按下的键,再用with语句“封装”上。

效果是进入语句块时顺序按下提供按键,退出语句块时逆序释放按键。

如下:

import pynput, time

ctr = pynput.keyboard.Controller()

with ctr.pressed(
pynput.keyboard.Key.ctrl,
pynput.keyboard.Key.shift,
's'):
pass time.sleep(0.3) with ctr.pressed(pynput.keyboard.Key.esc):
pass

  • § 2.2.5

type在英语中除了“类型”还有“打字”之意。

该方法接收字符串,然后打出每个字符。

据测试,向它提供一个“按键列表”也可以正常使用。

例:

import pynput

ctr = pynput.keyboard.Controller()

ctr.type('Hello world!')

ctr.type([pynput.keyboard.Key.esc])
#按下esc再松开。


  • 以上是正文。


一些建议

该模块鼠标、键盘的监听操作均由多线程实现。

所以,可以利用多线程共享内存的特征编程;二要注意不要频繁启动监听,这样对系统开支极大。

还有就是对鼠标位置监听要求不是很高时(比如实时向用户显示鼠标位置),可以每次循环sleep一下。

如果向Listener提供的函数会执行很久(比如含有sleep),会导致电脑变卡。

闲谈

之前和别人聊天,他说他在不需要时把电脑的麦拔下来、摄像头挡上。

我说用Fn快捷键禁掉麦克风更方便。

现在想想,黑客可以通过模拟按键解禁麦克风啊。

虽然这个模块没有Fn键,但别的呢?

最后

这份算是最全的了。原创不易,纯手打。

转载请注明作者和链接哦。

感谢阅读!

python监听、操作键盘鼠标库pynput详细教程的更多相关文章

  1. 用Python监听鼠标和键盘事件

    PyHook是一个基于Python的“钩子”库,主要用于监听当前电脑上鼠标和键盘的事件.这个库依赖于另一个Python库PyWin32,如同名字所显示的,PyWin32只能运行在Windows平台,所 ...

  2. 转载:python + requests实现的接口自动化框架详细教程

    转自https://my.oschina.net/u/3041656/blog/820023 摘要: python + requests实现的接口自动化框架详细教程 前段时间由于公司测试方向的转型,由 ...

  3. python + requests实现的接口自动化框架详细教程

    前段时间由于公司测试方向的转型,由原来的web页面功能测试转变成接口测试,之前大多都是手工进行,利用postman和jmeter进行的接口测试,后来,组内有人讲原先web自动化的测试框架移驾成接口的自 ...

  4. 使用python监听、模拟鼠标键盘事件

    最近守望职业选手疑似开挂事件挺热闹的,在下小菜一枚,并不能从视频中看出端倪.看了一些关于外挂的讨论,自动点射和压枪只需在鼠标驱动上做些改动即可,自瞄或其他高级功能则需要读内存或修改游戏文件,检测也更容 ...

  5. pyHook监听用户鼠标、键盘事件

    一.代码部分:获取用户输入信息,并与截图一起保存到XX目录下   # -*- coding: utf-8 -*- #   import pythoncom import pyHook    impor ...

  6. 事件监听机制——鼠标事件MouseEvent

    鼠标事件 鼠标事件包括鼠标的双击.左击.右击.中间键等等,本文进行事件加载进行简单介绍,具体可以参考键盘事件. import java.awt.*; import java.awt.event.*; ...

  7. PostgreSQL数据库服务端监听设置及客户端连接方法教程

    众所周知,PostgreSQL 是一个自由的对象-关系数据库服务器(数据库管理系统),是一个可以免费使用的开放源代码数据库系统.本文详细介绍了PostgreSQL数据库服务端监听设置及客户端连接方法, ...

  8. python监听鼠标和键盘

    import PyHook3 def OnMouseEvent(event): print('MessageName:',event.MessageName) print('Message:',eve ...

  9. JavaScript-4.6鼠标事件监听,获取鼠标坐标window.event---ShinePans

    <html> <head> <meta http-equiv="content-type" content="text/html" ...

随机推荐

  1. Python 开发工具链全解

    可能刚开始学习Python时,有人跟你说可以将源文件所在的文件夹添加到 PYTHONPATH环境变量中,然后可以从其他位置导入此代码.在大多数情况下,这个人常常忘记补充这是一个非常糟糕的主意.有些人在 ...

  2. Task启动方式及源码探究

    启动Task有几种方式: 1.Task.Run() 2.new TaskFactory.StartNew() 3.var t=new Task();  t.start(); 平时用的最多是第一和第二种 ...

  3. Linux系统管理第六次作业 进程和计划任务管理

    1.通过ps命令的两种选项形式查看进程信息 [root@localhost ~]# ps aux USER        PID %CPU %MEM    VSZ   RSS TTY      STA ...

  4. Android Studio常用配置

    目录 1. 主题颜色设置 2. Logcat颜色设置 3. 类注释 4. 编译器添加背景图 4.1 第一种方式 Background Image 4.2 第二种方式 Sexy Editor 5. 修改 ...

  5. web 之 tomcat 8.5 和9.0如何进入manager?

    tomcat 8.5 和9.0如何进入manager? 第一步找到tomcat-user.xml文件 第二步添加如下代码 <role rolename="manager-gui&quo ...

  6. 常用的CSS小技巧

    实际开发过程中会遇到一些需要用CSS小技巧处理的布局问题,现在分享几个个人工作中遇到的小问题和解决方案. 1.inline元素间的空白间隙 这里要介绍一个神器font-size:0. 如果你写了个列表 ...

  7. Microsoft Dynamics CRM 2015 服务器系统的性能维护,追踪, 也可以用到任务管理器哟...

    Microsoft Dynamics CRM 2015 的追踪是一个很有用的function,它能为我们的CRM调试,评估 提供有价值的信息:我们可以用window的性能监控工具来了解CRM的性能状态 ...

  8. INTERVIEW #3

    菊厂的面试本来没打算记录,因为当时投的是非技术岗(技术支持).为了全面,就寥做记录. 菊厂的面试因为有口头保密协议,所以不能透露具体题目. 0 群面 简历通过筛选后,会有短信通知去面试. 非技术岗第一 ...

  9. Codeforce-CodeCraft-20 (Div. 2)-B. String Modification (找规律+模拟)

    Vasya has a string s of length n. He decides to make the following modification to the string: Pick ...

  10. 刷新DNS解析缓存+追踪+域名解析命令

    刷新DNS解析缓存 命令:ipconfig /flushdns 用于改完host之后. 追踪IP: 命令:tracert www.baidu.com 域名解析: 命令:nslookup www.bai ...