【Python RPA】マウス・キーボード操作を同時に検知・取得する方法(pynput)
2020.11.19 /
様々なRPA(Robotic Process Automation)ソフトが販売されており、RPA業界も非常に活気がでているように感じます。
そんなRPAソフトはPythonを使えば簡単なものであれば自作することもできます。
RPAソフトで業務効率化や、いつもの変わらない作業を自動化したいという人はぜひRPAソフトの自作を試してみてください。
RPAソフトを作るには、マウス・キーボード操作を検知し、どういった操作をしたのかを取得する必要があります。
本記事では、マウス操作・キーボード操作を両方とも同時に検知・取得する方法を解説していきます。使用するライブラリはpynputです。
マウス操作もキーボード操作も両方とも検知することができるので、非常に開発できるソフトの幅が広がりますよ。
pynputとは
pynputはマウス操作やキーボード操作などのイベントを検知し、その操作内容を取得できるライブラリです。
検知して取得するだけでなく、マウスやキーボードの操作も行うことができます。
公式サイトは以下になり、英語ですが使い方も詳しく記載されています。
現在のpynputの最新版は1.7.1です。(2020年11月19日現在)
pynputのライセンスはGNU Lesser General Public License v3 (LGPLv3)です。
LGPLに関しては以下記事をご参照ください。
【Python】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オブジェクトを生成します。
マルチスレッド(並列処理)を実現するために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パッケージについて説明している記事はあまりなく、詳しく説明している記事は皆無だったので、今回かなり詳しく解説しました。
その他にも使える機能があれば、随時追記していきます。