顯示具有 phantomjs 標籤的文章。 顯示所有文章
顯示具有 phantomjs 標籤的文章。 顯示所有文章

2014年7月31日 星期四

筆記:小型 Web Crawler/Automator 個人工具箱

許多 (browser) automation 的工具都用「鬼」命名 XDDDD
phantomjs, slimerjs, casperjs, ghost.py ...
圖片來自:手滑背單字 的懶惰鬼


#以下為我撰寫小型 web crawler / automator 時常使用的工具與思路


觀察 & 分析

釐清要什麼以後,宜先人工操作網頁,並透過以下方式進行初步觀察:
  • chrome 開發人員工具 => network => 勾選 preserve log => 進行操作
    • 觀察 http 封包的發送
  • chrome 開發人員工具 => 點選左上角搜尋圖示 => 直接點擊欲觀察的網頁元素
    • 在該網頁元素的程式碼部分,可以使用右鍵直接取得 xpath / csspath 的資訊
  • 使用 visual event 觀察頁面上 javascript event 與 UI 的 binding 情況


個人工具箱

我慣用的工具有:(程式執行成本由低到高)
  • requests 函式庫,從 http 的層級解決問題
    • 執行效率最佳
    • 雖然位於底層,但最後不一定會是最繁雜的 solution
      • 可無視許多 application UI 的操作邏輯
    • 若上層的 application 過於複雜,會難以找出合法 http request 的格式
      • 要處理的參數過多會導致需要花費很多時間測試
      • 參數值越依賴 application  的運算,越難生成
      • 隨著頁面跳轉、ajax 呼叫 ... 複雜度會上升
      • 需要自行維持  headers / cookies 的值 ... 手動模仿部分瀏覽器行為
  • mechanize / twill / mechanicalSoup 之類的函式庫,用精簡版的瀏覽器解決問題
    • 執行效率次佳
    • 部分瀏覽器的功能已經被實作,能帶來很大的方便
      • 但是不能執行 javascript ,使得適用範圍小很多
    • 函式庫會附帶一些便捷的 API ,協助填寫表單、點擊連結 ...
    • 適合拿來跑簡單的 functional testing
      • 至少可以不用擔心如何維持瀏覽器的狀態
      • 拿來測 API 也並無不可
  • 使用 phantomjs 等等內嵌 webkit 的工具,透過無視窗介面的瀏覽器解決問題
    • 執行效率欠佳
    • 能執行 javascript ,可高度模擬使用真實瀏覽器的情境
    • 有廣大的社群以此為基礎,開發相關的 testing / automation ... tools
      • casperjs 是高階,極為好用的封裝
        • resurrectio 提供了 chrome plugin,可以人工錄製欲自動化的步驟以後,自動生成以 casperjs 寫的測試程式碼
          • 還在開發初期,頗有機會測試程式碼會出錯,需要人工修改
      • ghost.py 是 python 版本仿 casperjs 的函式庫
        • 依賴 pySlide or pyQT ... 安裝得花功夫
        • 能夠使用的 API 仍比 casperjs 少很多,文件亦不足
        • 優點為:使用 python 寫出的程式碼架構,可讀性比 js 版本高非常多
  • 使用 selenium 驅動瀏覽器,直接人工錄製欲自動化的步驟或進而匯出程式碼
    • 執行效率欠佳,且大都需要視窗環境
      • 驅動真實瀏覽器時,會顯示出視窗,好處是較容易除錯
      • 亦可驅動以 phantomjs 為核心的 ghostdriver,不需顯示出視窗
    • Selenium 的 Python 及各語言 binding,能夠讓開發者在習慣的環境下開發程式
    • 直接使用錄製功能時,記錄下來的動作不一定具備正確重現性
      • 亦即播放時仍可能出錯


使用策略、心得

對於簡單的網頁,特別是無須登入那種,requests 可以說是最佳解
甚至直接使用 pyquery 就能快速完成 crawling + parsing 的工作

但是對於較複雜的網頁,常常會陷入 requests vs. casperjs 的抉擇
當評估用 requests 實作要太多時間,而能接受較慢的執行速度時
casperjs 算是一個比較快速的解法

換言之,以下可能是不錯的使用策略:
  • 需要執行頻率高的 crawling 時,推薦用 requests 
  • 需要執行頻率低或有複雜 application 操作的 automation 時,推薦用 casperjs


實務上,要使用 requests 自幹時
千萬記得到 google / github 找找看有沒有人有做過同樣的事情
即便語言不同,只要能夠看懂 http 相關的操作
也很容易可以寫出自己的版本


反之,即便要走 casperjs 路線
也並不代表會一路順遂,因為仍然有一定的學習成本
  • 高階的 resurrectio 能夠自動產生 casperjs  的  code ,但是不一定 work
  • casperjs 有乍看醜醜,但是其實蠻完善的文件(建議讀完他)
  • 分享幾個使用上的經驗:
    • 網頁會有 popup 視窗的行為,要特別注意
    • 使用 evaluate API 之前,盡可能看看其他 API 是否有提供包好的功能
    • 可以關掉讀取圖片的功能,大幅加速程式速度
    • 我個人會透過擷取圖片功能,事後看各個步驟的執行結果

原本我以為若使用casperjs ,就可以在幾個小時之內馬上完成工作
結果一邊撞 javascript / casperjs 的牆,一邊讀文件後
最後還是花費了超過一天才完成工作 ...
當然,熟悉這個工具以後,會認為付出是划算的


歡迎補完

本文沒有探討 parsing 或是  crawling 的深入議題,僅只是介紹寫寫小 scripts 時的工具
若有朋友知道有什麼好物,請推薦給我啊啊啊!





2014年6月25日 星期三

台南黑客松:用路人小幫手 x 回報大改造

爆肝了幾天,py.Tainan 在 2014 台南黑客松拿到好成績!
(圖片來自 Punnode 的報導)



此次台南黑客松滿足了「台南」、「政府」、「Open Data」的元素
一直嘴砲說改天要跳 g0v 坑的我,只能責無旁貸的參戰下去了 XD

儘管已經硬拉映瑋幫忙設計 APP,評估起來團隊組成還是不夠全面
於是就在 FB 徵人,想不到馬上就找到阿男與小宋 <=熱血地搭高鐵來台南!


題目發想


檢視過台南市政府提供的開放資料後並沒有很大的共鳴
又考量到如果與他人選了同樣的主題,在有限的時間內並沒有做得比別人好的本錢
索性從自身經驗開始發想 ...

「台南有些路段,路面真他媽的不平 .... 」

由於遇到這種路段,發自內心會真的很生氣
就決定做此題目了!(Anger-Driven Development)

於是我進行以下 survey ,了解到市政府對路平專案、路證核發、交通事件回報 ... 的做法
並發現以下問題:

  • 政府有做事,但是民眾不知道
    • 因為不知道,所以無從監督政府的執行
      • 然後就做得很爛
  • 路平、路證、交通事故的資訊散佈在政府的各網站
  • (我)作為民眾不會想知道市政府底下各單位的權責業務範圍,只希望當下問題能被解決
    • 想要查詢的資訊希望能夠即時得知
    • 想要回報的問題,要有便捷的管道可以使用
  • 台南市的 線上即時服務系統 不好使用


Hack Hack Hack


為了解決上述問題,我決定採用以下方式來 Happy Hacking

  • 沒給路平、施工、交通相關的 API ? ... 那就自幹吧!
  • 回報頁面太難用? ... 那也幫政府自幹出 API 好了!
  • 全民通報 APP (民眾版)太難用? ... 乾脆也自幹一個!
    • 需要從民眾的「使用情境」出發
    • 此產品將應用自幹的 API ,讓大家知道 Open Data 後可以有什麼改變

構思至此為止,之後我除了帶團隊成員一起去吃琴牛肉湯以外
大概就沒什麼貢獻了 XDDDD


阿男是台南少數我知道有用 Python 寫 Web 的朋友(之前用 pylons !!)
他這次也毫無意外的使用 ...
呃 ... nodejs + phantomjs + notepad++ 實作出最重要的路平、路證 API
(證明了寫 python 的人也是很喜歡擁抱其他語言的 ... XD )
而且支援了很多我覺得非常重要的投影片


映瑋畢業於成大工設,擁有多年的 iOS 「使用」經驗
儘管沒有設計過 APP,被我凹了以後,短時間內也能幫忙設計出質量俱佳的 APP
重點是 ... 她不會被「架構」、「Open Data」... 等等的術語迷惑
設計能夠從使用者的情境出發!
例如:相簿樣板、標籤、分享到 Facebook 的概念都是由她提出


研替中的小宋本行不在 APP 開發,這次完全是熱血衝下來,邊學邊改 APP
這次黑客松開發壓力最大的人,鐵定就是他了! XD


我在架構跟目標出來以後,就把台南市線上即時服務系統解構成一系列的回報用 API
並做了一個返樸歸真版的回報 page,以此舉例說明可以這樣使用回報 API


成果


在極度缺乏睡眠的情況下,我們終於完成了第一版的 API 開發
50 % 左右的 APP  功能與完整的 APP 設計
週日早上團隊在一陣忙亂中製作完投影片,就一起抱著快掛的身體前往會場

我們在第四組就上場進行三分鐘的限時簡報
原本準備五分鐘的投影片很明顯講不完 ... Orz  



雖然沒講完頗沮喪,卻因為很早完成簡報,所以能夠放輕鬆地聽聽其他組的報告
以及與場內的熟人聊天、打嘴砲  XD

頒獎時原本是預期得獎機會不大(太早出場 + 沒有完成簡報)
最後卻意外地在 35 組中拿到 No.2 ... T___T

四人累到掛掉後 ... 終於得到了肯定!
我們之後也會買網域,並把 API 整理後再度釋出!

  • 本專案目前 focus 在台南,將來會與 g0v 的專案討論看看怎麼合作
  • 本專案屬性與黑客松同組的 Open311 很像
    • 可以透過 API 串接起來
  • 如果有朋友對於我們設計的 APP 有興趣,可與我們聯絡喔!




隨筆雜記


Day 1 恰巧與主持人穿同一件 T-Shirt .. XDDD

  • data.tainan.gov.tw beta 使用 ckan 架設!(python!!)
  • 比賽前我以為只有 40 人參賽 ... 
    • 怎麼算都很有機會得獎 XD
    • 結果第一天看到有 39 隊上百人參賽 ... 囧rz
      • 後來想通,在 kktix 上一隊只會顯示出一人 ...
  • 我最看好的百年地圖果然得到很高的評價!!
  • 映瑋被團隊一致選為:最適合當 PM 的人
  • 記得嗎?拍照時那張很大的「第二名」板子
    • 「沒有人」毫不猶豫把第一名的板子留給我們
    • 然後映瑋就把第一第二名的板子對切,當作材料回收走了... o.o"
  • 當初團隊取名 py.Tainan 其實就是 Tainan.py 的倒裝
  • 前同事的隊伍其實有做一個超有梗的拍照樣板 XDDDD
  • 主辦單位直接發現金,非常有誠意!
    • 小宋賺回了台北台南來回高鐵錢 : )