[Python] pyautoguiを使ってみる

pyautogui

pyautoguiはPythonのGUI自動化モジュールです。

Welcome to PyAutoGUI’s documentation!

これを読んで使ってみようと思いました。

「写経」を自動化し、オートで功徳を積める仕組みを作ってみたのでございます。

使い方は、以下の記事がとてもきれいにまとめてくれてます。

PyAutoGuiで繰り返し作業をPythonにやらせよう

windows10の環境で、公式のドキュメントを最初から進めていったところ、計算機のところで、画像を認識せずに進めなくなったので、その解決策をメモしておきます。

pyautoguiの画像認識

pyautoguiには、実行時のスクリーンショットの画像とあらかじめ用意していた画像を比較して、一致している場所を返す、またはその箇所にマウスを移動する関数が用意されています。

ちなみに、windows10では、’windows印のキー + shift + s’ のショートカットで、範囲を指定したスクリーンショットが取得できます。

例えばwindows10で、左下のwindowsマークのスクリーンショットを取って、windows_logo.pngという名前で保存します。

インタラクティブモードで下記のコードを実行します。

>>> import pyautogui
>>> pyautogui.locateCenterOnScreen('windows_logo.png')
Point(x=23, y=1061)
>>> pos = pyautogui.locateCenterOnScreen('windows_logo.png')
>>> pyautogui.click(pos)

pyautoguiが画面上のwindowsマークを認識してその場所をクリックするので、windowsのメニューが開きます。

pyautoguiで電卓アプリを動かしてみる

公式ドキュメントでは、計算機の例が示されていますが、windows10では以下のエラーが出てしまい、画像が認識でできません。

電卓アプリを起動して、画像を切り出します。

key_7.png
key_multiple.png
key_8.png

windowsマークと同じように認識させようとしてみますが、エラーが出てしまいます。

>>> pyautogui.locateCenterOnScreen('key_7.png')
Traceback (most recent call last):
# 省略
TypeError: 'NoneType' object is not subscriptable

解決策1 背景の透過をオフにする

windows10の仕様でアプリは背景を透過しているそうで、これが画像を正しく認識できない原因のようです。

下記の方法に従って背景の透過をオフにすることで、画像は正しく認識されpyautoguiが正しく動作するようになります。

Windows 10 電卓の背景の透過をオフにする方法

>>> pos_seven = pyautogui.locateCenterOnScreen('key_7.png')
>>> pyautogui.click(pos_seven)
>>> pos_multi = pyautogui.locateCenterOnScreen('key_multiple.png')
>>> pyautogui.click(pos_multi)
>>> pos_eight = pyautogui.locateCenterOnScreen('key_8.png')
>>> pyautogui.click(pos_eight)
>>> pyautogui.press('enter')
>>>

上から順番に実行すると、電卓アプリがちゃんと動いて56が出力されます。

解決策2 画像認識の精度を下げる

pyautoguiの画像認識は、以下のモジュールが使われており、confidenceで画像の精度が変更できそうです。

https://github.com/asweigart/pyscreeze/blob/master/pyscreeze/__init__.py#L131

opencvをインストールします。

$ pip install opencv-python

下記を実行してみます。

>>> pyautogui.click(pyautogui.locateCenterOnScreen('key_7.png', confidence=0.8))
>>> pyautogui.click(pyautogui.locateCenterOnScreen('key_multiple.png', confidence=0.8))
>>> pyautogui.click(pyautogui.locateCenterOnScreen('key_8.png', confidence=0.8))
>>> pyautogui.press('enter')

こちらもちゃんと動作しました。

ちゃんと実行できるようになったので、コードにまとめておきます。

import subprocess
import time
import pyautogui

subprocess.Popen('calc')

time.sleep(5)

pyautogui.click(pyautogui.locateCenterOnScreen('key_7.png', confidence=0.8))
pyautogui.click(pyautogui.locateCenterOnScreen('key_multiple.png', confidence=0.8))
pyautogui.click(pyautogui.locateCenterOnScreen('key_8.png', confidence=0.8))
pyautogui.press('enter')

エラーが出なくなった良かった…。