代码解放双手,用 Python 控制你的输入设备

简介: Python 中提供了很多模块可以用于控制输入设备,像是传统的 win32gui,或者是用于游戏开发的 Pygame。其中 win32gui 更贴切的说是基于 Windows 的编程,它的操作丰富多样,可以获取每个窗口,也可以获取窗口的题柄等。而 Pygame 的长处在于 2D 游戏的开发。而今天要讲的 pynput 则不同,它操作非常简单,而且里面包含的内容也更贴切输入设备,其中非常重要的两个模块就是 mouse 和 keyboard,分别提供了控制鼠标和键盘的类,下面我们就来看看一些具体操作。

前言

Python 中提供了很多模块可以用于控制输入设备,像是传统的 win32gui,或者是用于游戏开发的 Pygame。其中 win32gui 更贴切的说是基于 Windows 的编程,它的操作丰富多样,可以获取每个窗口,也可以获取窗口的题柄等。而 Pygame 的长处在于 2D 游戏的开发。而今天要讲的 pynput 则不同,它操作非常简单,而且里面包含的内容也更贴切输入设备,其中非常重要的两个模块就是 mouse 和 keyboard,分别提供了控制鼠标和键盘的类,下面我们就来看看一些具体操作。

1. 控制鼠标

我们先来安装这个模块,安装起来非常简单,我们直接使用 pip 安装:

pip install pynput

接下来就可以使用该模块了。我们导入 mouse 模块:

from pynput import mouse

在 mouse 模块中提供了一个 Controller 类,该类就是我们的鼠标控制器,我们创建该类的对象就可以鼠标键盘:

from pynput import mouse
# 创建一个鼠标
m = mouse.Controller()

获取了鼠标对象后,我们就可以获取一些属性,或者进行一些操作。

1.1 获取鼠标位置

我们可以获取鼠标的位置信息,也就是当前鼠标所在的坐标:

from pynput import mouse
# 创建一个鼠标
m = mouse.Controller()
# 输出鼠标的位置
print(m.position)

输出结果为一个元组。

1.2 定位鼠标

我们也可以直接修改鼠标的位置:

from pynput import mouse
# 创建鼠标
m = mouse.Controller()
# 将鼠标移动到左上角
m.position = (0, 0)

这种方式是直接定位鼠标,我们还可以根据当前位置移动鼠标。

1.3 移动鼠标

移动鼠标调用的是 move 函数:

from pynput import mouse
# 创建鼠标
m = mouse.Controller()
# 将鼠标移动到左上角
m.move(50, -50)

第一个参数为 x 移动的值,第二个参数为 y 移动的值。

另外一般鼠标上都会有三个控制按钮,左键、右键和滚轮,下面我们看看如何操作它们。

1.4 点击鼠标

我们点击按钮时都会先按下按钮,然后再松开按钮:

from pynput import mouse
# 创建鼠标
m = mouse.Controller()
# 按下鼠标右键
m.press(mouse.Button.right)
# 松下鼠标右键
m.release(mouse.Button.right)

在 mouse 提供了 Button 类,里面内置了左键和右键的常量,我们直接使用就可以了。

除了上面的方法,我们还可以直接调用 click 方法,点击鼠标:

from pynput import mouse
# 创建鼠标
m = mouse.Controller()
# 点击鼠标左键
m.click(mouse.Button.left)

1.5 双击鼠标

双击也是个非常常用的操作,我们同样可以使用 click 方法:

from pynput import mouse
# 创建鼠标
m = mouse.Controller()
# 点击鼠标左键
m.click(mouse.Button.left, 2)

click 方法接收两个参数,第一个为按钮,第二个为非必选参数,含义为点击的次数。

1.6 滚动滚轮

对于像 Excel 表这种大型的表格,我们经常需要上下左右滚动,而 mouse 模块中就提供了这样的方法:

from pynput import mouse
# 创建鼠标
m = mouse.Controller()
# 滚动鼠标,第一个参数为 y 滚动的数值,第二个参数为 x 滚动的数值
m.scroll(0, -10)

1.7 监听鼠标的事件

鼠标中的事件有三个,点击事件、移动事件、滚动事件,我们看看如何监听鼠标的事件:

from pynput import mouse

def on_move(x, y):
    """鼠标移动的监听方法 x,y 为移动后的位置"""
    print('鼠标移动到了{0}'.format((x, y)))

def on_click(x, y, button, pressed):
    """鼠标点击的监听方法 x,y 为坐标,button 为按钮,pressed 为是否是按下"""
    if pressed:
        print('点击了({0}, {1})'.format(x, y))
    else:
        print('鼠标在({0}, {1})松开'.format(x, y))

def on_scroll(x, y, dx, dy):
    """鼠标滚动的监听方法 x,y 为作为,dx,dy 为滚动幅度"""
    print('鼠标在{0}, 向右滚动{1}, 向下滚动{2}'.format((x, y), dx, dy))

# 创建一个监听者
with mouse.Listener(
        # 关联监听方法(不加括号)
        on_move=on_move,
        on_click=on_click,
        on_scroll=on_scroll) as listener:
       # 阻塞线程
    listener.join()

我们的 mouse 模块提供了 Listener 类,该类的对象就是我们的监听者。当我们触发某个事件时,监听者就会执行关联好的方法。

2. 控制键盘

在 pynput 中提供了 keyboard 模块,该模块中提供了与 mouse 模块类似的一些类,这些类可以用于控制键盘。其中 keyboard 中也有一个 Controller 类,该类对象就是我们的键盘控制器。

from pynput import keyboard
# 创建一个键盘
kb = keyboard.Controller()

我们可以通过上述代码创建一个键盘控制器。有了控制器我们就可以操作这个键盘了。

2.1 按下并松开某个键

这里同样是调用 press 和 release 方法:

from pynput import keyboard
# 创建一个键盘
kb = keyboard.Controller()
# 按下 a 键
kb.press('a')
# 松开 a 键
kb.release('a')

上面我们是通过传入字符的方式按按钮,这里智能点击单个字符的按钮。在 keyboard 模块中 Key 类中,提供了大量预设的按钮,我们可以直接使用:

from pynput import keyboard
# 创建键盘
kb = keyboard.Controller()
# 按下大小写锁定
kb.press(keyboard.Key.caps_lock)
# 松开大小写锁定
kb.release(keyboard.Key.caps_lock)

上面就是我们 press 和 release 的用法了。

2.2 按下两个按钮

我们可以通过多次调用 press 的方法按下几个按钮,当然我们还有一种简便写法:

from pynput import keyboard
# 创建一个键盘
kb = keyboard.Controller()
# 按下 shift+a
with kb.pressed(keyboard.Key.shift):
    kb.press('a')
    kb.release('a')

上面的效果就是我们打出了一个 A。

2.3 打字

理论上来说,press 和 release 方法可以完成键盘大多数操作,打字也不例外,但是出于效率的考虑我们可以使用 type 方法:

from pynput import keyboard
# 创建键盘
kb = keyboard.Controller()
# 打字
kb.type('Hello world')

在我们打中文字的时候,输入法并不会影响我们的操作。当时当我们打英文时,如果输入法是中文模式,则会是我们平时打拼音的效果。

2.4 事件监听

键盘的监听同样是由 keyboard 中 Listener 类实现的:

from pynput import keyboard
# 按下按钮
def on_press(key):
    print('按下了{0}'.format(key))
# 松开按钮
def on_release(key):
    print('松开了{0}'.format(key))

# 监听
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()

监听步骤同鼠标一样,这里就不再赘述了。

3. 使用 pynput 完成游戏辅助器

pynput 本身并不具备什么高难度的操作,我们更多的时用它实现一些重复循环的动作,而在玩游戏时,我们刷副本就是一个大量重复的动作。这时候,我们就可以用程序替代我们工作。

我们这里以 PokeMMO 为例,我们先看看游戏本身的键盘分布:

在这里插入图片描述

上面这些键就是我们要操作的一些键。下面我们需要实现自动刷怪的功能。如果对这个游戏不了解的话也不要紧,这里只是将其作为一个例子,重要的是将问题转换成代码的步骤。

3.1 刷怪流程

我们首先要知道整个流程是什么,也就是从第一次开始,到第二次重复这段流程的操作。如果对照 PokeMMO 的话,流程如下:

  1. 第一次的时候自动调整位置,让人物飞到医院
  2. 从医院出发,到野区
  3. 使用技能引出野怪(该技能可以使用四次),并战斗
  4. 循环使用技能引出野怪(四次)
  5. 回医院补充技能值
  6. 在医院门口调整位置

上面就是一次完整的流程,我们将每个流程拆分开慢慢实现。

3.2 将每一个步骤都划成一个流程

除了上面的整体流程外,我们每一个步骤都可以划分为一个具体的流程,也就是一系列操作。比如我们的第一个步骤,我们做如下操作:

  1. 点击宠物
  2. 选择飞空术
  3. 选择城市

这样就把我们的第一个步骤划成了一个流程,我们将每个步骤都封装成一个函数,从小到大,实现完整的流程。

3.3 调整位置、让人物飞医院

我们对照键盘,将这一流程转化为代码:

import time
from pynput import keyboard

# 创建一个键盘
kb = keyboard.Controller()

def fly():
    """定义方法,让人物回到医院"""
    # 选择宠物
    kb.type('3')
    time.sleep(0.5)
    # 选择飞空术
    kb.type('s')
    time.sleep(0.5)
    # 选择城市,因为飞空术花的时间比较长,这里休眠 7 秒
    kb.type('l')
    kb.type('l')
    time.sleep(7)

这样我们就实现了第一个步骤。

3.4 从医院出发,到野区

这个步骤无非就是上下左右键的改变,根据不同路线每个按键按的时长不一样,我们可以将路线封装成一个列表:

# 0,1,2,3 分别表示上右下左
Lmz_weed = [
    # 向左移动 6 秒
    (3, 6),
    # 向上移动 0.4 秒
    (0, 0.4)
]

该列表的元素为元组,每个元组代表一条路线。而元组中的内容则是方向和按下的时长。于是我们通过循环的方式,行走任何路线:

def to_weed(road):
    """根据路线移动"""
    # 使用自行车
    m_keyboard.type('c')
    # 根据线路移动
    for i in road:
        key = None
        if i[0] == 0:
            # 向上移动
            key = Key.up
        elif i[0] == 1:
            # 向右移动
            key = Key.right
        elif i[0] == 2:
            # 向下移动
            key = Key.down
        elif i[0]== 3:
            # 向左移动
            key = Key.left
        # 按下相应方向
        m_keyboard.press(key)
        time.sleep(i[1])
        m_keyboard.release(key)

上面就是我们行走的函数。

3.5 使用技能引出野怪

该步骤可以分为下列流程:

  1. 选择宠物
  2. 使用技能
  3. 攻击宠物
  4. 循环四次

我们将引出宠物和攻击宠物分别封装成两个函数:

def earthquake():
    """使用地震击败怪物"""
    # 使用地震
    m_keyboard.type('f')
    time.sleep(0.5)
    m_keyboard.type('q')
    time.sleep(0.5)
    m_keyboard.type('e')
    time.sleep(37)

def sweet():
    """使用香气甜甜"""
    # 选择第二个宠物使用香甜气息
    m_keyboard.type('2')
    time.sleep(0.5)
    m_keyboard.type('s')
    time.sleep(15)

写出了上面两个函数,我们只需要用一个简单的循环就可以完成整个流程:

for i in range(4):
    # 引出宠物
    sweet()
    # 攻击
    earthquake()

3.6 回医院补充技能值

这需要我们先回到医院,然后进入医院,然后同护士对话:

def to_hospital():
    """去医院"""
    # 选择第三个宠物飞空
    fly()

    # 走进医院
    m_keyboard.press(Key.up)
    time.sleep(7)
    m_keyboard.release(Key.up)

    # 对话
    for i in range(8):
        time.sleep(1.2)
        m_keyboard.type('a')
    time.sleep(1)
    for i in range(3):
        time.sleep(1)
        m_keyboard.type('b')


    # 走出医院
    m_keyboard.press(Key.down)
    time.sleep(7)
    m_keyboard.release(Key.down)
    # 对准宠物位置
    fly()

在对话的时候,我们模拟日常操作,不断按 a,然后不断按 b。

3.7 完整流程

完整流程就是我们用我们的每个步骤依次调用相应的方法,然后整合在一起:

time.sleep(3)
flag = True
while(True):
    """循环刷野怪"""
    if flag:
        to_hospital()
    flag = False
    to_weed(Lmz_weed)
    for i in range(4):
        sweet()
        earthquake()
    to_hospital()

看到这里会有许多困惑的地方,主要原因是对游戏不熟悉。不过这个程序本身不是重点,重点是将整个操作化为一系列流程,然后将某一流程切割成一系列操作,最后通过代码实现这些操作。

4. 总结

哪些情况我们可以用 pynput 帮助我们呢?大量重复的操作,像是消息轰炸就是比较典型的一种操作。另外一些我们人类无法企及的手速,这时候我们就可以用电脑来实现。另外大家可以自己发掘 pynput 的作用。

目录
相关文章
|
6天前
|
Python
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
以下是一些常用的图表类型及其Python代码示例,使用Matplotlib和Seaborn库。
|
4天前
|
Python
? Python 装饰器入门:让代码更灵活和可维护
? Python 装饰器入门:让代码更灵活和可维护
11 4
|
4天前
|
缓存 测试技术 Python
探索Python中的装饰器:简化代码,提高可读性
【9月更文挑战第28天】在Python编程中,装饰器是一个强大的工具,它允许我们在不修改原有函数代码的情况下增加额外的功能。本文将深入探讨装饰器的概念、使用方法及其在实际项目中的应用,帮助读者理解并运用装饰器来优化和提升代码的效率与可读性。通过具体示例,我们将展示如何创建自定义装饰器以及如何利用它们简化日常的编程任务。
10 3
|
3天前
|
机器学习/深度学习 数据格式 Python
将特征向量转化为Python代码
将特征向量转化为Python代码
10 1
|
6天前
|
JavaScript 前端开发 Python
python执行js代码
本文档详细介绍如何安装Node.js环境及PyExecJS库,并提供示例代码展示其功能。首先,通过指定链接安装Node.js,安装完毕后可在命令行中输入`node --version`来验证安装是否成功。接着,使用`pip install PyExecJS`安装PyExecJS库,该库允许Python程序执行JavaScript代码。文档还提供了多个示例代码,展示了如何在Python环境中执行和编译JavaScript代码,并可以选择特定的JavaScript运行时环境,如Node.js或JScript。最后,通过具体案例展示了PyExecJS的功能与使用方法。
14 3
|
7天前
|
Java Linux Python
Linux环境下 代码java调用python出错
Linux环境下 代码java调用python出错
20 3
|
5天前
|
Python
Python 装饰器入门:让代码更灵活和可维护
Python 装饰器入门:让代码更灵活和可维护
10 1
|
6天前
|
Python
5-19|记录Python调用salt代码
5-19|记录Python调用salt代码
|
7天前
|
存储 Python
深度剖析:Python里字典树Trie的构建与查询,让你的代码更优雅!
在编程的世界里,数据结构的选择往往直接决定了程序的效率和可读性。今天,我们将深入探索一种高效处理字符串搜索与匹配的数据结构——字典树(Trie),也称作前缀树或单词查找树。通过Python实现Trie树,我们将看到它如何优雅地解决一系列字符串相关的问题,并提升代码的整体质量。
13 2
|
5天前
|
数据处理 Python
Python切片魔法:一行代码实现高效数据处理
Python切片魔法:一行代码实现高效数据处理
10 0
下一篇
无影云桌面