2010年8月1日

SIKULI 初體驗 - 利用 SIKULI 每日自動將 50 個 AWStats Report 另存成 mht 檔

話說今年 1 月底的時候,看到一篇很紅的文章:Sikuli 帶來的意義與無窮的潛力,作者是 vgod,當時有些知名的網站/部落客也寫過感想:
SIKULI 官網首頁有放一個 Demo,內容是自動設定網卡IP:


當時看完以後覺得超炫,但是後來也沒花時間去嘗試看看,直到上週想要作一件事:把 AWStats 每天產生的報表存成靜態網頁 (mht),才想到用 SIKULI 應該可以很簡單的完成這樣工作!

需求

之所以想要作這件事情,是因為每次瀏覽 AWStats 報表的時候都是連到一個如:http://myAWStatsReportSite/awstats/awstats.pl?&config=mySite 的 url,此時 awstats.pl 這隻程式會讀取事先計算好的統計資料檔,然後即時的繪製月報表

對於規模很小的網站來說大概沒啥感覺,但是對於每日流量到達 GB 以上等級的網站來說,在每月下旬的時候點選月報表的速度就明顯的慢很多,而若想要把 10 個左右的這類網站的流量合併統計,那麼到了月底的時候,即時繪製月報表最多可以花上超過 20 秒,這是個無法令人接受的速度!

仔細想想,這種報表的資料來源是歷史資料,一旦歷史資料分析完畢以後,往後不管在任何時間點選這張報表,內容應該都是一樣的,因此很適合以靜態網頁來呈現。為了方便檔案管理 & 加速網路傳輸,我決定把檔案另存成 mht 檔,這樣以後看報表的速度就快多啦!

問題是我的 AWStats 分析的網站很多,月報表 + 日報表總共有 50 個,叫我每天手動一個一個把網址貼到 IE,然後另存成 mht,再 FTP 到 Server 上 ..... 我才不要哩,又不是吃飽沒事幹!這就是 SIKULI 大顯身手的時候啦!(是說就是要把這種瑣碎工作弄成自動化,才可以每天吃飽沒事幹阿 ... Zzz)

SIKULI 初體驗

要使用 SIKULI,首先要去官網下載最新版的 SIKULI IDE: 1.0.1 (Java 6 or 7 is required, 2013-08-31 更新版本),目前對於 Windows & Mac 的支援較佳,聽說也有人把 SIKULI port 到 Linux 上。我抓的是 Windows 版,在 Win XPP 上安裝非常簡單,一路 Next 到底就好。

Sikuli IDE 打開以後大概長這樣:


版面配置跟很多主流的 IDE 差不多,很容易上手。

接下來就可以動手寫程式啦!在官網的 Documentation 中有 Tutorials & Examples 可以參考,花點時間看過去以後就知道程式大概要怎麼寫了。

基本上程式寫起來很簡單,由於 SIKULI 內建強大的電腦視覺引擎 (computer vision engine),內建的 function 如 find、findAll、click、paste 等都可以餵入一張圖片作為參數,當 SIKULI 執行 sikuli script 時就會去比對目前螢幕上可視區域中與指定圖片相符合的區域 (region),並且對該區域執行指定的動作 (e.g., click、paste)。

用文字寫起來太囉唆了,直接跑一個官網上的範例最容易瞭解了: Click all starts in Gmail

將 zip 檔下載解壓縮,用 SIKULI 打開後,再準備好一個 Gmail 視窗:



經過測試,如果用範例內的 find 函式會有問題 (TypeError: 'edu.mit.csail.uid.Match' object is not iterable,看來 find 函式的 return 值是單一的物件,不是如陣列一樣可以作 iteration 的資料結構),改用 findAll 以後就正常了:


當 SIKULI Script 在執行的時候,會看到一瞬間滑鼠游標依序由上往下把所有未標記成星號的 Gmail 郵件標記成星號,真的是非常有趣!

另外,SIKULI 可以用 click / doubleClick / rightClick 等函式來模擬滑鼠事件,以 type 函式控制鍵盤輸入,因此只要可以用滑鼠 + 鍵盤完成的工作,都可以寫成程式讓 SIKULI 自動執行 (應該有超過 90% 的工作都可以用滑鼠 + 鍵盤完成吧?所以 SIKULI 真的是潛力無窮呢!)

在以 type控制鍵盤輸入方面,SIKULI 支援 Windows Key, Ctrl, Alt, Tab, Up, Down, F1~F15 等特殊鍵,非常方便,我最常用的有以下幾種:
  1. type("c", KEY_CTRL):ctrl+c
  2. type("\t", KEY_ALT):alt + tab
  3. sleep(n):讓 process 睡 n 秒
  4. var = Env.getClipboard():把系統剪貼簿中的暫存資料存到變數 var
  5. paste("IE開啟舊檔.png", var):把變數 (URL) 貼到 IE 的「開啟舊檔 (ctrl-o )」視窗中
SIKULI 所支援的特殊鍵請參考官網文件:12. Key Constants 中的 12.1. Key Modifiers12.2. Special Keys

由於 Sikuli 是以 Jython 為基礎發展的,而 Jython 是 Python for the Java Platform,因此要查詢基本語法的話可以參考 Jython / Python 的資料。

我這次寫的 script 邏輯如下:


程式利用的技巧就如同上述 4 點,並不困難。

測試情境:
  1. AWStats Static Report test.xlsx 隨便放哪裡都可以,但是要先用 Excel 開過一次,讓檔名出現在最新開啟過的檔案清單 (MRU list)中
  2. 要在「我的文件」中建立一個名為「AWStats Static Reports」的資料夾 (不然就要自己重新抓圖,去改程式碼第12行)
  3. script 執行完畢後會回到 SIKULI IDE (執行過程中發生錯誤也會回到 IDE 中),此時可再檢視「我的文件」->「AWStats Static Reports」中是否有三個 mht 檔。

Sikuli IDE 的優點:
  1. 如同[T客邦] 抓圖寫程式,SIKULI 將改變世界一文中所說,Graphical Scripting Language 真的是非常有趣,實際上若打開 Sikuli source files 資料夾中的 ProjectName.py 檔來看就可以知道,在 Sikuli IDE 中看到的圖檔在程式碼中其實是檔名 (如「1.png」),但是 IDE 在 project 資料夾中找到這個檔以後,就把圖檔讀出來顯示在畫面上,令人覺得很親切,大大增加了程式碼的可讀性和易用性,該行程式要作甚麼真的是一目瞭然。
  2. 大大降低寫程式的門檻,讓一般人也有機會自己把平常操作電腦的瑣碎步驟自動化。
  3. SIKULI IDE 的配色看起來很舒服。

Sikuli IDE 目前的小缺點:
  1. 在 Win XPP 下,按 Alt + Tab 從 Sikuli IDE 跳到其他視窗,再跳回 Sikuli IDE 後,(有時候)會 focus 在 Sikuli IDE 的「檔案」選單,而非程式碼編輯器中,這點不太方便。
  2. 將程式碼從一個 project copy 到另一個 project,或者將 project 另存新檔後,有時候會有問題,例如 function 的左括號「(」看起來不見了 (但是看ProjectName.py 檔會發現還在,如果在 IDE 裡面多加一個「(」反而會讓 script 無法執行),或者是找不到圖檔 (這時要重新指定圖檔),會導致執行時的 SyntaxError。

未來目標:
  1. 設定 Windows 排程,在上班前把這個 script 跑過一次,等到上班時間就可以直接瀏覽靜態的 mht 報表了
  2. 在開啟 IE & Excel 之前,先把用來存放 mht 檔的資料夾清空
  3. 50 個 mht 檔都產生完畢以後,自動分門別類的以 FTP 上傳到 Server 中
經過這次的練習,以後如果要處理類似的繁瑣工作 (而且是跨應用程式的),又多了一個好用而且超酷炫的工具啦!

參考資料:
  1. Sikuli 帶來的意義與無窮的潛力
  2. PROJECT SIKULI (官網)
  3. PROJECT SIKULI documentation (官網)
  4. [T客邦] 抓圖寫程式,SIKULI 將改變世界
  5. [阿宅萬事通] Pranav Mistry 的第六感與高雄餐旅學院,還有來自台灣的 Sikuli~~~
  6. wwfc的遊戲世界 - for loop

3 則留言:

Amos Fan 提到...
作者已經移除這則留言。
Unknown 提到...

你好,請問一下
關於SIKULI,如果想要寫出一些類似按鍵精靈提供的api以及更改主程式的介面,增加一些特殊鍵的按鈕的話,要學PYTHON還是JYTHON呢?

Unknown 提到...

你好,我看 Sikuli 官網上是用 Python (http://www.sikuli.org/, 參考 "How can I learn and use Sikuli?" 段落)。

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D