有將近一個月沒寫文章了,懶人日常就是糾結于寫還是不寫,有沒有必要寫之間。想寫的主題確實有一些,但磨磨蹭蹭到最后一篇也沒寫。
今天想寫一篇與Android無關的技術內容,語言是相通的,只要需求分析清楚,用什么語言來實現倒是其次。
先來看看一下午用python折騰出來的結果(整個耗時10s):
需求
通過python腳本自動添加git@osc的權限
背景
我有不少代碼是私有的,正常邏輯下給一個人添加權限的scenario:
- 登錄git@osc
- 進入項目
- 項目設置
- 項目成員管理
-
添加
python01.png
如果有多個項目需要添加權限,那就要重復上述步驟。每次的操作耗費的時間成本在2分鐘/人。
解題過程
好歹咱也是個程序員啊,總不能老是被這些重復又單調的事情所困擾。所以我打算用代碼來解決它。
如果你對Stay分析問題的思路與解決問題的技巧感興趣,不妨接著往下看。即使不會python也沒關系,因為我也不怎么會:)
本篇文章算是對之前文章80%的問題,按這個套路都能找到解決方案的案例補充。
git@osc有現成的API嗎?
這個問題應該問誰最方便?當然是wiki啊。如果官方都沒有給你提供解決方案,那你就木有正規途徑可以走了。好吧。找了一圈git@osc,沒有發現open api。pass。oscchina的open api倒是有,并且還有官方開源的android客戶端,想參考的同學可以看看。
既然沒有正規途徑可走,那就來點黑科技咯。google下看看有沒有爬下來整理的私有api。關鍵詞(gitosc open api) er... 好吧,gitosc還不夠有名,沒人愿意爬它的API list。
寫代碼是唯一的方法嗎?
其實這個需求的優先級并不那么高,如果能快速的解決它,花半天時間我是愿意的。但如果超過就不劃算了,畢竟現在的基數也不大,一天可能也就操作一次而已。2分鐘還是耗的起。
好吧,其實我是想放棄了。我這么怕麻煩的人,寧愿每次都花2分鐘,也不愿意當下多花的時間來一勞永逸。等等,再容我想想...
以前每當我花這兩分鐘的時候,我都在想,這純體力勞動,能自動化得多好啊。這時候我就想起郭神的slogan:
每當你在感嘆,如果有這樣一個東西就好了的時候,請注意,其實這是你的機會
即使不寫代碼,最差我也能用按鍵精靈寫出來啊。頁面是固定的,每個UI component坐標都是固定的。逼急了就寫一個只能在自己機器上跑的按鍵精靈腳本。每次只需要設置好初始參數,run就可以了。
慢著...這不對勁啊,雖然解放了雙手。特么電腦還是要run腳本,模擬屏幕點擊啊。有時候為了等頁面刷新,還要多加一些時間等待。可能2分鐘人工就能完成的事,用按鍵精靈要花3分鐘了。
傻傻的看著電腦模擬點擊響應,這我可忍不了。就跟在android用robotium寫自動化測試一樣無聊。按鍵精靈,pass...
不就是寫代碼么
理論上來說,你會多少種語言,就能寫多少種實現。既然決定用代碼實現,那就先拆分需求吧。
- 從登陸到添加權限一共有5步,中途load的網頁有host/login, host/project, host/project/setting, host/project/team_member/new。
注:host=git.oschina.net - 通過chrome開發者工具network console,需要提交表單的地方就兩個,一個登陸,一個添加權限。
- git@osc每一個頁面都生成一個token,當內部請求api需要帶上這個token
- 添加權限時的form需要賬號對應的userid,而不是username
- userid可以通過api搜索username對應的結果集,需要檢查唯一性,避免添加錯誤的user
認真調研下來,其實就是請求幾個url,解析幾個標簽,post幾個form表單。任務就搞定了。糾結的就是,該用什么語言來實現呢。假如你只會android,沒事,java肯定可以寫出來。至于是多少代碼量就無法保證了。涉及到的知識點(JSOUP+HttpUrlConnection+CookieManager)
選什么語言好呢?
google: 模擬網頁登陸
搜下來的結果集都是python版的(不過也可能是因為我經常搜python使然),python在數據采集上的優勢是公認的。像這么簡單的需求,用PHP,ruby都能輕松實現。不過PHP需要部署,沒有python和ruby跑起來方便。
其實Stay上個月斷斷續續的在看python,選python也是想檢驗學習成果。
在google搜索結果集了,盡量早發布時間較新的文章,技術更新太快了,很可能12,13年的老帖已經無法適用現在的需求了,通過google,找到一個github repo fuck-login。模擬一些國內知名的網站登陸。雖然沒有git@osc的網站登陸,不過照貓畫虎,實現起來也挺快的。
代碼實現
參考了不少文章,有幾個通用代碼塊,先copy出來。
在每次request之后需要手動同步cookie。session.cookies.save()
class TokenParser繼承的HtmlParser,HtmlParser是用來解析html的工具類。
有了以上來個基礎,剩下來的就是寫request了。因為可以直接通過腳本來請求request,所以不需要按照web操作的scenario一步步來。只要拼接好url就可以了。這樣可以省略2,3步,只需要1登陸,4成員管理頁面,5添加權限就夠了。
一步步完成吧。
登陸實現
formdata是通過chrome的network console查出來的。有興趣的可以自己找個網站試試。chrome->settings->More Tools->Developer Tools->Network
fetch_access_token(url)
方法是load login頁面,解析整個html文本中的token標簽對應的值。取出來賦值給formdata中的authenticity_token
。這樣模擬網頁登陸,通過服務器token校驗。
所幸git@osc不需要驗證碼,不然還得加個gui模塊,把圖片load出來,讓用戶手工輸入驗證碼再登陸
添加某項目權限
一樣,先load項目成員管理頁面,通過fetch_access_token(url)
取token。拼裝好formdata,調用API添加一個成員到項目中去。
userid怎么來的?
這個API相當于模糊搜索,返回的是git@osc賬號合集。
[{"id":340944,"name":"stay4it","username":"stay4it","hash":"0a5cd60ed0a5b79259b0eb6f8b23afe5","avatar":"http://git.oschina.net/uploads/44/340944_stay4it.jpg?1437179788"}]
解析json里的id就可以了。因為結果集是jsonarray,所以需要判斷唯一性。
由于fetch_user(q)
需要拿到唯一的userid,否則后續添加權限的操作都不能執行。所以腳本執行順序可以調整下:
- login()
- fetch_user(q): userid
- join_project(project, userid)
通過上述代碼就可以將一個賬號添加到一個project中了。大功告成。
剩下的就是一些簡單優化,以及一個賬號添加多個project權限等需求擴展了。
整個代碼150行搞定。雖然只有150行,期間調研方案,通過chrome console爬數據,token解析,formdata調試,還有一些python語法不熟悉需要現查。整體從立項到實現花了3個小時。
結束語
寫代碼是個很有趣的過程。如果一上來就想著找現成的代碼,或者直接問大神怎么寫,可能就要花好幾天了。除非你有相關領域的大神朋友,否則還是像Stay這樣好好分析需求,解決問題吧。
寫代碼只是需求實現的最后一環,考慮清楚了再寫要比上來就胡亂寫代碼要高效得多。
常思考,常實踐,別局限于某種語言,而是從生活化的需求著手分解,列出一個個小的task。按部就班的去實現它,不會的現查。久而久之,就成了全干工程師(?????????)
推薦閱讀: