SikuliX で GUI 操作を全自動化してみた
こんにちは、けんにぃです。ナビタイムジャパンで公共交通の時刻表を使ったサービス開発やリリースフローの改善を担当しています。
今回は GUI 操作を全自動化した話をしようと思います。いわゆる RPA と呼ばれる自動化の話です。
GUI と CUI
何らかの作業を行うときに皆さんは GUI と CUI のどちらを使いますか?どちらを使うべきかはケースバイケースだとは思いますが、どのように使い分けるのがベストなんでしょうか。少し考察してみたいと思います。
私は下記のようなケースでは GUI を使用します。
・非開発者が行う作業
・グラフ化などの視認性が求められる作業
・色の確認などの UI のテスト
一方で下記のような状況では CUI を使用しています。
・正確さが求められる作業
・作業スピードの向上
・大量のテストを実行
おおむね人の判断が必要な作業では GUI を使用し、定型化可能で CI に任せられる作業は CUI を使用するというような使い分けをしています。
ただ CI を使うべきシーンでも作業を CUI で実装することはそれなりに難易度が高いため、作業者の知識や経験によってはうまく実現できないこともしばしばあります。
つまり CUI で作業効率化を図りたいが、何らかの理由により GUI で作業を行っているというケースが実際にはあり得るのです。
こういったジレンマを解消させるため RPA による自動化を検討しました。
RPA
RPA はロボティック・プロセス・オートメーションの略で、CUI や API を使わずに作業を自動化する手法のことです。
人間が GUI を操作する時の作業をそのままロボットに行わせるため、マウスを操作したり、画像認識で GUI 上のボタンをクリックさせるなどの機能を使って自動化を実現します。
RPA を使えばゲーム操作の自動化も出来るようです。また Selenium はブラウザ操作に特化した RPA ツールの一種と言えます。
SikuliX
今回 GUI 操作の自動化に当たり、採用したのが SikuliX というツールです。
SikuliX の実行環境は Java ですが、自動化のためのコードは Python で記述できます。
難点なのが Python 2 で記述しないといけないため、日本語の扱いでハマることがあります。しかし SikuliX は書籍もいくつか出ており日本語の情報が豊富なため、Python 2 の使用については妥協することにしました。
Python 3 に向けた対応は現在開発中とのことなので、今後に期待しようと思います。
SikuliX のインストール
試した環境は Mac ですが Windows でもほぼ同じ手順で動かせると思います。
ダウンロードのページより下記の 2 つをダウンロードして同じディレクトリに保存しておきます。
・sikulixide-2.0.4.jar(IDE)
・jython-standalone-2.7.1.jar(Jython: Java で実装された Python)
Java 製の IDE 上で Python のコードを記述して実行するという流れになります。IDE を起動するには下記のコマンドを実行してください。
$ java -jar sikulixide-2.0.4.jar
すると下記のような IDE が起動します。
SikuliX の使い方
Spotlight を起動して Hello, World! と入力するプログラムを書いてみます。
1. Spotlight の起動
ショートカットキーの ⌘ + SPACE を入力して Spotlight を起動します。
type(Key.SPACE, Key.CMD)
2. テキストの入力
Spotlight 上で Hello, World! と入力します。
type("Hello, World!")
3. ファイルを保存
メニューから File → Save as... を選択してファイル名を適当に入力してファイルを保存します。
4. プログラムの実行
IDE 上の Run ボタンを押すとプログラムが実行されます。
画像認識を使った操作
前の例ではショートカットキーで Spotlight を起動しましたが、Mac の画面右上にある 🔍 をクリックすることで Spotlight を起動することも出来ます。
SikuliX にはアイコン画像を画像認識により検出することで、検出位置にマウスを移動させることが出来ます。そのやり方について説明します。
1. アイコン画像を保存
IDE 上にある Take screenshot ボタンを押して Mac の右上にある 🔍 アイコンのスクリーンショットを保存します。
2. アイコンをクリック
🔍 アイコンをクリックさせます。
click(🔍)
関数に 🔍 アイコンを渡しているのが奇妙ですが、これは IDE 上の見え方の問題で、実際には保存した 🔍 画像のファイル名を渡すコードが記述されています。
3. テキストの入力
Spotlight 上で Hello, World! と入力します。
type("Hello, World!")
4. プログラムの実行
Run ボタンを押してプログラムを実行すると、🔍 の位置にマウスが移動して Spotlight が起動すると思います。
実行ファイルを指定してプログラムを起動
プログラムを起動させる一番シンプルな方法は実行ファイルを指定して起動させる方法です。App.open() に実行ファイル名を渡して起動させることが出来ます。
App.open("Safari")
App.open(r"/Applications/Google Chrome.app")
App.open(r"C:\Program Files\App\app.exe")
一定時間待機させる
wait() を使うことで一定時間操作を待機させることが出来ます。
# 5 秒待つ
wait(5)
SikuliX はプログラムの起動が終わったかどうかを把握しているわけではないため、一定時間待たずに次の操作を続けると、プログラムが起動し終わる前に次の操作を行ってしまう可能性があります。そのため次の操作に移る前に wait() を挟んであげることが重要になってきます。
wait() には画像ファイルを渡すことも出来ます。
上記のコードは OK ボタンが現れるまで 30 秒待機するというコードです。ダイアログが表示されるまで待ちたいときなどに利用できます。
注意点
日本語の扱い
文字列は Python 2 系で扱わないといけないため "..." と u"..." の違いをちゃんと理解しておく必要があります。
特にキーボードから日本語を入力させたい場合は type() を使うことは出来ません。代わりに paste() を使う必要があります。
paste(u"こんにちは")
type() はあくまでもキーボードのキーを指定するため、キーボード上にある記号と英数字しか渡せません。そのため、日本語入力が有効な状態で
type("konnnichiha")
と書いてあげると一応『こんにちは』という日本語が入力できます。
RPA を導入するタイミング
自動化をする際は RPA を導入する前にまず CUI や API を使って実現可能かどうかを検討したほうが良いかなと思いました。これは Selenium を使う場合でも同様です。
まとめ
はじめて RPA を使ったのですが、上手に使うと普段の作業がかなり改善しそうな気がしました。テストでの活用も出来そうなのでぜひお試しください。