LoginSignup
4
5

More than 3 years have passed since last update.

Python×WindowsAppDriverによるGUIの自動化

Posted at

【前置きの前置き】

もともとはWinActorを現場に使ってもらうって計画だったらしく、
一時期契約まではしていたのですが、投資を回収できていないということから、WinActorも含むRPAの予算全カット。
その結果、必要経費0円でRPA化を進むことに・・・。
今回は、GUIの自動操作実現までの奮闘記。

【前置き】

GUI操作の自動化にもいろいろと種類があります。
最初に行き着いたのはpyautoguiを使った画像認証+キーボード/マウスの操作なのですが、
これだとキーボードとマウスの操作は確実にやってくれますが、
本当に画面を操作してくれているのか不明です。

そこに画像認証を加えるとかなり精度があがります。
ただ、これにも欠点があります。
・画面の表示上から指定の画像を探すような操作をするため遅い
・デスクトップの背景画像が変えてあると反応しない
・探させる画像1つで動作が変わる

もっと安定したものが欲しいと探して見つけたのが、
「UI Automation」なのですが、
以下の理由で却下
・コーディングが個人的に好みでない
・情報量が少ない(・・・と、個人的に感じた)

そこからいろいろと情報を集めてたどりついたのが、
「WindowsAppDriver」(長いので以下WAD)
以下が採用の理由
・コーディングの見た目がSeleniumに似ている
 └ Seleniumを覚えてれば誰でも使える。その逆も言える
・情報が割と新しく、調べれば簡単に調べられる

※UI AutomationとWADの根本の仕組み

VB.netやJQueryなどに近いもので
操作対処のIDやその他の属性を指定して、対象を補足し操作するというタイプです。

【本題】

基本的には、以下のURLに書いてある内容をやってもらえれば動きます。
https://arakan-pgm-ai.hatenablog.com/entry/2019/08/19/000000

私が工夫した内容は以下の通り

①動作環境

まず、実行環境には、「開発者モード」の権限を与える必要があります。
そのため、個人使用のPCを実行環境に選ぶという選択肢を早々に消しました。

私が選んだのは、仮想環境にWindows10を入れて使う
(仮想環境が用意できないのであれば、PCの代替えで引き揚げてきたPCでも可)
※代替えの引き上げPCなので故障などのリスクに対する対応を考えておく必要があります
※自動化専用ということもあって自動でログインできるようにしておくというのが肝

その他にクリップボードやマウスやキーボードなどの資源を人間と取り合うのを防ぐ目的と
メンテナンスがしやすくなるというのもあります。

作業者が10人いれば、10人のPCにインストールしてあげる必要とか出るかもしれませんし
作業者が複数人集まれば、注意事項とか守らない人も出てきます。
作業者が1人でも担当交代とかいろいろとありますので
作業者が触れない環境を作って、運用する方法というのを取っています。

どうやって自動化したプログラムを動かすか?
これは、タスクスケジューラとかを使うのが一番手軽です。
この辺りの対策もいろいろとありますのでまた後日。

②間違ってWADの画面を閉じないようにする方法

WADを使った自動化が浸透してくると他のプログラマーもこの環境を使い始めます。
そうするとよくわからない人も見様見真似で使い始めるものです。
そうなると、黒い画面を閉じちゃった・・・。
っとか、やってしまうものです 
 
そうなると、タスクスケジューラなどで起動設定していても
WADが止まっているので動きません。

1番単純な対策は、黒い画面を見せないように起動することでしょう
以下のコードをShell:startupに設置しておくことです

wad.vbs
dim ws
Set ws = CreateObject("Wscript.Shell") 
ws.Run """C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe""", 0

③操作対象のアプリケーションがリモートの画面越しの場合

操作できませんので操作対象のアプリケーションをローカルにインストールしましょう
GUIの調査ツールで見るとわかりますが、VNCやXen越しに操作しようとすると
VNCやXenの画面のキャンパス部分の情報しか取れません。

④入力速度の向上

pyperclipを使って入力対象の文字列をクリップボードに入力し
テキストボックスに対してCtrl+Vを送り付けて貼り付けを行いましょう。
標準の入力の仕組みを使っても良いのですが、
キーボードを叩いているような動きをしますので長い文章を入力するときは
動作速度が遅くなります。

⑤操作対象のアプリケーションがバッチ起動&起動済みの場合

前提の話ですが
以下のコードは、電卓を起動して電卓のアプリを補足するというような動きをします。

desired_caps["app"] = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"

そのため
 desired_caps["app"]にバッチのパスを指定してもアプリを補足できません。
 ※バッチのプロセスとアプリケーションのプロセスは別物です
 アプリケーションのフルパスを指定しても、自動更新などのバッチに書いてあることをやってくれません。
 新しくアプリケーションを立ち上げてしまうため、今動いているアプリケーションを捕まえることができません。
 
そこで取っている対策は、
・以下のコードを実行し、アプリケーションを起動する

subprocess.Popen(['start', バッチのショートカットのPATH], shell=True)
# たしか、start以外にexplorerでもよかったはず。

・Pythonのコードの以下の部分を変更すること

desired_caps["app"] = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"
 ↓
desired_caps["app"] = "Root"

こうするとデスクトップそのものを補足します。

上記の2つを満たしていれば、
 デスクトップに「●●●」というウィンドタイトルのアプリケーションは起動しているか?
 という確認ができるようになります。
 なので●秒待ってみて、見つからなければエラー/起動できれば、作業続行みたいな形にできます。

⑥ダイアログの操作方法について

テキストボックスなど同様に属性値を調べてから操作することもできますが
かなり複雑な作りになっているものも存在します。
※特にファイルダイアログ

対策としては、
 ウィンドタイトルを確認した上で
 pyautoguiのキーボード操作と組み合わせると簡単に実現できます。

これだけやっておけば、大抵のことはできるのではないかと思います。
次回はWEBの自動操作辺りについてまとめてみようかと。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5