ふにゃるんv2

もとは、http://d.hatena.ne.jp/Wacky/

RecIE(IEの操作を記録するツール)とPythonを連携して、簡単な英日変換ツールを作ってみよう

いつも通り、ネットをふらふらしていたら、RecIEというソフトが出た〜と紹介がありました。


ブラウザを制御して〜と言われると、Seleniumってソフトを思い出します。


まぁ、こっちはUIのテスト用のツールに特化しているんですが、Seleniumって FireFox用ですよね?
自分、いつもIE(正確にはプニルたん)を使っているし、仕事でもIEがデフォルトなんですよね。
で、これを使って、何か出来ないかな?と思った次第です。


でまぁ、今回、PythonとRecIEの連携例として、簡単な英日翻訳ツールを作ってみました。

RecIEを試してみる

まぁ、使ってみないと どんな代物か判らない訳で。早速ダウンロード。

  • recie09.zip
  • uwsc41.zip


RecIEを使うには、UWSCが必要らしいのです。
で、同じフォルダに両方の圧縮ファイルを展開し、実行。
実行すると、以下の画面が出てきます。

RecIE1
RecIE1 posted from フォト蔵


で、「記録」ボタンを押すと、URLの入力を要求されます。

RecIE2
RecIE2 posted from フォト蔵


例えば、http://honyaku.yahoo.co.jp/transtext を入力すると、Yahoo!翻訳のページに移動します。

RecIE3
RecIE3 posted from フォト蔵


ここで、適当な英文を入れて翻訳ボタンを押すと、翻訳結果が出ます。
そんな作業をすると、右下のペインで にょきにょき スクリプトコードみたいなものが出来上がります。

RecIE4
RecIE4 posted from フォト蔵


作業が一旦完了したら、「停止」ボタンを押します。で、先ほどの作業内容を再現したい場合、「再生」ボタンを押します。
すると、先ほどと同じ作業を再現してくれます。おぉ。

RecIE5
RecIE5 posted from フォト蔵


ちなみに、どんなスクリプトが生成され、実行されたのか、以下に紹介。

IE = CreateOLEObj("InternetExplorer.Application")
IE.Visible = True
IE.Navigate("http://honyaku.yahoo.co.jp/transtext")
BusyWait(IE)
IESetData(IE,"hello python world.","text") // TEXTAREA
IESetData(IE,True,""," 翻訳 ") // SUBMIT
BusyWait(IE)
//------
Procedure BusyWait(ie)
  Sleep(0.5)  // Wait
  Const TIME_OUT = 90
  tm = Gettime()
  repeat
    Sleep(0.2)
    ifb Gettime() - tm > TIME_OUT
      MsgBox("Time Out:BusyWait")
      ExitExit
    endif
  until (! ie.busy) and (ie.readyState=4)
  Sleep(0.5)
Fend

結構判りやすい書式ですね。

RecIEとPythonを連携させる

で、先ほどのスクリプトなんですが、UWSCに一緒に引っ付いてくるオンラインヘルプを読むと、どうやらUWSC独自のものみたいなんですね。
UWSC内部で全て完結させるのも「有り」なんですが、それじゃ おっPyファンとしては面白くない。
何とかして、Pythonと連携してやろうと思った訳です。


どうやって、PythonとRecIEの間のやり取りを行おうか、オンラインヘルプを呼んでいると、どうやらクリップボード間のテキストデータの受け渡しが出来る模様です。

ちなみに、PythonもWin32拡張モジュールを組み込めば、win32clipboardモジュールをロードする事で、クリップボードのデータのやり取りが出来ます。


という訳で、以下のように組み立てる事にしました。

  1. Pythonから英日翻訳したい英文を、クリップボードに送る
  2. UWSCを、子プロセスで起動する
  3. UWSCスクリプトで、クリップボードから文字列を読み取り、英日翻訳させる
  4. 翻訳結果を読み取り、クリップボードに送る
  5. Pythonに制御が戻ったら、クリップボードから文字列を取り出す


以下にコード例を示します。

test.py:
#!/bin/env python
# -*- encoding: shift-jis -*-
import os
import win32clipboard as cl
import win32con

def get_clipboard_text():
    cl.OpenClipboard()
    data = cl.GetClipboardData( win32con.CF_TEXT )
    cl.CloseClipboard()
    return data

def set_clipboard_text(s):
    cl.OpenClipboard()
    cl.SetClipboardText( s )
    cl.CloseClipboard()

def main():
    s = "hello python world"
    print "変換前[%s]" % s
    set_clipboard_text(s)
    os.system("uwsc test.uws")
    print "変換後[%s]" % get_clipboard_text()

if __name__ == "__main__":
    ret = main()
test.uws:
IE = CreateOLEObj("InternetExplorer.Application")
IE.Visible = True
IE.Navigate("http://honyaku.yahoo.co.jp/transtext")
BusyWait(IE)
IESetData(IE,GetStr(0),"text")        // $$$ この行を修正
IESetData(IE,True,""," 翻訳 ") // SUBMIT
BusyWait(IE)
SendStr(0, IEGetData(IE, "trn_text")) // $$$ この行を追加
IE.Quit()                             // $$$ この行を追加

//------
Procedure BusyWait(ie)
  Sleep(0.5)  // Wait
  Const TIME_OUT = 90
  tm = Gettime()
  repeat
    Sleep(0.2)
    ifb Gettime() - tm > TIME_OUT
      MsgBox("Time Out:BusyWait")
      ExitExit
    endif
  until (! ie.busy) and (ie.readyState=4)
  Sleep(0.5)
Fend

test.pyは、"hello python world."を そのまま渡すという超簡素仕様ですが、まぁいいでせぅ。
とりあえず、実行してみます。

$ python test.py
変換前[hello python world]
変換後[よろしくパイソン界。]

ウィンドウが開いて、以下のように実行されます。

RecIE6
RecIE6 posted from フォト蔵

感想

今回の内容程度ならば、直接PythonからIEを呼び出して制御する事は、簡単です。
しかし、RecIEは、簡単に制御内容をスクリプト化してくれます。
特にテキストボックスへの書き込みを行う為に、IEソースコードを眺め回す必要が無いのは、大きなメリットだと思います。
Pythonでデータを渡して、RecIEでIEを制御する事で、適材適所な使い方が出来ると思います。


まぁ、惜しむらくは、UWSCPythonとの間で、もうちょっと確実なデータ受け渡し手段が用意されていると良いなぁ。という所でしょうか。
Python側をGUIで用意すれば、SendMesssage等を使うという方法もありますね。