Sikuli - クリップボードの値を取得する

Sikuliでクリップボードの値を取得するには、App.getClipboardメソッドを使用します。
例えば、コピーした文字列をresult変数に取得するには下記のように実装します。

1
2
result = App.getClipboard()
print(result)

もちろんクリップボードの値を取得する前に type(‘xxxxx.png’, ‘c’, Key.CTRL)などを実行しておいて情報をコピーしておく必要があります。

Sikuli - 例外処理

合致しなかったときの例外処理

Sikuliでは画像が見つからなかった時に例外が発生し、プログラムが停止します。
これを防ぐ方法としてまず考えられるのが、existsメソッドを使う方法です。existsメソッドを使ってあらかじめ画像が存在するかどうかを確認し、存在するならばクリックするようにプログラミングします。

1
2
3
4
if exists('xxxx.png'):
click(getLastMatch())
else:
popup(u'画像が見つかりませんでした。')

しかしこのようにif文をひとつひとつ記述するのは煩雑で、コードも見づらくなりますので、次の処理を検討した方がよいでしょう。

例外をトラップ

Sikuliは、画像が見つからないときなどに、FindFailedという例外を発生します。
次のコードのようにtry catchで囲って処理します。この方法であれば先に実装したようにひとつひとつexistsメソッドで調べなくてもすみます。

1
2
3
4
try:
click("xxxx.png")
catch FindFailed:
popup(u'画像が見つかりませんでした。')

例外をスキップするか例外ハンドラ処理

画像が見つからない場合は、そのまま無視したり、ユーザにどうするかを尋ねたりするほか、自分が設定した独自の例外ハンドラで処理することもできます。

関数名 解説
setThrowException(f) 例外を発生するかどうかを設定する。
f=Trueで発生させる(既定)
f=Falseで抑制する
setFindFailedResponse(ABORT|SKIP|PROMPT|RETRY) 画像が見つからなかったときにどうするかを設定する。
ABORT=例外を発生し終了する(既定)
SKIP=無視する。戻り値はNone
PROMPT=どのようにするかをユーザに尋ねる
RETRY=見つかるまでリトライする
setFindFailedHandler(handler) 例外が発生したときに実行する独自の例外ハンドラhandlerを設定する。

(1)例外の抑制

setThrowException(False)またはsetFindFailedResponse(SKIP)を実行すると、例外を抑制できます。この場合、戻り値はNoneになります。
clickメソッドやtypeメソッドは、引数がNoneであってもエラーなどは発生せずなにもしないだけです。
特にエラーメッセージを表示する必要がなく、単純に見つからなかったときは何もしないということであれば次のように記述できます。

1
2
setThrowException(False)
click('xxxx.png')

(2)どうするかをユーザに尋ねる

setFindFailedResponse(PROMPT)を実行しておくと、画像が見つからなかったときに確認ダイアログ①が表示されます。

1
2
setFindFailedResponse(PROMPT)
click('xxxx.png')

確認ダイアログ①


[Retry]をクリックすればリトライし、[Abort]をクリックすればプログラムは終了します。
[Capture/Skip]ボタンをクリックするとさらに次の確認ダイアログ②が表示されます。

確認ダイアログ②


[Capture]をクリックすると、この画像を別の画像に差し替えることができます。
Sikuliでは画像の解像度などの違いによって、別の環境に持っていくと画像がマッチしなくなってしまうことがあります。
setFindFailedResponse(PROMPT)としておけば、そのような場合ユーザがマッチする画像を差し替えることができるため大変便利です。

(3)独自の例外ハンドラ設定

setFindFailedHandlerメソッドを使うと、独自の例外ハンドラを設定できます。
ハンドラの書式は以下の通りです。

1
2
3
def handler(event):
#画像が見つからないときの処理をここに書く
event.setResponse(PROMPT) # どうするかをユーザに尋ねる

引数のeventオブジェクトはイベントが発生したときに渡されるObserveEventオブジェクトです。
例外ハンドラではevent.setResponseメソッドを使って、ABORT,SKIP,PROMPT,RETRYのいずれかの値を返さなければなりません。

この方法をとると画像が見つからなかったときに、エラーログを出力したり、メールを送信したりし、その後の処理はユーザに尋ねるといったことができるので個人的には一番お勧めです。

Sikuli - 使いどころ

Sikuliはアイデア次第でいろいろな場面で使えます。代表的な用途としては次の通りです。

  • 業務アプリ操作の自動化
    事務作業・経理作業を自動化することにより作業を大幅に軽減できます。特に、あるソフトから別のソフトへの転記作業は得意で、Sikuliを導入すれば大変効率が向上するはずです。
  • システム開発のテスト自動化
    システム開発をする際の各種テストの自動化にSikuliは貢献します。
    開発したシステムのテストでは操作するシナリオを決め、その通りに実装できているかを確認する場面があるかと思います。そのような場面において一旦Sikuliを使ったテストプログラムを作っておけば何度でも再テストできます。
    さらに他のシステムを開発する際にも、それを流用したテストができるため人間が一からテストを手作業で実施するのに比べてはるかに効率化できます。
    Sikuliにはスクリーンショットをとって保存する機能もあるのでテストのエビデンスを残すのも簡単です。
  • ゲームのBot作成
    ゲームの自動プレイの作成ができます。PCに接続したAndroid端末の操作もできます。(ただまだテスト版で不安定だという噂です。)

Sikuli - デメリット

Sikuliには次のようなデメリットがあります。

  • 画面の解像度やテーマが変わると動かなくなる可能性がある
    Sikuliでは、画像マッチングでボタンなどの操作対象を探しているので、デザインが変わった場合やディスプレイの解像度が変わった場合などに、動かなくなる可能性があります。
    そのような問題が発生した場合は、プログラムの画像が入っている部分を正しく差し替える必要があります。
  • 自動実行中にはユーザ操作ができない
    RPAツールはマウス操作やキーボード操作を自動化するツールです。サンプルを作って実行するとすぐに気づきますが、実行中は自動的にマウスポインタが動いたりキー入力したりするので、その間ユーザは操作することができません。
    操作が禁止されるわけではありませんが、マウスが勝手に動く中それを遮るように人間がマウス操作やキー操作するのは現実的ではありません。
    完全にSikuliに操作を任せたいのであれば、Sikuli専用PCを用意するか仮想マシンを用意する必要があります。

Sikuli - メリット

Sikuliには次のようなメリットがあります。

  • プログラムが直感的
    ソースコードの中に対象の画像が表示されるので、何を操作しているのかが直感的に分かります。
  • メニューやボタン以外も操作可能
    画像マッチングで位置を特定するだけなので、そこに何があるのかを気にしません。ほとんどの操作対象はボタンやメニューだと思いますが、それ以外のものも操作できます。例えば、Adobe Flashを使ったアプリケーションやPC上で動作するスマホのシミュレータなど、OSからはボタンやメニューとして認識されないものでも操作することができます。
  • 画像マッチングを利用して監視もできる
    画像上の変化を監視することができます。例えば何か業務アプリで障害が発生したときに赤いエラーメッセージが表示されるようなシステムがあったとします。Sikuliを使うと画面の変化を監視し赤いエラーメッセージが表示されたときに、警告メールを送信するようなプログラムを作ることができます。
    PCにカメラを接続していれば、Sikuliでそのカメラ画像の変化を監視することもできます。
  • ユーザインターフェースを作れる
    Python、Ruby、Javaなどに対応していて、それぞれのプログラミング言語に対応した各種ライブラリを使うことができ、単純なRPAツールとしてだけでなく本格的なカスタムRPAを作る際のフレームワークとしても活用できます。
  • OCR処理ができる
    画像をOCR処理することができ、帳票をスキャナで読み込んでOCR処理を行い、帳票入力を支援するツールなども作れます。

Sikuli - OCR日本語対応

Sikuliで日本語のOCRを実行してみました。

環境

動作確認環境は次の通りです。

  • OS
    Windows 10 Home
  • Sikuliバージョン
    2.0.1
  • javaバージョン
    1.8.0_101(64bit)

前準備

OCRを日本語に対応させるためには、日本語OCR用のデータファイルをダウンロードする必要があります。

ダウンロードデータ

https://github.com/tesseract-ocr/tessdata/blob/master/jpn.traineddata

ダウンロードデータを格納するフォルダ

C:\Users(ユーザ名)\AppData\Roaming\Sikulix\SikulixTesseract\tessdata

※SikulixTesseractフォルダが見つからない場合は、一度SikuliでOCRに関する処理を実行してみると、自動で作成されるようです。

実装

以下のコードを実行すると、領域選択画面が現れるので、そこでOCRを実行したいエリアを選択するとOCR処理されたデータがout.txtに出力されます。

1
2
3
4
5
6
7
8
9
10
11
import sys
reload(sys)
sys.setdefaultencoding("SHIFT_JISX0213")

tr = TextOCR.start()
tr.setLanguage("jpn")

r = selectRegion()
#print(r.text())
with open('out.txt', 'w') as f:
f.write(r.text())

※標準出力だと文字化けするのでとりあえずファイル出力にして回避しました。

Sikuli - バッチ起動時に引数を渡す

Sikuliプロジェクトをバッチ(コマンド)で実行する際に引数を渡すには下記のようにします。

1
java -jar sikulix.jar -r xxxxxxx.sikuli -- 引数1 引数2

-jarのあとにsikuli.jarを指定し、-rのあとにSikuliプロジェクトを指定するところまでは引数なしのコマンド実行と同じです。
そこからハイフンを2つ入力し、引数をスペース区切りで指定すると、起動引数として処理に渡すことができます。

Sikuliプロジェクトの中で起動引数を確認するときは、Pythonでの文法そのままです。

1
2
3
import sys

print(sys.argv)

Python使いの方にとっては実行時のハイフン2つを覚えるだけで簡単に実装できます。

Sikuli - 設定変更

Sikuliには各種設定を変更するプロパティがあり、値を変更することで挙動を変えることができます。

Settingsクラスのプロパティ

プロパティ 説明 既定値
MinSimilarity 類似度。 0.7
MoveMouseDelay マウスの動きの遅れ。0に設定すると瞬間移動する。 0.5秒
DelayBeforeMouseDown マウスのボタン押下の際の遅れ時間(秒)。 0.3秒
DelayBeforeDrag ドラッグの際の遅れ時間(秒)。 0.3秒
DelayBeforeDrop ドロップの際の遅れ時間(秒)。 0.3秒
ClickDelay クリックの際の遅れ時間(秒)。最大1秒まで。 0秒
TypeDelay キー入力の際の遅れ時間(秒)。最大1秒まで。 0秒
SlowMotionDelay スローモーションで動かす際の遅れ時間(秒)。
WaitScanRate 画像マッチングの際の待ち時間間隔(秒)。 3
ObserveScanRate イベントが発生するかどうかを確認するために画像をスキャンする時間間隔(秒)。 3
ObserveMinChangePixels 画像の変化イベント(Changeイベント)を、どのくらいのピクセルが変更したときに発生させるか。 50(約7×7ピクセル四方)
AlwayResize 自動で画像リサイズするかどうか。0でしない、1でする。 0
ImageCallback 画像マッチングする際に呼び出してもらいたいコールバック関数を指定する。

ソフトウェア上でのRPAの位置づけと機能

RPAはアプリケーションのひとつですが、業務システムやOAツールなどのアプリケーションを、データや各種処理を通じて横断的につなぐ役割を果たします。

ミドルウェアは垂直方向での共通基盤ですが、RPAでは水平方向に横断的にアプリケーションをつなぎます。

RPAは次の3つの機能があります。

  • 定義
    ロボットの処理を定義する。
  • 実行
    定義された処理を実行する。
  • 運用管理
    ロボットの稼働状態、実行結果の取得、スケジュールやプロセスの管理する。

Sikuli - Appクラス

Appクラスは、アプリケーションの起動やフォーカスの設定、ウィンドウを閉じる操作等の機能を提供します。

コンストラクタは下記の通りです。

コンストラクタ 説明
App() 引数なしのコンストラクタ
App(name) アプリケーション名や実行ファイル名を指定したコンストラクタ