【Python RPA】マウス・キーボード操作を同時に検知・取得する方法(pynput)

時計 2020.11.19 / 時計

【Python RPA】マウス・キーボード操作を同時に検知・取得する方法(pynput)

様々なRPA(Robotic Process Automation)ソフトが販売されており、RPA業界も非常に活気がでているように感じます。

そんなRPAソフトはPythonを使えば簡単なものであれば自作することもできます。

RPAソフトで業務効率化や、いつもの変わらない作業を自動化したいという人はぜひRPAソフトの自作を試してみてください。

RPAソフトを作るには、マウスキーボード操作を検知し、どういった操作をしたのかを取得する必要があります。

本記事では、マウス操作・キーボード操作を両方とも同時に検知・取得する方法を解説していきます。使用するライブラリはpynputです。

マウス操作もキーボード操作も両方とも検知することができるので、非常に開発できるソフトの幅が広がりますよ。

pynputとは

pynputはマウス操作やキーボード操作などのイベントを検知し、その操作内容を取得できるライブラリです。

検知して取得するだけでなく、マウスやキーボードの操作も行うことができます。

公式サイトは以下になり、英語ですが使い方も詳しく記載されています。

PyPI - pynput –

pynput Package Documentation

現在のpynputの最新版は1.7.1です。(2020年11月19日現在)

pynputのライセンスはGNU Lesser General Public License v3 (LGPLv3)です。
LGPLに関しては以下記事をご参照ください。

pynputのインストール

pynputは外部パッケージなので、pipを使ってインストールします。

pip install pynput

作成するプログラムでpynputを使用する場合は、必ずプログラムの先頭でpynputをインポートしてください。

import pynput

マウス操作の検知ではmouse、キーボード操作の検知にはkeyboardをそれぞれpynputからインポートして使いましょう。

from pynput import mouse, keyboard

マウス操作の検知

pynput.mouseにはマウスの操作や検知をするクラスがあります。
マウス操作の検知にはpynput.mouse.Listenerを使用します。

以下にサンプルプログラムを記します。

# sample1.py
from pynput import mouse

def move(x, y):
    print('マウスポインターは {0} へ移動しました'.format((x, y)))

def click(x, y, button, pressed):
    print('{2} が {0} された座標: {1}'.format(
        'Pressed' if pressed else 'Released',(x, y), button))
    if not pressed:     # クリックを離したら
        return False    # Listenerを止める

def scroll(x, y, dx, dy):
    print('{0} スクロールされた座標: {1}'.format(
        'down' if dy < 0 else 'up',(x, y)))

mouse_listener = mouse.Listener(
    on_move=move,
    on_click=click,
    on_scroll=scroll)
mouse_listener.start()

ここで使用しているmouse.Listenerはthreading.Threadであり、すべてのコールバックはthreadオブジェクトを生成します。

threading.Threadとは

マルチスレッド(並列処理)を実現するためにthreadモジュールは使われ、threadモジュール内のthreading.Thread()関数を用いて、Threadオブジェクトを生成し並列処理を行う

後ほどまた説明しますが、mouse.Listenerがthreading.Threadであるために、マウスとキーボードのイベント検知を同時に行うことができるのです。

サンプルプログラムを起動して、マウス操作をすると以下のように表示がされます。

マウスポインターは (523, 388) へ移動しました
down スクロールされた座標: (374, 221)
up スクロールされた座標: (374, 221)
Button.left が Pressed された座標: (523, 388)
Button.left が Released された座標: (523, 388)

pynput.mouse.Listener()

マウス操作の検知で使用するpynput.mouse.Listenerの構文を以下に示します。

  • class pynput.mouse.Listener(on_move=None, on_click=None, on_scroll=None, suppress=False, **kwargs)
パラメーター 内容
on_move(callable) マウスカーソルの移動が起きたときに呼ばれるコールバック。カーソルの座標(x, y)と一緒に呼ばれる
on_click(callable) マウスボタンがクリックされたときに呼ばれるコールバック。引数(x, y, button, pressed)と一緒に呼ばれる。x, yはカーソル座標、buttonはクリックされたボタン、pressedはボタンが押されたかどうか
on_scroll(callable) マウススクロールイベントが発生したら呼ばれるコールバック。引数(x, y, dx, dy)と一緒に呼ばれる。x, yはカーソル座標、dx, dyはスクロールベクター

検知を終了させる

検知を終了させるにはpynput.mouse.Listenerを止める必要があります。

これを止めるためにはpynput.mouse.Listener.stopを使用するか、StopExceptionを起こすか、コールバックからreturn Falseをする必要があります。

キーボード操作の検知

pynput.keyboardにはキーボードの操作や検知をするクラスがあります。
キーボード操作の検知にはpynput.keyboard.Listenerを使用します。

以下にサンプルプログラムを記します。

# sample2.py
from pynput import keyboard

def press(key):
    try:
        print('アルファベット {0} が押されました'.format(key.char))
    except AttributeError:
        print('スペシャルキー {0} が押されました'.format(key))

def release(key):
    print('{0} が離されました'.format(key))
    if key == keyboard.Key.esc:     # escが押された場合
        return False    # listenerを止める

listener = keyboard.Listener(
    on_press=press,
    on_release=release)
listener.start()

ここで使用しているkeyboard.Listenerはthreading.Threadであり、すべてのコールバックはthreadオブジェクトを生成します。

mouse.Listenerと同じでthreadオブジェクトを生成するため、マルチスレッドが可能になります。

サンプルプログラムを起動して、キーボード操作をすると以下のように表示がされます。

アルファベット t が押されました
't' が離されました
スペシャルキー Key.f4 が押されました
Key.f4 が離されました

pynput.keyboard.Listener()

キーボード操作の検知で使用するpynput.keyboard.Listenerの構文を以下に示します。

  • class pynput.keyboard.Listener(on_press=None, on_release=None, suppress=False, **kwargs)
パラメーター 内容
on_press(callable) キーが押されたときに呼ばれるコールバック。引数(key)と一緒に呼ばれる
on_release(callable) キーが離されたときに呼ばれるコールバック。引数(key)と一緒に呼ばれる

検知を終了させる

検知を終了させるにはpynput.keyboard.Listenerを止める必要があります。

これを止めるためにはpynput.keyboard.Listener.stopを使用するか、StopExceptionを起こすか、コールバックからreturn Falseをする必要があります。

マウス・キーボード操作の両方を検知

マウス・キーボード操作の両方を検知する場合は、マウスイベントの検知とキーボードイベントの検知をマルチスレッド(並列処理)で行います。

以下にマウス・キーボード操作の両方を検知するサンプルプログラムを記載します。

# sample3.py

from pynput import mouse, keyboard

def move(x, y):
    print('マウスポインターは {0} へ移動しました'.format((x, y)))

def click(x, y, button, pressed):
    print('{2} が {0} された座標: {1}'.format(
        'Pressed' if pressed else 'Released',(x, y), button))

def scroll(x, y, dx, dy):
    print('{0} スクロールされた座標: {1}'.format(
        'down' if dy < 0 else 'up',(x, y)))

def press(key):
    try:
        print('アルファベット {0} が押されました'.format(key.char))
    except AttributeError:
        print('スペシャルキー {0} が押されました'.format(key))

def release(key):
    print('{0} が離されました'.format(key))
    if key == keyboard.Key.esc:     # escが押された場合
        mouse_listener.stop()       # mouseのListenerを止める
        keyboard_listener.stop()    # keyboardのlistenerを止める

# mouseのリスナー
mouse_listener = mouse.Listener(
    on_move=move,
    on_click=click,
    on_scroll=scroll)
mouse_listener.start()

# keyboardのリスナー
keyboard_listener = keyboard.Listener(
    on_press=press,
    on_release=release)
keyboard_listener.start()

サンプルプログラムを見ていただくとわかるように、mouseとkeyboardで別々のリスナー(Threadオブジェクト)を生成し、start()を実行してそれぞれのスレッドを起動しています。

2つのスレッド(マウスイベント検知、キーボードイベント検知)が並列で動いているため、両方とも検知できるようになります。

まとめ

マウス・キーボード操作を同時に検知・取得する方法はいかがでしたか。

Pythonのpynputパッケージについて説明している記事はあまりなく、詳しく説明している記事は皆無だったので、今回かなり詳しく解説しました。

その他にも使える機能があれば、随時追記していきます。