1. 程式人生 > >python+selenium+phantomjs 踩坑

python+selenium+phantomjs 踩坑

在寫爬蟲時遇到有些網頁載入超時的情況,以下對比一下他們的優缺點:

WebDriverWait():selenium設定元素髮現超時等待時間
WebDriverWait()函式是在在設定時間內,預設每隔一段時間檢測一次當前頁面所指定元素是否存在,如果超過設定時間檢測不到則丟擲異常。

用法: WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located((By.ID, "kw")))

until(method,message):

  • method: 在等待期間,每隔poll_frequency時間之後呼叫這個傳入的方法,直到返回值不是False或者超出timeout時間範圍才不再執行
  • message :如果超時,丟擲TimeoutException,將message傳入異常

注: until_not 與until方法剛好相反,until是當某元素出現或什麼條件成立則繼續執行,until_not是當某元素消失或什麼條件不成立則繼續執行,引數也相同,

WebDriverWait():

In [12]: WebDriverWait()
 driver=                               %%!
 ignored_exceptions=                   "Application Data"
 poll_frequency=                       "Local Settings"
> self= "My Documents" timeout= "Saved Games"
  • driver: WebDriver 的驅動程式
  • timeout:最長超時時間,預設以秒為單位
  • poll_frequency:呼叫until或until_not中的方法的休眠時間的間隔(步長)時間,預設為 0.5 秒
  • ignored_exceptions:這裡設定忽略的異常如果在呼叫until或until_not的過程中丟擲中的異常元組中, 則不中斷程式碼,繼續等待,如果丟擲的是這個元組外的異常,則中斷程式碼,丟擲異常。預設只有NoSuchElementException。

在使用 presence_of_element_located()函式檢查元素是否存在或載入完成時,這個函式傳入的是一個元組引數,而非兩個單獨的引數,錯誤程式碼如下:

In [12]: WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(By.ID, "kw"))
---------------------------------------------------------------------------
TypeError  Traceback (most recent call last)<ipython-input-12-84622169566b> in <module>()
----> 1 WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(By.ID, "kw"))

TypeError: __init__() takes exactly 2 arguments (3 given)

只需要一個引數,並且只能是一個元組,正確寫法如下:

In [13]: WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located((By.ID, "kw")))
Out[13]: <selenium.webdriver.remote.webelement.WebElement (session="b0f52d40-582
d-11e7-9ffc-7d9ee5fd2752", element=":wdc:1498233922094")>

implicitly_wait(timeout):隱式等待

如果某些元素沒有找到, 不是立即可用的,隱式等待是告訴WebDriver去等待一定的時間後去查詢元素。 預設等待時間是0秒,一旦設定該值,隱式等待是設定該WebDriver的例項的生命週期。

sleep:程序等待

有些時候我們喜歡將程序睡眠幾秒鐘而使網頁載入完成。

三者的比較

測試用例如下(本例為了測試時間找了一個網頁中沒有的標籤進行測試):

WebDriverWait()用例

import datetime
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

dcap = dict(DesiredCapabilities.PHANTOMJS)
user_agent = "Mozilla/5.0WindowsNT6.1WOW64AppleWebKit/535.8KHTML,likeGeckoBeamrise/17.2.0.9Chrome/17.0.939.0Safari/535.8"
dcap["phantomjs.page.settings.userAgent"] = user_agent
driver = webdriver.PhantomJS(desired_capabilities=dcap)
# driver.implicitly_wait(10)
start_time = datetime.datetime.now()
print 'start_time: ', start_time
driver.get('https://www.baidu.com')
t = datetime.datetime.now()
try:
    element = WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.CLASS_NAME, "gettell")))
    element.click()
except Exception, e:
    print e
end_time = datetime.datetime.now()
print "Sds", (t - start_time).seconds
print "time", (end_time - start_time).seconds
driver.quit()

測試結果:

E:\usr\Anaconda2\python.exe C:/Users/Administrator/Desktop/ershouche/wait.py
start_time:  2017-06-24 03:29:41.140000
Message: 
Screenshot: available via screen

Sds 0
time 11

Process finished with exit code 0

可以看到總用時10秒, 開啟網頁小於1秒,等待10秒。查詢元素小於1 秒。下例查詢網頁中存在的元素:

import datetime
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

dcap = dict(DesiredCapabilities.PHANTOMJS)
user_agent = "Mozilla/5.0WindowsNT6.1WOW64AppleWebKit/535.8KHTML,likeGeckoBeamrise/17.2.0.9Chrome/17.0.939.0Safari/535.8"
dcap["phantomjs.page.settings.userAgent"] = user_agent
driver = webdriver.PhantomJS(desired_capabilities=dcap)
# driver.implicitly_wait(10)
start_time = datetime.datetime.now()
print 'start_time: ', start_time
driver.get('https://www.baidu.com')
t = datetime.datetime.now()
try:
    element = WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.ID, "su")))
    element.click()
except Exception, e:
    print e
end_time = datetime.datetime.now()
print "Sds", (t - start_time).seconds
print "time", (end_time - start_time).seconds
driver.quit()

測試結果:

E:\usr\Anaconda2\python.exe C:/Users/Administrator/Desktop/ershouche/wait.py
start_time:  2017-06-24 03:42:04.557000
Sds 0
time 0

Process finished with exit code 0

從此結果看出,開啟網頁速度小於1秒,查詢元素時間少於1秒,程式執行只需要不到一秒就完成了。所以我們得到的結果是:

  • WebDriverWait()只要在最大時間內找到元素就會繼續向下執行程式,沒有找到就繼續按照時間間隔去查詢,直到超過最大時間限制則丟擲超時異常

implicitly_wait(timeout)用例

import datetime
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
dcap = dict(DesiredCapabilities.PHANTOMJS)
user_agent = "Mozilla/5.0WindowsNT6.1WOW64AppleWebKit/535.8KHTML,likeGeckoBeamrise/17.2.0.9Chrome/17.0.939.0Safari/535.8"
dcap["phantomjs.page.settings.userAgent"] = user_agent
driver = webdriver.PhantomJS(desired_capabilities=dcap)
start_time = datetime.datetime.now()
print 'start_time: ', start_time
driver.implicitly_wait(10)
driver.get('https://www.baidu.com')
t = datetime.datetime.now()
driver.save_screenshot("ssd.png")
ts = datetime.datetime.now()
try:
    driver.find_element_by_id("su").click()
except Exception, e:
    print e
end_time = datetime.datetime.now()
print "Sds", (t - start_time).seconds
print "time", (end_time - start_time).seconds
print "s", (ts - start_time).seconds
driver.quit()

測試結果如下:

start_time:  2017-06-24 04:14:36.779000
Sds 0
time 0
s 0

開啟網頁時間小於1秒, 總用時1秒,查詢元素時間也小於1秒,說明webdriver在能找到元素時無需等待。再來查詢一個頁面中不存在的元素

import datetime
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
dcap = dict(DesiredCapabilities.PHANTOMJS)
user_agent = "Mozilla/5.0WindowsNT6.1WOW64AppleWebKit/535.8KHTML,likeGeckoBeamrise/17.2.0.9Chrome/17.0.939.0Safari/535.8"
dcap["phantomjs.page.settings.userAgent"] = user_agent
driver = webdriver.PhantomJS(desired_capabilities=dcap)
start_time = datetime.datetime.now()
print 'start_time: ', start_time
driver.implicitly_wait(10)
driver.get('https://www.baidu.com')
t = datetime.datetime.now()
try:
    driver.find_element_by_id("su").click()
except Exception, e:
    print e
ts = datetime.datetime.now()
try:
    driver.find_element_by_id("sudf").click()
except Exception, e:
    print e
end_time = datetime.datetime.now()
print "Sds", (t - start_time).seconds
print "time", (end_time - start_time).seconds
print "s", (ts - start_time).seconds
driver.quit()

測試結果:

E:\usr\Anaconda2\python.exe C:/Users/Administrator/Desktop/ershouche/wait.py
start_time:  2017-06-24 04:18:43.785000
Message: {"errorMessage":"Unable to find element with id 'sudf'","request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"85","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:57585","User-Agent":"Python http auth"},"httpVersion":"1.1","method":"POST","post":"{\"using\": \"id\", \"sessionId\": \"27957130-5851-11e7-a4d7-9740be247d0a\", \"value\": \"sudf\"}","url":"/element","urlParsed":{"anchor":"","query":"","file":"element","directory":"/","path":"/element","relative":"/element","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/element","queryKey":{},"chunks":["element"]},"urlOriginal":"/session/27957130-5851-11e7-a4d7-9740be247d0a/element"}}
Screenshot: available via screen

Sds 0
time 10
s 0

Process finished with exit code 0

這個結果是開啟網頁用時小於1秒, 第一次查詢元素耗時小於1秒, 第二次查詢沒找到,則webdriver等待了10秒中,從這四個例子中可以看到,WebDriverWait()是設定間隔不斷去找,找到就繼續執行,找不到就丟擲超時異常,implicitly_wait(timeout)先找一次,找不到了等待timeout的時間之後繼續找,找到了就繼續向下執行,找不到就丟擲異常;在下面的程式裡如果出現查詢元素的情況規則同上步驟,因此他是對整個模組起作用的,不需要重寫。而sleep就比較死板了,我設定睡眠多長時間,它就睡多長時間。

綜合上面的例子可得,當頁面載入不完全時適合使用implicitly_wait(timeout),當局部JS載入緩慢時我們可使用WebDriverWait(),我不建議用sleep來等待頁面或JS的載入。

如有疑問請加qq群:526855734

相關推薦

python+selenium+phantomjs

在寫爬蟲時遇到有些網頁載入超時的情況,以下對比一下他們的優缺點: WebDriverWait():selenium設定元素髮現超時等待時間 WebDriverWait()函式是在在設定時間內,預設每隔一段時間檢測一次當前頁面所指定元素是否存在,如果超過設定時

python+selenium+PhantomJS爬取網頁動態加載內容

use for ive comm 自動化測試 mac os x page 影響 blank 一般我們使用python的第三方庫requests及框架scrapy來爬取網上的資源,但是設計javascript渲染的頁面卻不能抓取,此時,我們使用web自動化測試化工具Selen

Python之類變數

1、首先是這樣有個類變數,你要在使用的,如果前面不加類名,那在方法裡就會去找全域性變數 顯然current_workspace_path是個類變數 class MainAc(object): window_TITLE = "Alu測試組工具合集_v1.0" current

[Python-Selenium] 入門總結+點陳列

這文章主要介紹了: 如何入門Selenium Selenium進階指南 坑點陳列 1. 如何入門Selenium Selenium主要涉及動態網頁的爬取,一般都是結合F12,或者BeautifulSoup一起服用效果更佳。那麼最開始如何從0開始入門呢 當然從安裝做起

python菜鳥系列-虛擬機器docker載入python專案映象並且執行

docker載入映象 docker load --input xxxx.tar docker建立一個新的容器,指定埠對映,例如8080指向容器的8000埠 docker run --nam

python+selenium+phantomjs實現爬蟲功能

一.phantomjs介紹 phantomjs是一個基於webkit核心的無頭瀏覽器,即沒有UI介面,即它就是一個瀏覽器,只是其內的點選、翻頁等人為相關操作需要程式設計實現。 提供javascript API介面,即通過編寫js程式可以直接與webkit核心

Python Selenium + PhantomJS爬取考拉海購商品資料

爬完QQ音樂以後打算爬網易雲音樂的,中間出了一點小狀況,就改爬考拉海購了(什麼狀況你猜呀❛˓◞˂̶✧以後會爬完網易雲音樂的!) 今天寫近段時間的最後一篇,寫完這篇就要開始期末複習了,寒假再來更新 pip install selenium 下載s

linux爬蟲開發環境配置python+selenium+phantomJS

你可能會遇到以下問題不知道怎麼解決,raise exception_class(message, screen, stacktrace) selenium.common.exceptions.WebDriverExce

python selenium

from int find 微博 登陸 selector pytho row exce 想做做信息檢索課設,先寫個爬蟲爬爬微博。 看了一下午微博的api,晚上決定用chromnium。 先通過pip安裝selenium,官方文檔看一眼, pip install sel

[Python爬蟲] 之十五:Selenium +phantomjs根據微信公眾號抓取微信文章

頭部 drive lac 過程 標題 操作 函數 軟件測試 init   借助搜索微信搜索引擎進行抓取   抓取過程   1、首先在搜狗的微信搜索頁面測試一下,這樣能夠讓我們的思路更加清晰        在搜索引擎上使用微信公眾號英文名進行“搜公眾號&r

[Python爬蟲] 之十九:Selenium +phantomjs 利用 pyquery抓取超級TV網數據

images 判斷 nco dex onf etc lac lin 利用   一、介紹     本例子用Selenium +phantomjs爬取超級TV(http://www.chaojitv.com/news/index.html)的資訊信息,輸入給定關鍵字抓取

python爬蟲 selenium+phantomjs動態解析網頁,加載頁面成功,返回空數據

img 使用 一個 做的 ima 導數 技術分享 信息 之前 廢話不多說,直接說重點: 剛開始做的時候,代理IP,頭部信息池,都已經做好了,使用selenium+phantomjs獲取js動態加載後的源碼 起初挺好的,能出來動態加載後的源碼,但是運行了幾次之後,電腦有點卡頓

Python爬蟲小白---(二)爬蟲基礎--Selenium PhantomJS

decode bject windows beautiful 結構 由於 target header 速度 一、前言    前段時間嘗試爬取了網易雲音樂的歌曲,這次打算爬取QQ音樂的歌曲信息。網易雲音樂歌曲列表是通過iframe展示的,可以借助Selenium獲

python+selenium自動化軟件測試(第6章):selenium phantomjs頁面解析使用

前端 down word logs pan canvas 鼠標 agent 瀏覽器中 我們都知道Selenium是一個Web的自動化測試工具,可以在多平臺下操作多種瀏覽器進行各種動作,比如運行瀏覽器,訪問頁面,點擊按鈕,提交表單,瀏覽器窗口調整,鼠標右鍵和拖放動作,下拉框和

盤點selenium phantomJS使用的

效率 scrip gen time self. doc http width 並發 說到python爬蟲,剛開始主要用urllib庫,雖然接口比較繁瑣,但也能實現基本功能。等見識了requests庫的威力後,便放棄urllib庫,並且也不打算回去了。但對一些動態加載的網站,

python+selenium環境搭建以及遇到的

三方庫 很大的 第三方庫 git 工具 解壓縮 .py clas 安裝python ---恢復內容開始--- window10下環境搭建 1.安裝python https://www.python.org/downloads/ 在該網址下下載python最新版本,點擊

Python爬取異步加載的網站selenium+PhantomJS

ron .com .html scrip psu 語言 sel 文字 get 一個網站的爬蟲腳本,在調試的時候發現問題: 腳本跑:content-type用text/xml 可以post成功,但post中body的內容沒有生效,所有的響應都是當前日期;用applicatio

selenium+PhantomJS小案例—爬豆瓣網所有電影代碼python

utf-8 str num %s com star open main link #coding=utf-8from selenium import webdriverdef crawMovie(): driver=webdriver.PhantomJS() d

python 3.6.1 安裝scrapy之旅

ext href sta 版本 deb targe IE src pyw 系統環境:win10 64位系統安裝 python基礎環境配置不做過多的介紹 window環境安裝scrapy需要依賴pywin32,下載對應python版本的exe文件執行安裝,下載的pywin