§ 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. 深入理解kestrel的应用

    1 前言 之所以写本文章,是因为在我停止维护多年前写的NetworkSocket组件两年多来,还是有一些开发者在关注这个项目,我希望有类似需求的开发者明白为什么要停止更新,可以使用什么更好的方式来替换 ...

  2. 如何让ThreadPoolExecutor更早地创建非核心线程

    最近在项目中遇到一个需要用线程池来处理任务的需求,于是我用ThreadPoolExecutor来实现,但是在实现过程中我发现提交大量任务时它的处理逻辑是这样的(提交任务还有一个submit方法内部也调 ...

  3. kubeadm 默认镜像配置问题引申

    背景: 每次使用功能kubeadm的时候都需要提前准备好镜像,为什么自定义使用的镜像源呢? 在没有翻越围墙时 kubeadm init --kubernetes-version=v1.13.0 --p ...

  4. 获取 ProgramData 之类的环境变量(文件夹路径)的值

    GetEnvironmentVariable Recognized Environment Variables https://docs.microsoft.com/en-us/windows/dep ...

  5. 【DNS域名解析命令】 ping

    ping, ping6 - send ICMP ECHO_REQUEST to network hosts ping命令向网络主机发送ICMP回传请求 详细描述: ping使用ICMP协议强制ECHO ...

  6. Linux下必知必会文件和目录

    转载于:https://blog.51cto.com/xiyuxingxia/2372712

  7. python 类C数组的两种形式:list -->内容可变, tuple --->内容不可变

    python 中的列表相当与 C 中的数组,列表:list 初始化使用[ ], 元组:tuple 初始化使用(): 一.列表list 1 #!/usr/bin/python  2   3 #list初 ...

  8. 如何在linux服务器下快速安装配置Node.js

    简单粗暴,先用xshell或其他软件连接服务器 1.下载(此处版本根据官网版本自己修改) wget https://npm.taobao.org/mirrors/node/v8.9.3/node-v8 ...

  9. vue无法自动打开浏览器

    原文链接: 点我 如果不能自动打开浏览器,是因为没有安装插件. 插件安装的方法1.安装插件,在cmd中输入: $ npm i open-browser-webpack-plugin --save这里的 ...

  10. keras-深度学习处理文本数据

    深度学习用于自然语言处理是将模式识别应用于单词.句子和段落,这与计算机视觉是将模式识别应用于像素大致相同.深度学习模型不会接收原始文本作为输入,它只能处理数值张量,因此我们必须将文本向量化(vecto ...