ちょっと流行っているのでPyAutoGUIをやってみる。意地になってみた。
では、さっそく。
VSCodeを起動。ViewからTerminalを出して、
D:\ProgramFiles\Python\Python39\Scripts\pip3 install pyautogui
を実行(うちのPCにはいろんなpythonがいらっしゃるので、フルパスで指定しています)。
すると、
Successfully installed PyTweening-1.0.4 mouseinfo-0.1.3 pyautogui-0.9.53 pygetwindow-0.0.9 pymsgbox-1.0.9 pyperclip-1.8.2 pyrect-0.1.4 pyscreeze-0.1.28
となり、インストールされたようです。
さらに、たぶんいると思うので、
D:\ProgramFiles\Python\Python39\Scripts\pip3 install pywin32
を実行。
で、
Successfully installed pywin32-302
ってなるので、インストール出来たようです。
画像認識をするのにOpenCVなるものがあったほうがいいらしいので、
D:\ProgramFiles\Python\Python39\Scripts\pip3 install opencv-python
を実行。
で、
Successfully installed opencv-python-4.5.4.60
ってなるので、インストールできたようです。
Requirement already satisfied: numpy>=1.19.3 in ...
ともいっているので、OpenCVにはnumpy必要らしいです。
さて、今回の目標は
下リンクのpdfで、全ページにおいて、リナックスペンギンの横に自分の署名をして、Windowsロゴの横にバツをつける。
ってことにします。
では、じゃんじゃんやります。
pywin32のwin32guiでAcrobatReaderのハンドルを取得します。画像を認識させるので前面に持ってくる必要があるからです。
方法1
filename='2021-12-15_pyAutoGUI_testdocument1.pdf'
appindicator=' - Adobe Acrobat Reader DC (64-bit)'
handle_adobe_acrobat=win32gui.FindWindow(None,filename+appindicator)
win32gui.SetForegroundWindow(handle_adobe_acrobat)
方法2(こんな方法もあるというメモ程度)
def forground( hwnd, title):
name = win32gui.GetWindowText(hwnd)
if name.find(title) >= 0:
# 最小化していたら表示させる
if win32gui.IsIconic(hwnd):
win32gui.ShowWindow(hwnd,1) # SW_SHOWNORMAL
win32gui.SetForegroundWindow(hwnd)
return
win32gui.EnumWindows( forground, 'Adobe Acrobat')
handle_adobe_acrobat=win32gui.GetForegroundWindow()
方法2だとウィンドウタイトルの一部の文字列で探し出すことができます。前面に持ってくるのが必須の場合はいいですが、その必要がない場合(そういうシチュエーションがあるかどうかはわかりませんが)はじゃまくさいことこの上ないです。方法1ならSetForegroundWindowをしなければいいだけ。方法1の面倒なところは、ウィンドウタイトルで探すので、ウィンドウタイトルを正確に知っている必要があることです。
さて後はKEYを送ったり、クリックしたりするだけです。
UWSCだと狙ったWindowハンドル(UWSCではidと言っていた)に指示を出せますが、PyAutoGUIではそれができない。pywin32ではSendMessageとか使えばできそうだけどクソめんどくさそう。今のところAcrobatが前面にある前提なのでPyAutoGUIで単にキーを送ることにします。狙ったハンドルに送れるのなら前面に持ってくる必要ないのですが、、、いけてないけどしょうがない。
ペンギンさんと窓ロゴを認識させるのですが、拡大縮小でマッチングしてくれないらしいので、毎回同じ表示になるようにします。まぁ表示倍率を指定するだけです。
pyautogui.hotkey('ctrl', 'y')
pyautogui.write('50%')
pyautogui.hotkey('\n')
これで、50%表示になります。
Acrobatにキーを送って、表示倍率設定のダイアログを出して設定しています。一瞬で終わるのでダイアログが見えないです。
さて、署名を押すところですが、まずペンギンさん用の署名は事前に「署名を追加」で登録しておきます。
さて、署名をおすのはキー操作でやるのはなかなかハードルが高い(ていうかムリ?)ので、イメージマッチングで座標を取得してクリックします。アイコンの画像は前もってsnipとかでとっておきます。でも、これってウィンドウズのテーマとか変えたりすると見た目が変わっちゃうので、、、どうなの?やっぱりRPAって「これで自動化できますっ」って汎用的なものを作るのには向いてないよなー。繰り返しがクソ面倒くさいと思ったときにちゃっちゃっとやるもんでしょ!!
で、前もってsnipした画像はこいつらです。署名は原本を「署名を追加」して、PyAutoGUIで探すときは実際にAcrobatの画面に表示されたものをsnipしたものを使います。
こいつらを探してクリックするのはこうします。実際に自分で操作するとわかりますが、署名を画像からバツに切り替えるときはなぜかバツを2回押す必要があるので、その通りに操作しています。
icon_sign_location = pyautogui.locateCenterOnScreen('img/icon_sign.png', grayscale=True, confidence=0.8)
pyautogui.click(icon_sign_location.x,icon_sign_location.y)
time.sleep(2)
hogehoge_sign_location = pyautogui.locateCenterOnScreen('img/selected_hogehoge_sign.PNG', grayscale=True, confidence=0.8)
pyautogui.click(hogehoge_sign_location.x,hogehoge_sign_location.y)
time.sleep(2)
penguin_location = pyautogui.locateCenterOnScreen('img/penguin.PNG', grayscale=True, confidence=0.8)
pyautogui.click(penguin_location.x-50,penguin_location.y)
time.sleep(2)
sign_batu_location = pyautogui.locateCenterOnScreen('img/icon_sign_batu.png', grayscale=True, confidence=0.8)
pyautogui.click(sign_batu_location.x,sign_batu_location.y)
time.sleep(1)
pyautogui.click(sign_batu_location.x,sign_batu_location.y)
time.sleep(1)
windows_location = pyautogui.locateCenterOnScreen('img/windows.PNG', grayscale=True, confidence=0.8)
pyautogui.click(windows_location.x-80,windows_location.y)
time.sleep(2)
押した後の待ち時間とか、環境や別プロセスの負荷によって変わるので安全を見て2秒です。
で、あとはページをめくるので、
pyautogui.hotkey('right')
とする。
これをページ数分繰り返せばいい。
できたコードは、
- import pyautogui
- import win32gui
- import time
- filename='2021-12-15_pyAutoGUI_testdocument1.pdf'
- appindicator=' - Adobe Acrobat Reader DC (64-bit)'
- handle_adobe_acrobat=win32gui.FindWindow(None,filename+appindicator)
- win32gui.SetForegroundWindow(handle_adobe_acrobat)
- #l,t,r,b = win32gui.GetWindowRect(handle_adobe_acrobat)
- #region_adobe_acrobat=(l, t, r-l, b-t)
- for i in range(6):
- print(i)
- pyautogui.hotkey('ctrl', 'y')
- pyautogui.write('50%')
- pyautogui.hotkey('\n')
- icon_sign_location = pyautogui.locateCenterOnScreen('img/icon_sign.png', grayscale=True, confidence=0.8)
- pyautogui.click(icon_sign_location.x,icon_sign_location.y)
- time.sleep(2)
- hogehoge_sign_location = pyautogui.locateCenterOnScreen('img/selected_hogehoge_sign.PNG', grayscale=True, confidence=0.8)
- pyautogui.click(hogehoge_sign_location.x,hogehoge_sign_location.y)
- time.sleep(2)
- penguin_location = pyautogui.locateCenterOnScreen('img/penguin.PNG', grayscale=True, confidence=0.8)
- pyautogui.click(penguin_location.x-50,penguin_location.y)
- time.sleep(2)
- sign_batu_location = pyautogui.locateCenterOnScreen('img/icon_sign_batu.png', grayscale=True, confidence=0.8)
- pyautogui.click(sign_batu_location.x,sign_batu_location.y)
- time.sleep(1)
- pyautogui.click(sign_batu_location.x,sign_batu_location.y)
- time.sleep(1)
- windows_location = pyautogui.locateCenterOnScreen('img/windows.PNG', grayscale=True, confidence=0.8)
- pyautogui.click(windows_location.x-80,windows_location.y)
- time.sleep(2)
- pyautogui.hotkey('right')
実際に動作させた様子はこちら。
まぁまぁいいところまでできました。タイトルを「PyAutoGUIを試す(1)」としたけど第2回があるのか?個人的にはRPAってものには不満があります。UWSCもそうだけど、やらせている間は自分がPCを(ほぼ)使えないし。何度も書いたように結構自分専用でしか作れないし。これってやっぱりWindowsとかWebアプリとかの罪だよなー、、、LinuxみたいにCUIが発達していると、RPAが必要になることないし。WebアプリもそもそもWebアプリの設計者が設定ファイルのアップロード機能とか作ってくれていれば、その設定ファイルを何とかして自動生成すればいいわけだし。昔はWindowsネイティブソフトってキーボードだけでも操作できるように設計するのが推奨されていたけど今はちがうのかな?AcrobatReaderとかまさにキーボードだけじゃ操作できないし。まぁ、こんな世の中になっちゃってるのでしょうがない。こんなものが脚光を浴びる今の世を嘆きながらそっと筆を置くにゃ~かんきち。
PyAutoGUIがうまくいかないことがあるらしい。ので、自分のところ(うまくいっている)のpyautoguiとpyscreezeを貼っておく。
<Pythonインストールフォルダ>\Lib\site-packages
のそれぞれのフォルダのソースを差し替えてみてはどうかと思う。
とある場所のとあるPCではpyautoguiのインストール時にエラーが出まくって、そのくせsuccessfully installedってでるのに、結局ちゃんと動かなかったのですが、上記のファイルに差し替えたら動きました。バージョンはこの記事の冒頭の記録に書いてあるので、ここから変わってしまったら、、、その時に考える。
ちなみに、ページめくりではなく、複数のファイルに対して繰り返し処理をしたい場合、
os.startfile(foldername+'//'+filename)
として、起動させる。で処理する。で
pyautogui.hotkey('ctrl', 'w')
っとして閉じる。
を繰り返す。
CTRL+wはWindowsでは「閉じる」の共通語です。ちなみにUWSCはデフォルトではCTRL+wが何かに割り当てられていて、この共通語を使おうとすると別のことが起きる。UWSCの設定を変えて回避できます。、、、いまする話じゃない?失礼しました。
コメントをお書きください