はじめに
PythonでRPAを作成する場合、実際に人間が行った操作を記録して、その操作をあとから自動再生できると便利です。
そこで、Pythonのmouseライブラリを使って、人間のマウス操作を検知するレコーダーを作成しました。
最初は単純にマウスのクリック位置を取得するところから始めましたが、徐々に機能を追加し、
- 左クリック
- 右クリック
- 中クリック
- ダブルクリック
- スクロール
- ドラッグ&ドロップ
- 操作間隔の記録
- RPAコードの自動生成
- ライブラリ非依存の
actions.jsonへの保存
まで発展させました。
今回はさらにキーボード入力の記録機能を追加します。
最終的には、特定のRPAライブラリに依存しない操作データを保存し、
人間の操作
↓
操作レコーダー
↓
actions.json
↓
RPAコード生成
├─ PyAutoGUI
├─ mouse
└─ その他のRPAライブラリ
という構成を目指します。
1. これまでのマウス操作レコーダー
これまでのレコーダーでは、Pythonのmouseライブラリを利用してマウスイベントを取得していました。
例えば左クリックをすると、
[DETECT] LEFT_CLICK X=1107, Y=481
のようにリアルタイムで表示します。
最後には、
========================================
Summary
========================================
01. LEFT_CLICK X=1107, Y=481
02. RIGHT_CLICK X=147, Y=610
03. DOUBLE_CLICK LEFT X=163, Y=617
04. LEFT_CLICK X=869, Y=53
05. LEFT_CLICK X=1040, Y=821
========================================
のように操作結果を確認できます。
2. 対応しているマウス操作
現在は以下の操作を検知できます。
| 操作 | Action |
|---|---|
| 左クリック | click |
| 右クリック | click |
| 中クリック | click |
| ダブルクリック | double_click |
| スクロール | scroll |
| 左ドラッグ | drag |
| 右ドラッグ | drag |
| 中ドラッグ | drag |
ドラッグについては、開始位置と終了位置だけでなく、操作時間も記録しています。
例えば、
[DETECT] DRAG_LEFT START X=155, Y=719 -> END X=163, Y=628 duration=1.290s
のように記録します。
3. RPAライブラリに依存しない操作データ
最初は記録した操作から、直接mouseライブラリのコードを生成していました。
例えば、
mouse.click(150, 617)
time.sleep(0.5)
のようなコードです。
しかし、最終的にはPyAutoGUIを使ってRPAを実行することを想定しています。
そこで、
レコーダーはRPA実行ライブラリを知らなくてもよい
という設計に変更しました。
レコーダーは、
人間の操作
↓
ライブラリ非依存のAction
↓
actions.json
までを担当します。
その後、
actions.json
↓
PyAutoGUI Generator
↓
PyAutoGUIコード
のように、別のプログラムでRPAコードを生成します。
この構造にすることで、将来的に複数のRPAライブラリに対応できます。
4. actions.json
操作はactions.jsonに保存します。
例えば、
{
"type": "click",
"button": "left",
"position": {
"x": 1528,
"y": 271
}
}
のように、実行ライブラリに依存しない形式で保存します。
また、操作間隔も記録しています。
{
"type": "click",
"button": "left",
"position": {
"x": 1528,
"y": 271
},
"delay": 1.317
}
これによって、
前の操作から何秒後に次の操作を行ったか
も保存できます。
5. キーボード入力を追加する
マウス操作だけでは、RPAとしてできることに限界があります。
例えば、
テキストボックスをクリック
↓
ユーザー名を入力
↓
Tab
↓
パスワードを入力
↓
Enter
という操作を自動化するには、キーボード入力も記録する必要があります。
そこでPythonのkeyboardライブラリを利用して、キーボードイベントを取得することにしました。
インストールは、
pip install keyboard
です。
6. キーボードActionの設計
キーボード操作については、単純に「キーを押した」という情報だけを保存するのではなく、操作内容によってActionを分けます。
現在は以下の4種類を使用します。
text
key
hotkey
ime
7. 通常の文字入力はtext
通常の文字入力はtextとして保存します。
例えば、
abc
と入力した場合、
{
"type": "text",
"text": "abc"
}
とします。
1文字ずつ、
{
"type": "key",
"key": "a"
}
と保存するのではなく、連続した通常文字を1つのtextにまとめます。
これによってJSONが読みやすくなります。
8. Shiftによる大文字入力
Shiftを押しながら文字を入力した場合は、入力された文字として扱います。
例えば、
Shift + A
の場合、
{
"type": "text",
"text": "A"
}
とします。
これは、
{
"type": "hotkey",
"keys": [
"shift",
"a"
]
}
とするよりも、「何を入力したのか」が分かりやすくなるためです。
9. BackspaceやEnterなど
文字を入力するキーではない特殊キーはkeyとして保存します。
例えば、
Backspace
なら、
{
"type": "key",
"key": "backspace"
}
です。
Enterの場合は、
{
"type": "key",
"key": "enter"
}
となります。
同様に、
- Tab
- Delete
- Insert
- Esc
- 矢印キー
- Home
- End
- Page Up
- Page Down
- F1~F12
などもkeyとして扱います。
10. Ctrl+Cなどのショートカット
Ctrlなどの修飾キーと組み合わせた操作はhotkeyとして保存します。
例えば、
Ctrl + C
なら、
{
"type": "hotkey",
"keys": [
"ctrl",
"c"
]
}
です。
同様に、
Ctrl + V
Ctrl + X
Ctrl + A
Ctrl + S
Ctrl + Z
などもhotkeyとして保存できます。
11. レコーダーの終了キー
レコーダーの終了キーを、
F12
に変更しました。
F12自体は操作Actionとして保存しません。
12. 半角/全角キー
日本語入力では、半角/全角キーも重要です。
現在は半角/全角キーを、
{
"type": "ime",
"action": "toggle"
}
として記録します。
これは、
IMEの状態を切り替える操作
として扱うためです。
13. 日本語入力について
ここは少し注意が必要です。
例えば、
こんにちは
と入力した場合、Windowsでは、
konnitiha
↓
IME変換
↓
こんにちは
という処理が行われます。
現段階では、WindowsのIMEによって最終的に確定された文字列を取得する処理までは実装していません。
そのため、今回のレコーダーでは、まずキーボードから入力された文字を記録します。
例えば、
konnnitiha
と入力した場合、
{
"type": "text",
"text": "konnnitiha"
}
として保存します。
14. キーを押している時間は記録しない
キーボード入力では、キーを押している時間を記録しません。
例えば、
aを3秒間押し続ける
という操作をした場合でも、
aaaaaaaaaaaaaaaaa
のようなキーリピートを、そのまま「17回入力した」と解釈するのは適切ではありません。
OSのキーリピートによって生成された文字数と、人間がRPAとして意図した入力回数は必ずしも一致しないからです。
そのため、
キーを押している時間は今回のAction仕様には含めない
ことにしました。
必要であれば、あとからtextの内容を編集して入力回数を調整できます。
これはRPAの再現性を高めるうえでも重要だと考えています。
15. マウスとキーボードを同じActionとして扱う
ここまでの設計によって、マウスとキーボードの操作を同じactions配列に保存できます。
例えば、
左クリック
↓
ユーザー名入力
↓
Tab
↓
パスワード入力
↓
Enter
なら、
{
"actions": [
{
"type": "click",
"button": "left",
"position": {
"x": 500,
"y": 300
}
},
{
"type": "text",
"text": "username"
},
{
"type": "key",
"key": "tab"
},
{
"type": "text",
"text": "password"
},
{
"type": "key",
"key": "enter"
}
]
}
のように表現できます。
これなら、RPAを実行するライブラリが何であるかをActionデータ側は知る必要がありません。
16. 現在のActionの種類
現在の設計では、概ね以下のように整理しています。
| type | 内容 |
|---|---|
click |
左・右・中クリック |
double_click |
ダブルクリック |
scroll |
スクロール |
drag |
ドラッグ&ドロップ |
text |
通常文字入力 |
key |
Enter、Backspaceなど |
hotkey |
Ctrl+Cなど |
ime |
IME切り替え |
これらはすべて、特定のRPA実行ライブラリに依存しないActionです。
17. 最終的な構成
現在目指している構成は次のようになります。
人間の操作
│
┌─────────┴─────────┐
│ │
マウス キーボード
│ │
└─────────┬─────────┘
↓
操作レコーダー
↓
ライブラリ非依存
Action
↓
actions.json
↓
┌─────────┴─────────┐
│ │
PyAutoGUI生成 その他の生成器
│ │
↓ ↓
RPAプログラム RPAプログラム
この構造にしておけば、将来的に、
- PyAutoGUI
- mouse
- pywinauto
- その他のRPAライブラリ
などに対応できます。
18. 今回の実装で確認できたこと
今回キーボード入力を追加したことで、RPAレコーダーとして必要な基本的な操作をかなりカバーできるようになりました。
マウス
- 左クリック
- 右クリック
- 中クリック
- ダブルクリック
- スクロール
- ドラッグ&ドロップ
キーボード
- 通常文字
- Shiftによる大文字
- Backspace
- Enter
- Tab
- 矢印キー
- ファンクションキー
- Ctrlなどのショートカット
- 半角/全角
さらに、各操作について操作間隔も記録しています。
20. 今後の課題
今後は、レコーダーそのものの機能を増やすだけではなく、actions.jsonを利用したRPA実行側を発展させていきたいと考えています。
例えば、
actions.json
↓
PyAutoGUI Generator
↓
Python RPAコード
というコード生成機能を完成させます。
さらに、
actions.json
↓
画像認識による待機
↓
対象画面が表示されるまで待つ
↓
マウス・キーボード操作
という仕組みも組み合わせたいと考えています。
単純な座標操作だけでは、ウィンドウの表示タイミングや処理速度によってRPAが不安定になるためです。
最終的には、
人間が一度操作する
↓
操作を記録
↓
必要に応じてActionを編集
↓
画像認識による待機などを追加
↓
RPAコードを生成
↓
自動実行
という流れを目指しています。