亚洲好骚综合-亚洲黄色录像-亚洲黄色网址-亚洲黄色网址大全-99久久99久久-99久久99久久精品国产

您的位置:軟件測試 > 開源軟件測試 > 開源功能測試工具 > Selenium
Selenium+PhantomJS的爬蟲那些事兒
作者:Mr.Kua 發布時間:[ 2017/3/7 15:01:00 ] 推薦標簽:功能測試 Selenium 進程

  0x00
  近寫爬蟲分析灰色網站,要使用無頭瀏覽器動態加載網頁,使用selenium+PhantomJS, 自己研究的時候遇到了一些比較有意思的坑,和大家分享一下。
  0x01
  先說一下架構,在大規模爬取網頁內容的時候,為了提高性能,降低存儲和計算開銷,單個PhantomJS進程往往需要連續處理大量的URL,那么針對單個PhantomJS進程在連續處理不同URL的時候,往往會出現一些意想不到的問題。
  例如,由于我們需要通過
from selenium import webdriver
d = webdriver.PhantomJS()
d.set_page_load_timeout('10')
d.implicitly_wait('10')
d.get(url)
d.current_url
  這樣的方式記錄給予Phantomjs引擎的原始URL和PhantomJS動態加載后的URL,但是當單進程PhantomJS大量處理URL時,我們發現有許多原始URL和動態加載后的URL完全無法對應。這會是什么原因導致的呢?
  目前遇到的情況而言,大體分為兩種情況導致:
  網頁內部存在onbeforeunload事件調用使得網頁無法被正常關閉。
  待訪問資源不可用。
  0x02 onbeforeunload
  我們來看一個比較有意思的網頁,在爬取到該網頁所在的URL之后,phantomjs”停止了工作“, 所有后續給phantomjs處理的URL 其調用current_url返回的URL值都是這個特殊網頁的URL,以下是該網頁內含部分HTML代碼:
  <BODY onbeforeunload="return('你確定仔細閱讀此文章了嗎?')" style="margin:0px;"><iframe border="0" name="lantk"  width="0" height="0" allowtransparency="" scrollbars="yes" frameborder="0"></iframe>
  形如 <ELEMENT onbeforeunload="handler"> 的代碼會注冊一個事件,當瀏覽器引擎卸載當前HTML文檔之前拋出一個對話框,用戶可以確認是否他要離開這個網頁。 對應在Javascript中,可相應的對該事件進行處理:
  object.onbeforeunload = handler;
  object.addEventListener("beforeunload", handler, useCapture);
  事件是DOM事件的簡稱,根據w3.org DOM的文檔 1.4.2 Complete list of event types:unload事件類型的實現將從環境中移除該網頁文檔自身和其附帶的所有資源,包括圖片、CSS、和Javascript腳本。在運行這樣的事件之后文檔將被卸載。
  那DOM的設計者們設計onbeforeunload事件的本意是什么?onbeforeunload存在的意義在于,你無法通過javascript腳本形式對其進行處理,如果用戶想要離開某個網頁,那么你無法阻止他離開這個網頁,你也無法在用戶點擊關閉網頁(觸發unload事件時)進行其他阻止用戶離開的活動,為了安全性考慮,用戶的自由是第一位的,網頁編寫者無法將用戶”囚禁“在網頁應用程序中。
  在IE瀏覽器中,可以通過自定義字段來建立自定義消息,如上述代碼中的 return(‘你確定仔細閱讀此文章了嗎?' ,而在其他瀏覽器中,這個事件不會顯示自定義的消息。
  那么在我們的案例中,原因在于phantomjs接收到URL并加載了網頁DOM之后,受困于onbeforeunload事件,導致代碼中沒有拋出異常,然而引擎也永遠停留在了當前頁面,對于后續接收到的任務不予處理。
  URL無法訪問的其他情況
  除了上述的情況導致phantomjs異常以外,還有一種由于URL無法訪問導致current_url異常的情況,這種情況可以在如下三種子條件下觸發:
  DNS查詢返回域名不存在,無論是本地hosts還是遠程DNS服務器的返回都可以。
  URL的無法返回正常HTTP響應。
  單獨通過phantomjs訪問上述兩種情況的URL,current_url將會返回 about:blank , 然而如果同一phantomjs進程曾經處理過其他URL, 則由于上述兩種情況,phantomjs driver沒有真正去處理第二個URL。
  我們可以把phantomjs的狀態簡單的視為一個狀態機模型,由于在處理一系列URL時候狀態是連續傳遞下去的,通過輸入,會改變狀態機的狀態,而滿足上述任意一個條件的輸入,將導致phantomjs狀態停留在原位,當用戶簡單將輸入和輸出進行對應的時候會出現問題。
  0x03 解決方案
  針對onbeforeunload的問題,可以在獲取網頁源碼后加入對使用onbeforeunload的網頁使用phantomjs自身對網頁中注入js腳本進行處理。然而這樣會造成一定的性能下降。
  針對URL無法訪問的情況,有兩種方案: 1.可以在phantomjs處理每個任務之前先進行DNS查詢,對于無DNS解析記錄的可以不用提交phantomjs處理。然而這種方案對于IP類URL沒有很好的控制。 2。可以在phantomjs每個任務之間插入 driver.get('http://about:blank') 這樣可以間接避免上一個URL的狀態污染到下一個任務。
  然而,這兩種方法都是治標不治本,根本解決方案應該是將每phantomjs會話之間的執行完全隔離,我們使用selenium連接phantomjs后端其實使用的是detro開發的ghostdriver,是一個Remote WebDriver Wire protocol的Phantomjs實現,根據 Github上的鏈接 ,以及作者ghostdriver庫github頁首的簡介,項目開發者由于生活的壓力已經兩年沒有更新了。。你們說Github是不是應該開一個打賞機制?

軟件測試工具 | 聯系我們 | 投訴建議 | 誠聘英才 | 申請使用列表 | 網站地圖
滬ICP備07036474 2003-2017 版權所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd
主站蜘蛛池模板: 在线免费视频一区 | 亚洲va欧美ⅴa国产va影院 | 美腿丝袜亚洲综合 | 色视网站 | 伊人激情久久综合中文字幕 | 91情国产l精品国产亚洲区 | 久久综合婷婷香五月 | 成人激情文学 | 天天射天天爱天天干 | 天天透天天射 | 欧美 video| 一级毛片看一个 | 欧美日韩在线成人免费 | 免费的黄色小视频 | 韩国 伦理 在线 | 在线观看免费国产视频 | 成人一级大片 | 国产精品亚洲片在线观看不卡 | 美腿丝袜中文字幕 | 爽爽影院在线 | 久久一卡二卡 | 波多野结衣久久一区二区 | 一本一道dvd在线播放器 | 一级毛片q片 | 国产一国产一级新婚之夜 | 男女啪啪免费体验区 | 欧美日韩一区二区三区在线播放 | 波多野结衣在线视频播放 | 午夜草草| 天天舔天天色 | 天天碰天天操 | 成年黄网站在线观看免费 | 2021天天操 | 99r在线视频 | 一及毛片 | 亚洲综合一区国产精品 | 亚洲午夜视频 | 亚欧乱色视频网站大全 | 欧美视频网站免费看 | 91精品福利一区二区三区野战 | 亚欧乱色视频网站大全 |