前 言
所謂爬蟲,簡單來說就是通過網(wǎng)絡(luò)請求獲取內(nèi)容并解析出結(jié)果的過程,當中以網(wǎng)頁爬蟲最為常見。然而隨著Web應(yīng)用的日益復(fù)雜化,各種Ajax和JS加持的Web頁面對于爬蟲來說,在請求內(nèi)容這第一步就造成了不小難度。爬蟲工程師們往往不得不苦于分析網(wǎng)頁請求中各種不明意義的字段,開始一段心酸的JS探尋之旅。而此時,來自測試領(lǐng)域的一套自動化測試工具,卻給爬蟲工程師們帶了新的曙光——她,就是Selenium。
關(guān)于Selenium
Selenium是一套Web應(yīng)用的自動化測試框架,擁有完整的瀏覽器支持,通過模擬瀏覽器的真實操作實現(xiàn)Web應(yīng)用測試,并且提供簡單好用的錄制/回放工具讓使用者無需了解腳本語言就能寫出可以執(zhí)行的測試用例。
Selenium底層由各種web driver驅(qū)動,提供豐富的API接口。對Python/Java等語言的支持,再配合上headless的瀏覽器(如PhantomJS),注定會成為爬蟲工程師手中的利器!
實踐看亮點
準備
Python 2.7.12
python-selenium 3.0.0
Selenium Webdriver(本文因可視化展示所需,所以用到chromedriver,實際爬蟲應(yīng)用中,一般常用PhantomJS作為headless瀏覽器)
亮點
1、完整的Web支持
得益于Selenium的運行機制,因為實際啟用了瀏覽器,所以能夠?qū)eb應(yīng)用進行完整的支持。一句話:瀏覽器看到的樣子就是爬蟲可以獲取到的內(nèi)容,所以在用Selenium編寫爬蟲的過程中,爬蟲開發(fā)者不用再糾結(jié)于網(wǎng)頁請求的分析,只需關(guān)注于頁面解析即可。
以某企業(yè)信息查詢網(wǎng)站查詢“星巴克”為例,抓包可知其實際查詢請求如下:
如圖可見該接口的請求cookie中帶有一個神奇的token字段。令人比較遺憾的是,該token并非是來自于其它請求的返回,而是由JS生成。
通常情況下,需要找到生成該token的JS代碼段,分析其輸入輸出,使用JS執(zhí)行器或者將該部分JS的邏輯自行實現(xiàn),以獲得token。而使用Selenium編寫爬蟲,則不用關(guān)心這個部分,短短幾行就可以完成一次頁面查詢。代碼示例:
從查詢結(jié)果頁的URL來看,我們還能更進一步簡化查詢操作,甚至一句代碼就能完成,如下:
2、支持響應(yīng)式交互
瀏覽網(wǎng)頁中,經(jīng)常會遇到執(zhí)行某些操作后才出現(xiàn)相關(guān)頁面元素的情況。這種場景用普通爬蟲方式很難模擬,但對于Selenium來說,卻有著先天優(yōu)勢。
以中國電信登錄頁為例,對于多次登錄錯誤的帳號會出現(xiàn)圖片驗證碼,而該驗證碼只有在輸入帳號后才會出現(xiàn)。普通做法,分析整個過程中執(zhí)行了哪些請求,請求cookie和請求參數(shù)如何獲得,然后模擬發(fā)送請求獲取結(jié)果。例如該場景中,通過抓包分析可知當中有三次關(guān)鍵請求(如圖)。
第一次根據(jù)號碼獲得城市代碼,第二次檢查對應(yīng)手機號登錄是否需要驗證碼,第三次獲取驗證碼圖片。
然而僅僅看這三次請求,其所需輸入都是欠缺的,因此整個分析過程會變得非常繁雜。此時使用Selenium直接模擬登錄操作,不失為一種簡單有效的方法。整個模擬過程如圖所示:
代碼示例:
3、豐富的html解析支持
Selenium API提供豐富的方法獲取頁面元素,支持多種方式進行元素定位選擇,比如根據(jù)元素id,name,xpath,css選擇器等。
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
當然同時也支持直接返回網(wǎng)頁源代碼,然后再自行使用其它第三方html解析庫進行解析。
4、動作鏈(ActionChains)
動作鏈是Selenium提供的用于模擬自動化交互的方式,如鼠標移動,鼠標按鍵點擊,鍵盤按鍵點擊和復(fù)雜菜單交互等等。在復(fù)雜的動作場景中,比如拖拽和滑動,非常有用。
基于此,Selenium爬蟲可以實現(xiàn)一些普通爬蟲難以實現(xiàn)的功能,比如特征位點擊、滑動驗證碼自動驗證等。以某常見滑動驗證碼為例,合理使用動作鏈可以實現(xiàn)自動驗證,效果如下圖所示:
注:具體實現(xiàn)方式不在本文敖述,大概思路為:獲取完整背景圖片及缺塊圖片,通過比較獲得缺塊位置,得出滑動距離,再用Selenium模擬鼠標拖拽滑動實現(xiàn)自動滑動驗證。示例中可以看出兩次嘗試后才驗證成功。因此成功率并非100%,所以加入自動重試以保證驗證結(jié)果。
總結(jié)
優(yōu)點
通過以上幾個例子可以看出,在網(wǎng)頁爬蟲中應(yīng)用Selenium的優(yōu)勢特別明顯。
完全瀏覽器化的操作簡化掉了請求分析的過程,讓爬蟲開發(fā)更多關(guān)注于頁面解析和結(jié)果處理。
爬蟲實現(xiàn)難度比較低。對于某些特殊的場景,比如對同樣功能的查詢類網(wǎng)站進行查詢接口封裝,Selenium能夠通過模擬瀏覽器的查詢操作快速實現(xiàn)。
缺點
因為Selenium實際上使用了瀏覽器,所以其缺點也顯而易見。
資源占用大,每開一個瀏覽器進程就會占用將近20MB左右內(nèi)存,在爬蟲應(yīng)用中需要進行及時關(guān)閉釋放,因此這也注定了Selenium爬蟲不適用于批量爬取。
速度慢,因為瀏覽器請求頁面會加載所有相關(guān)的資源請求,同時還有頁面操作的模擬過程,會導(dǎo)致爬蟲的執(zhí)行周期較長,因此也不適用于即時性要求較高的場景。
來自于測試領(lǐng)域的Selenium,對于爬蟲應(yīng)用來說是一柄利劍同時也是一把重劍,只有恰當?shù)娜∩岷蜏蚀_的使用才能真正達到“他山之石,可以攻玉”的最終目的。
本文作者:彭英杰(點融黑幫),就職于點融成都Data Team,負責(zé)接口集成以及爬蟲開發(fā)工作。喜歡折騰新事物,愛游戲,愛運動。