Sikuli - データを変更して複数PDFを出力する

表形式のデータを変更してPDFを出力する処理を行います。

1つや2つのPDFを出力するのであれば、手動でも問題ありませんが出力するPDFがたくさんになるほど、とても退屈なルーチンワークとなります。

この作業をSikuliを使って自動化してみます。
(Excelがインストールされていないので表形式ソフトとしてLibreo Officeを使います。)

今回のSikuliの処理フローは下記の通りです。

 (1) Libreo上のデータを書き換えます。
 (2) メニューからPDF出力を選択します。
 (3) ファイル名を指定してPDF保存を行います。

 (1)から(3)の処理をデータ数分繰り返します。繰り返すデータはSikuliソース上にリスト型(の中に辞書データ)として定義しています。

ソース


下記の動画では、Sikuliで自動的にPDFファイルを3つ出力し、後半は手動で出力したPDFファイルを開いてデータが変わっていることを確認しています。


Sikuli - wordpressに自動投稿

Sikuliを使ってwordpressに自動投稿してみます。

処理はとても簡単で、まずブラウザを起動してwordpressの新規投稿ページに移動します。
(wordpressにはログイン状態になっている状態です。)

新規投稿ページではタイトルと記事を入力して、カテゴリーを選択し投稿(Publish)ボタンを押して投稿完了です。

ちゃんと投稿できているかどうか確認するために最後に投稿を表示しています。

ソース



ログイン処理をせずに単純に記事を投稿するだけだと、とても簡単に実装できました。

これまでにSikuliを使っていくつか実装しましたが、これらを組み合わせれば「FXで自動的に売買を行い、その内容をtwitterやwordpressに自動的に投稿する」といった作業がRPAだけで行えるようになります。

Sikuli - twitterに自動つぶやき

Sikuliを使ってtwitterに自動的でつぶやいてみます。

基本的なメソッドだけを使っていて、次のようなフローで処理しています。

 (1)ブラウザ起動
 (2)ログイン
 (3)つぶやく
 (4)ログアウト
 (5)ブラウザ落とす

下記ソースと動画を参考にして頂ければと思います。

ソース1


ソース2



twitterのAPIを使えば、GUI操作なしでも自動でつぶやくことはできると思いますが、APIキーを取得したりAPIの仕様を確認したりする必要がありますので、全体的な労力を考えるとGUIで操作を自動化する方が楽に実装できるかなと感じます。
APIを用意していないサービスでも自動化可能なので、汎用性も高いかと。。

Sikuli - 為替レートの変化を常時監視

SikuliのOCR機能と状態変化を検知する機能を使って、画面に表示されている為替レートの変化を常時監視してみます。

まずOCRに関しては、Regionクラスのtextメソッドで数字くらいなら簡単に認識してくれます。

画面変化を検知するのは少し難しいのですが、変化検知したときに動作する関数をRegionに設定しておく感じとなります。
今回はhandler1関数を定義し、OCRで取得した数字をエディタに貼り付けてみます。
Regionへのイベントハンドラ追加にはonChangeメソッドを使い、第1引数にはどれだけ変化があったらイベントハンドラを呼び出すかを指定します。今回は10を指定したので10ピクセル以上変化したらイベントハンドラがコールされます。

状態検知を有効にするためにはobserve関数を使うのですが、この関数を使うと処理が止まってしまうので通常はobserveInBackground関数を使いバックグラウンドで状態検知を有効にします。

また、処理を終了するときにはstopObserver関数を使い、状態検知を無効にします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# coding:utf-8
def handler1(event):
app.focus()
paste(r.text() + ' ')

# 変化値を貼り付けるエディタ
app = App('MKEditor')

# ユーザに監視するエリアを指定させる
r = selectRegion()

r.onChange(10, handler1)
r.observeInBackground(FOREVER)

wait(90)

r.stopObserver()
print('finished!')

この処理の動きは下記の動画で確認していますので、参考にして頂ければ幸いです。



OCRと状態変化検知を使うと、投資対象の為替レートを常時監視ができるようになり、例えば一定時間にある程度上昇したらその上昇に合わせて順張り投資するといったことが可能になります。

パラダイムシフトの時のような急激な一方方向へのトレンドがある場合は、順張り+建玉追加投資できるとかなりの利益を上げることができますが、そんなトレンドを人が張り付いて確認し続けるのは大変なので今回実装したようなRPAでの処理をうまく活用したいものです。

Sikuli - FX(デモ版)の注文を自動化

Sikuliを使ってFXの自動売買を行う処理を実装してみました。
ソースと実際の動きを動画にしましたのでよかったら参考にして下さい。
(ソース上のログインユーザ名やパスワードはさすがに隠してます。)

ソースの内容としては、waitやclick,paste,typeといった基本的なメソッドしか使っていませんがこのくらいのGUI操作なら十分自動化できます。
ただもっとエラー処理など気を付けて実装する必要があると思いますが。。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Operaブラウザを起動
app = App(r'C:\xxxxx\xxxxx\Opera\launcher.exe')
app.open()

# Operaの起動を待って、ログインページに移動
wait("1580206648525.png")
paste('https://demotrade.fx.dmm.com/fxcmdipresen/webrich/direct/login')
wait(0.1)
type(Key.ENTER)

# ログインページのロードを待ってログイン
wait("1580206818170.png",20)
click(Pattern("1580206853211.png").targetOffset(-97,123))
wait(0.1)
paste('[ユーザ名]')
wait(0.1)
type(Key.TAB)
wait(0.1)
paste('[パスワード]')
wait(0.1)
type(Key.TAB)
wait(0.1)
type(Key.ENTER)

# DMMサイトのロードを待って自動注文
wait("1580207030297.png", 20)
click(Pattern("1580213297947.png").targetOffset(89,41))
click("1580207967756.png")
click("1580213354520.png")

# ログアウト
click("1580213395792.png")
click(Pattern("1580213422219.png").exact())

# Opera閉じる
click(Pattern("1580214355504.png").targetOffset(21,-18))

popup(u'終了しました。')

ソース内で参照している画像



最初の実装サンプルではこのくらいでもいいかと思いますが、レートが大きく動いているときに順張りするとか、AIで状況を判断して売買するなどいろいろ作りこんでいくと夢のあるシステムができると思います。

Sikuli - 起動しているInternet Exploreを全て終了する方法

起動しているIEを全て終了する必要があったので実装してみました。

まずAppクラスにIEのウィンドウタイトルを設定しAppインスタンスを作成します。
(ウィンドウタイトルは一部が合致していればAppインスタンスを作成してくれるようです。)

そして生成したAppインスタンスのisRunningメソッドをコールしてIEが起動しているかどうかをチェックします。

IEが起動している場合は、closeByKeyメソッドで順次IEを終了させる・・・・といった感じで簡単に実装できるはずでした。。。

1
2
3
4
5
6
7
# coding:utf-8
chkApp = App(u"Internet")
while chkApp.isRunning():
chkApp.focus()
#chkApp.closeByKey() # 終了しないことがある
#chkApp.close() # 次回のIE起動時にクラッシュしたと表示される
type('w', Key.CTRL) # 比較的平和に全て終了する

ここからいろいろ問題が発生します。

まずcloseByKeyメソッドだとIEが終了せず無限ループになることが分かりました。原因は分からなかったのですが、IEが複数ウィンドウ起動していると1つめのウィンドウが落ちてその次のウィンドウが落ちないという現象です。

仕方ないのでcloseメソッドを使うことにしました。この方法ですと問題なく全てのIEウィンドウが閉じるのですが、次回IEを起動したときに「前回のブラウズセッションは予期せずに終了しました」と表示されてしまいます。

最終的には[CTRL + w]というショートカットキーを使ってIEを終了することにしました。
この方法であればIEのウィンドウは問題なく全て閉じますし、気持ち悪いメッセージが表示されることもありません。めでたし、めでたし。

Sikuli - 複数個所を連続して選択する

Regionオブジェクトのfindメソッドを使うと、引数に指定した画像をRegionオブジェクトの内部から探し最も合致した一か所を返します。

findAllメソッドを使うと合致した全ての箇所をリストとして返します。
このfindAllメソッドを使うとチェックボックスをすべてクリックするといった操作を行うことができます。

1
2
3
4
5
r = Region(1622,365,220,125)
list = r.findAll('checkbox.png')

for chk in list:
click(chk)

Sikuli - マウスホイールでスクロールする

Sikuliではマウスホイールでスクロールするための関数 wheel が用意されています。

wheel関数の引数は3つあります、

  • Regionオブジェクト
  • マウスホイールのアップ・ダウン
  • 移動数

以下の例ではフォーカスのあるウィンドウでマウスホイールを5回分ダウンさせたあとに、5回分アップさせます。

1
2
3
4
5
r = App.focusedWindow()

wheel(r, WHEEL_DOWN, 5)

wheel(r, WHEEL_UP, 5)

実際の動作としてはRegionオブジェクトの中心位置にマウスが移動し(クリックはされない)、マウスホイールを回転させる動作が実行されます。

Sikuli - 幅や高さが等間隔なものに入力する

Sikuliで幅と高さが等間隔の場合のデータ入力ではsetRasterメソッドを使うと便利です。

まずはfindメソッドで入力エリアのRegionを指定します。
そのRegionに対してsetRasterメソッドを使うと等間隔に分割することができます。

分割したエリアにはgetCell関数に行番号と列番号を指定しそれぞれのセルにアクセスすることができます。

1
2
3
4
5
6
7
8
9
10
11
12
13
# coding:utf-8
data = [[1, 2, 3, 4],
[10, 20, 30, 40]]

cells =find("1579840049307.png")
#4行3列に分割
cells.setRaster(3, 4)

for y, row in enumerate(data):
for x, col in enumerate(row):
# getCellメソッドで各セルに値を貼り付ける
paste(cells.getCell(y + 1, x), str(col))
wait(0.3)

5行目に指定した画像は下記です。

1579840049307.png

実行してみるとカーソルが1セルずつ選択を行い、データが入力されていきます。

Sikuli - ダイアログの表示位置を設定する

ダイアログはデフォルトで画面中央に表示されますが、popatメソッドを使用するとダイアログの表示位置を変更することができます。

popatメソッドの引数にx,y座標を指定することができるとのことですが私の環境ではエラーになってしまいました。
動作確認ができたLocation指定のコードは下記の通りです。

1
2
popat(Location(1511, 255))
popup('test')

LocationはSikuli IDEのツールバーで指定できますのでこの方法がおすすめです。