【自動化】Pythonでマウスとキーボードを操る

##マウス/キーボード操作を自動化したいのはどんなとき？

PythonではExcelなどの「ファイル」やウェブブラウザなどの「アプリ」を直接操作することが比較的簡単にできます。

なので、マウス操作やキーボード入力を自動化したいことなんてあるの？と思われる方もいるかもしれません。

世の中にはたくさんのアプリ、ソフトが存在します。フリーソフトまで含めればそれこそ星の数ほど存在しています。
さすがのPythonもそれらのアプリのすべてに対応しているわけではありません。
Pythonで**直接操作することができないアプリ**もたくさんあるのです。

そのようなアプリでの作業を自動化したいケースでは、**マウスとキーボードの操作を自動化する**ことで対応できます。

そもそも人間がアプリを操作するときは、マウスとキーボードで操作するわけですから、マウスとキーボードをPythonで操ることができれば理屈の上では何でも自動で操作できるはずです（たぶん）。

というわけで、本記事ではPythonでマウスとキーボードを操作する方法を紹介します。

##PyAutoGUIで自動化する

Pythonでマウスとキーボードを操作するには**PyAutoGUI**というライブラリを使います。

pyautoguiはAnacondaでもデフォルトではインストールされていないはずなので、まずpipコマンドでインストールしましょう。

```
pip install pyautogui
```

無事インストールできたら、インポートします。

```python:python
import pyautogui
```

##マウス操作

###クリック
マウスの左クリックは`pyautogui.click()`で行います。

このとき、どこをクリックするかということなのですが、次の3パターンでクリック位置を指定できます。

|関数|説明|
|---|---|
|pyautogui.click()|**現在のマウスカーソル位置**をクリック|
|pyautogui.click(x, y)|**モニター上の座標(x, y)の位置**をクリック|
|pyautogui.click('button.png')|**クリックしたいボタンの画像**を指定してそこをクリック|

詳しく説明しますね。


####pyautogui.click()


現在のマウスカーソルの位置をクリックします。
この場合、後述するマウスカーソルを移動するコマンド`pyautogui.moveTo()`や`pyautogui.move()`で、まずマウスカーソルを所望の位置に移動させてから`pyautogui.click()`ということになると思います。

```python:python
# (100, 200)の位置にマウスカーソルを移動
pyautogui.moveTo(100,200)

# クリック
pyautogui.click()
```

####pyautogui.click(x, y) 

モニター上の座標(x, y)の位置をクリックします。
この座標(x,y)とは何かというと、例えば、あなたのモニターの解像度が1920 x 1080なら左上が(0,0)、右下が(1919, 1079) です。

```
0,0       X increases -->
+---------------------------+
|                           | Y increases
|                           |     |
|   1920 x 1080 screen      |     |
|                           |     V
|                           |
|                           |
+---------------------------+ 1919, 1079

(PyAutoGui公式ドキュメントから転載 <https://pyautogui.readthedocs.io/en/latest/mouse.html>)
```

`pyautogui.position()`で現在のマウスカーソルの座標を取得できるので、
クリックしたい位置にマウスを合わせて`pyautogui.position()`を実行して座標を確認するのが楽です。

```python:python
# クリックしたい位置の座標を確認
print(pyautogui.position())
```

```:実行結果
Point(x=207, y=528)
```

```python:python
# 上記でわかった座標をクリック
pyautogui.click(207, 528)
```

####pyautogui.click('button.png')

クリックしたいボタンの画像('button.png')を指定してクリックします。
アプリのウィンドウの大きさや位置などにより、必ずしもクリックしたい場所の座標が毎度同じ位置とは限りません。

そんなとき、**クリックしたい場所（ボタンなど）の画像**を指定することでその位置を直接クリックできます。

Windowsの「ペイント」アプリで**「☆」の図形**をクリックしたいとします。

![paint_star.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/5e1b875d-59a1-9666-4371-65edc37059b2.png)

この場合、☆の部分を画像として切り出しておきます('star.png')。

![star.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/fb7e2a9e-00cd-c4c7-8877-c7af5d4e5f4b.png)

```python:python
# ☆の部分をクリック
pyautogui.click('star.png')
```

この画像を指定する方法は大変便利なのですが、場合によっては画像の場所を認識できないこともあります。
百発百中ではない点に注意が必要です。


####クリックの種類
`pyautogui.click()`は通常の**左クリック**でした。
右クリックやダブルクリックなど別のクリックをしたい場合は下記のように対応する関数に置き換えましょう。

|クリックの種類|関数|
|---|---|
|右クリック|pyautogui.rightClick()|
|中クリック(ホイールクリック)|pyautogui.middleClick()|
|ダブルクリック|pyautogui.doubleClick()|

###マウスカーソルの移動
マウスカーソルの移動には2種類あります。
移動先の指定が絶対位置か相対位置かの違いです。

|関数|説明|
|---|---|
|pyautogui.moveTo(x,y)|モニター上の座標(x,y)を指定して、そこに移動|
|pyautogui.move(x,y)|現在位置から横にx,縦にyだけ移動する|

####pyautogui.moveTo(x,y)
モニター上の座標(x,y)を指定して、そこに移動します。現在位置がどこかは関係ありません。

`moveTo()`の第3引数として**移動にかける時間**を指定することもできます。
時間指定がないと一瞬で移動しますが、この時間指定によりゆっくり移動させることができます。

```python:python
# (100,100)の位置に移動
pyautogui.moveTo(100,100)

# (100,100)の位置に2秒かけて移動
pyautogui.moveTo(100,100,2)
```

####pyautogui.move(x,y)
現在のマウスカーソルの位置から横にx,縦にyだけ移動します。
`move()`も移動にかける時間を指定できます。

```python:python
# 現在位置から(100,100)だけ移動
pyautogui.move(100,100)

# 現在位置から(100,100)だけ2秒かけて移動
pyautogui.move(100,100,2)
```

###ドラッグ
ドラッグも移動先の絶対位置か相対位置かの違いで2種類あります。
ドラッグも第3引数に**ドラッグにかける時間**を指定することができます。

|関数|説明|
|---|---|
|pyautogui.dragTo(x,y)|現在位置からモニター上の座標(x,y)までドラッグ|
|pyautogui.drag(x,y)|現在位置から横にx,縦にyだけドラッグ|

```python:python
# 現在位置から(100,100)の位置まで2秒かけてドラッグ
pyautogui.dragTo(100,100,2)
```

##キーボード操作

###文字入力
キーボードから文字入力するには`pyautogui.write()`を使います。

実際には、一度文字入力したいテキストボックスなどをクリックして、
文字カーソルをアクティブにしてから`pyautogui.write()`を実行することになると思います。

```python:python
# 文字入力したい場所をクリック
pyautogui.click(100, 100)

# 文字入力
pyautogui.write('Hello world!')
```

何らかの事情であまり高速で入力したくないときは引数に`interval=xx`で文字入力間の秒数を指定すると、文字入力に間隔を空けることもできます。

```python:python
#1文字ごとに0.25秒の間隔で入力
pyautogui.write('Hello world!', interval=0.25)
```

注意点ですが、この方法では**日本語入力ができない**です！
なので、日本語を入力する場合は別の方法を使います。

その方法は、**一度入力したい文字列をクリップボードにコピーして貼り付けます。**

クリップボードを操作するには**pyperclip**を使います。
pyperclipの詳しい使い方は下記をご覧いただくとして、ここではコードだけ記載しておきます。

【自動化】Pythonでクリップボードを操作してExcelに表を貼り付ける
https://qiita.com/konitech913/items/83975332e395a387eace

```python:python
import pyperclip

# 入力した文字列をクリップボードにコピー
pyperclip.copy('こんにちは、世界！')

# Ctrl+vで貼り付け
pyautogui.hotkey('ctrl', 'v')
```

###キー入力
文字を入力するのではなく、単にキーを押したい場合は`pyautogui.press()`を使います。

```python:python
#「Enterキー」を押す
pyautogui.press('enter')

#「左カーソルキー」を4回押す
pyautogui.press(['left', 'left', 'left', 'left'])
```

「Ctrl+C(貼り付け)」や「Ctrl+Z(元に戻す)」などの**ホットキー**については`pyautogui.hotkey()`で指定します。

```python:python
# 「Ctrl+Z(元に戻す)」
pyautogui.hotkey('ctrl', 'z')
```

##ペイントを自動化する
では、最後にここまでの知識を使って、Windows付属の「ペイント」でお絵かきをしてみましょう。

☆の図形を大きさを変えて5つ重ね、最後にテキストで文字を入力してみます。

```python:python
# まず座標を把握
print(pyautogui.position()) # テキストを貼り付けたい位置
print(pyautogui.position()) # ☆のドラッグ開始位置
```

```:実行結果
Point(x=300, y=285)
Point(x=476, y=566)
```

座標がわかったら、いよいよお絵かきしていきます。

```python:python
import pyautogui
import pyperclip

#ペイントのウィンドウをアクティブにするために一度クリック
pyautogui.click(732,22)

text_x=300
text_y=285

star_x=476
star_y=566

# ☆の描画
stride = 50 # ☆をstride分だけ大きくしていく
star_num = 5 # ☆の数

pyautogui.click('star.png')

# ☆をstart_numの数だけ描く
for i in range(star_num):
    pyautogui.moveTo(star_x-stride*i, star_y-stride*i, 1)
    pyautogui.drag(50+stride*i*2, 50+stride*i*2, 1)
    
# テキストの入力
pyautogui.click('text.png')

pyautogui.click(text_x, text_y)
pyperclip.copy('まるでスターのマトリョーシカだぜ…') # 日本語は一旦クリップボードにコピー
pyautogui.hotkey('ctrl', 'v') # 貼り付け
```

**実行結果**

![pyautogui_demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/d457ddc2-d6cb-794c-f601-c706b33fc9b1.gif)


どうでしたか？
pyautoguiを使いこなせると様々なアプリの自動化に応用が効きそうですね。

## 参考
私の書いた他の自動化シリーズはこちらです。ご興味があればどうぞ！

【自動化】PDF内の表をPythonで抜き出す
https://qiita.com/konitech913/items/4ef70e1f7753c824b40f

【自動化】PythonでWordの文書を読み取る
https://qiita.com/konitech913/items/c30236bdf47775535e2f

【自動化】Pythonコードをexeファイル化する
https://qiita.com/konitech913/items/6259f13e057bc25ebc23

【自動化】PythonでOutlookメールを送信する
https://qiita.com/konitech913/items/51867dbe24a2a4272bb6

【自動化】PythonでOutlookのメールを読み込む
https://qiita.com/konitech913/items/8a285522b0c118d5f905

【自動化】Pythonでメール(msgファイル)を読み込む
https://qiita.com/konitech913/items/fa0cf66aad27d16258c0

【自動化】Pythonでクリップボードを操作してExcelに表を貼り付ける
https://qiita.com/konitech913/items/83975332e395a387eace