国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---37、動態(tài)渲染頁面抓取:Selenium

zhjx922 / 2226人閱讀

摘要:不過動態(tài)渲染的頁面不止這一種。再有淘寶這種頁面,它即使是獲取的數(shù)據(jù),但是其接口含有很多加密參數(shù),我們難以直接找出其規(guī)律,也很難直接分析來抓取。我們用一個實例來感受一下在這里們依然是先打開知乎頁面,然后獲取提問按鈕這個節(jié)點,再將其

上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---36、分析Ajax爬取今日頭條街拍美圖
下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---38、動態(tài)渲染頁面抓取:Splash的使用

在前面一章我們了解了 Ajax 的分析和抓取方式,這種頁面其實也是 JavaScript 動態(tài)渲染的頁面的一種情形,通過直接分析 Ajax 我們?nèi)匀豢梢越柚?Requests 或 Urllib 來實現(xiàn)數(shù)據(jù)的抓取。

不過 JavaScript 動態(tài)渲染的頁面不止 Ajax 這一種。比如中國青年網(wǎng):http://news.youth.cn/gn/,它的分頁部分是由 JavaScript 生成的,并非原始 HTML 代碼,這其中并不包含 Ajax 請求。如 ECharts 的官方實例:http://echarts.baidu.com/demo...,其圖形都是經(jīng)過 JavaScript 計算之后生成的。再有淘寶這種頁面,它即使是 Ajax 獲取的數(shù)據(jù),但是其 Ajax 接口含有很多加密參數(shù),我們難以直接找出其規(guī)律,也很難直接分析 Ajax 來抓取。

但是數(shù)據(jù)總歸是要抓取的,為了解決這些問題,我們可以直接使用模擬瀏覽器運行的方式來實現(xiàn),這樣我們就可以做到瀏覽器看到是什么樣,抓取的源碼就是什么樣,也就是可見即可爬。這樣我們就不用再去管網(wǎng)頁內(nèi)部的 JavaScript 用了什么算法渲染頁面,不用管網(wǎng)頁后臺的 Ajax 接口到底有哪些參數(shù),利用模擬瀏覽器的方式我們都可以直接獲取 JavaScript 渲染的最終結(jié)果,只要能在瀏覽器中看到,我們都能抓取。

在 Python 中提供了許多模擬瀏覽器運行的庫,如 Selenium、Splash、PyV8、Ghost 等等,本章我們介紹一下其中 Selenium 和 Splash 的用法,有了它們,我們就不用再為動態(tài)渲染的頁面發(fā)愁了。

Selenium的使用

Selenium 是一個自動化測試工具,利用它我們可以驅(qū)動瀏覽器執(zhí)行特定的動作,如點擊、下拉等等操作,同時還可以獲取瀏覽器當前呈現(xiàn)的頁面的源代碼,做到可見即可爬。對于一些 JavaScript 動態(tài)渲染的頁面來說,此種抓取方式非常有效,本節(jié)讓我們來感受一下它的強大之處吧。

1. 準備工作

本節(jié)以 Chrome 為例來講解 Selenium 的用法,在本節(jié)開始之前請確保已經(jīng)正確安裝好了 Chrome 瀏覽器并配置好了 ChromeDriver,另外還需要正確安裝好 Python 的 Selenium 庫,詳細的過程可以參考第一章的安裝和配置說明。

2. 基本使用

準備工作做好之后,首先我們來大體看一下 Selenium 有一些怎樣的功能,先用一段實例代碼來感受一下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

browser = webdriver.Chrome()
try:
??? browser.get("https://www.baidu.com")
??? input = browser.find_element_by_id("kw")
??? input.send_keys("Python")
??? input.send_keys(Keys.ENTER)
??? wait = WebDriverWait(browser, 10)
??? wait.until(EC.presence_of_element_located((By.ID, "content_left")))
??? print(browser.current_url)
??? print(browser.get_cookies())
??? print(browser.page_source)
finally:
??? browser.close()

運行代碼之后可以發(fā)現(xiàn)會自動彈出一個 Chrome 瀏覽器,瀏覽器首先會跳轉(zhuǎn)到百度,然后在搜索框中輸入 Python 進行搜索,然后跳轉(zhuǎn)到搜索結(jié)果頁,等待搜索結(jié)果加載出來之后,控制臺分別會輸出當前的 URL,當前的 Cookies 還有網(wǎng)頁源代碼,如圖 7-1 所示:

圖 7-1 運行結(jié)果
在jon g zhi tai可以看到我們得到的當前的 URL、Cookies、源代碼都是瀏覽器中的真實內(nèi)容。
所以說,如果我們用 Selenium 來驅(qū)動瀏覽器加載網(wǎng)頁的話,我們就可以直接拿到 JavaScript 渲染的結(jié)果了,不管是什么加密統(tǒng)統(tǒng)不用再需要擔(dān)心。
下面我們來詳細了解一下Selenium的用法。

3. 聲明瀏覽器對象

Selenium 支持非常多的瀏覽器,如 Chrome、Firefox、Edge 等,還有手機端的瀏覽器 Android、BlackBerry 等,另外無界面瀏覽器 PhantomJS 也同樣支持。
我們可以用如下的方式初始化:

from selenium import webdriver

browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.PhantomJS()
browser = webdriver.Safari()

這樣我們就完成了瀏覽器對象的初始化并賦值為 browser 對象,接下來我們要做的就是調(diào)用 browser 對象,讓其執(zhí)行各個動作,就可以模擬瀏覽器操作了。

3. 訪問頁面

我們可以用 get() 方法來請求一個網(wǎng)頁,參數(shù)傳入鏈接 URL 即可,比如在這里我們用 get() 方法訪問淘寶,然后打印出源代碼,代碼如下:

from selenium import webdriver

browser = webdriver.Chrome()
browser.get("https://www.taobao.com")
print(browser.page_source)
browser.close()

運行之后我們便發(fā)現(xiàn)彈出了 Chrome 瀏覽器,自動訪問了淘寶,然后控制臺輸出了淘寶頁面的源代碼,隨后瀏覽器關(guān)閉。
通過這幾行簡單的代碼我們便可以實現(xiàn)瀏覽器的驅(qū)動并獲取網(wǎng)頁源碼,非常便捷。

4. 查找節(jié)點

Selenium 可以驅(qū)動瀏覽器完成各種操作,比如填充表單、模擬點擊等等,比如我們想要完成向某個輸入框輸入文字的操作,總得需要知道這個輸入框在哪里吧?所以 Selenium 提供了一系列查找節(jié)點的方法,我們可以用這些方法來獲取想要的節(jié)點,以便于下一步執(zhí)行一些動作或者提取信息。

單個節(jié)點

比如我們想要從淘寶頁面中提取搜索框這個節(jié)點,首先觀察它的源代碼,如圖 7-2 所示:

圖 7-2 源代碼
可以發(fā)現(xiàn)它的 ID 是 q,Name 也是 q,還有許多其他屬性,那我們獲取它的方式就有多種形式了,比如find_element_by_name() 是根據(jù) Name 值獲取,ind_element_by_id() 是根據(jù) ID 獲取,另外還有根據(jù)XPath、CSS Selector 等獲取的方式。
我們用代碼實現(xiàn)一下:

from selenium import webdriver

browser = webdriver.Chrome()
browser.get("https://www.taobao.com")
input_first = browser.find_element_by_id("q")
input_second = browser.find_element_by_css_selector("#q")
input_third = browser.find_element_by_xpath("http://*[@id="q"]")
print(input_first, input_second, input_third)
browser.close()

在這里我們使用了三種方式獲取輸入框,根據(jù) ID、CSS Selector 和 XPath 獲取,它們返回的結(jié)果是完全一致的。
運行結(jié)果:




可以看到三個節(jié)點都是 WebElement 類型,是完全一致的。
在這里列出所有獲取單個節(jié)點的方法:

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

另外 Selenium 還提供了通用的 find_element() 方法,它需要傳入兩個參數(shù),一個是查找的方式 By,另一個就是值,實際上它就是 find_element_by_id() 這種方法的通用函數(shù)版本,比如 find_element_by_id(id) 就等價于 find_element(By.ID, id),二者得到的結(jié)果完全一致。
我們用代碼實現(xiàn)一下:

from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
browser.get("https://www.taobao.com")
input_first = browser.find_element(By.ID, "q")
print(input_first)
browser.close()

這樣的查找方式實際上功能和上面列舉的查找函數(shù)完全一致,不過參數(shù)更加靈活。

多個節(jié)點

如果我們查找的目標在網(wǎng)頁中只有一個,那么完全可以用 find_element() 方法,但如果有多個節(jié)點,再用 find_element() 方法查找就只能得到第一個節(jié)點了,如果要查找所有滿足條件的節(jié)點,那就需要用 find_elements() 這樣的方法,方法名稱中 element 多了一個 s ,注意區(qū)分。
比如我們在這里查找淘寶左側(cè)導(dǎo)航條的所有條目,如圖 7-3 所示:

圖 7-3 導(dǎo)航欄
就可以這樣來實現(xiàn):

from selenium import webdriver

browser = webdriver.Chrome()
browser.get("https://www.taobao.com")
lis = browser.find_elements_by_css_selector(".service-bd li")
print(lis)
browser.close()

運行結(jié)果:

[, , ···]

在此簡化了一下輸出結(jié)果,中間部分省略。
可以看到得到的內(nèi)容就變成了列表類型,列表的每個節(jié)點都是 WebElement 類型。
也就是說,如果我們用 find_element() 方法,只能獲取匹配的第一個節(jié)點,結(jié)果是 WebElement 類型,如果用 find_elements() 方法,則結(jié)果是列表類型,列表的每個節(jié)點是 WebElement 類型。
函數(shù)的列表如下:

find_elements_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector

當然我們和剛才一樣,也可可以直接 find_elements() 方法來選擇,所以也可以這樣來寫:

lis = browser.find_elements(By.CSS_SELECTOR, ".service-bd li")

結(jié)果是完全一致的。

5. 節(jié)點交互

Selenium 可以驅(qū)動瀏覽器來執(zhí)行一些操作,也就是說我們可以讓瀏覽器模擬執(zhí)行一些動作,比較常見的用法有:
輸入文字用 send_keys() 方法,清空文字用 clear() 方法,另外還有按鈕點擊,用 click() 方法。
我們用一個實例來感受一下:

from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get("https://www.taobao.com")
input = browser.find_element_by_id("q")
input.send_keys("iPhone")
time.sleep(1)
input.clear()
input.send_keys("iPad")
button = browser.find_element_by_class_name("btn-search")
button.click()

在這里我們首先驅(qū)動瀏覽器打開淘寶,然后用 find_element_by_id() 方法獲取輸入框,然后用 send_keys() 方法輸入 iPhone 文字,等待一秒之后用 clear() 方法清空輸入框,再次調(diào)用 send_keys() 方法輸入 iPad 文字,之后再用 find_element_by_class_name() 方法獲取搜索按鈕,最后調(diào)用 click() 方法完成搜索動作。
通過上面的方法我們就完成了一些常見節(jié)點的動作操作,更多的操作可以參見官方文檔的交互動作介紹:http://selenium-python.readth...。

6. 動作鏈

在上面的實例中,一些交互動作都是針對某個節(jié)點執(zhí)行的,比如輸入框我們就調(diào)用它的輸入文字和清空文字方法,按鈕就調(diào)用它的點擊方法,其實還有另外的一些操作它是沒有特定的執(zhí)行對象的,比如鼠標拖拽、鍵盤按鍵等操作。所以這些動作我們有另一種方式來執(zhí)行,那就是動作鏈。
比如我們現(xiàn)在實現(xiàn)一個節(jié)點的拖拽操作,將某個節(jié)點從一處拖拽到另外一處,可以用代碼這樣實現(xiàn):

from selenium import webdriver
from selenium.webdriver import ActionChains

browser = webdriver.Chrome()
url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"
browser.get(url)
browser.switch_to.frame("iframeResult")
source = browser.find_element_by_css_selector("#draggable")
target = browser.find_element_by_css_selector("#droppable")
actions = ActionChains(browser)
actions.drag_and_drop(source, target)
actions.perform()

首先我們打開網(wǎng)頁中的一個拖拽實例,然后依次選中要被拖拽的節(jié)點和拖拽到的目標節(jié)點,然后聲明了 ActionChains 對象賦值為 actions 變量,然后通過調(diào)用 actions 變量的 drag_and_drop() 方法,然后再調(diào)用 perform() 方法執(zhí)行動作,就完成了拖拽操作,如圖 7-4 和 7-5 所示:

圖 7-4 拖拽前頁面

圖 7-5 拖拽后頁面
以上兩圖分別為在拖拽前和拖拽后的結(jié)果。
更多的動作鏈操作可以參考官方文檔的動作鏈介紹:http://selenium-python.readth...。

7. 執(zhí)行JavaScript

對于某些操作,Selenium API 是沒有提供的,如下拉進度條等,可以直接模擬運行 JavaScript,使用 execute_script() 方法即可實現(xiàn),代碼如下:

from selenium import webdriver

browser = webdriver.Chrome()
browser.get("https://www.zhihu.com/explore")
browser.execute_script("window.scrollTo(0, document.body.scrollHeight)")
browser.execute_script("alert("To Bottom")")

在這里我們就利用了 execute_script() 方法將進度條下拉到最底部,然后彈出 alert 提示框。
所以說有了這個,基本上 API 沒有提供的所有的功能都可以用執(zhí)行 JavaScript 的方式來實現(xiàn)了。

8. 獲取節(jié)點信息

我們在前面說過通過 page_source 屬性可以獲取網(wǎng)頁的源代碼,獲取源代碼之后就可以使用解析庫如正則、BeautifulSoup、PyQuery 等來提取信息了。
不過既然 Selenium 已經(jīng)提供了選擇節(jié)點的方法,返回的是WebElement 類型,那么它也有相關(guān)的方法和屬性來直接提取節(jié)點信息,如屬性、文本等等。這樣的話我們就可以不用通過解析源代碼來提取信息了,非常方便。
那接下來我們就看一下可以通過怎樣的方式來獲取節(jié)點信息吧。

獲取屬性

我們可以使用 get_attribute() 方法來獲取節(jié)點的屬性,那么這個的前提就是先選中這個節(jié)點。
我們用一個實例來感受一下:

from selenium import webdriver
from selenium.webdriver import ActionChains

browser = webdriver.Chrome()
url = "https://www.zhihu.com/explore"
browser.get(url)
logo = browser.find_element_by_id("zh-top-link-logo")
print(logo)
print(logo.get_attribute("class"))

運行之后程序便會驅(qū)動瀏覽器打開知乎的頁面,然后獲取知乎的 LOGO 節(jié)點,然后將它的 class 打印出來。
控制臺輸出結(jié)果:


zu-top-link-logo

我們通過 get_attribute() 方法,然后傳入想要獲取的屬性名,就可以得到它的值了。

獲取文本值

每個 WebEelement 節(jié)點都有 text 屬性,我們可以通過直接調(diào)用這個屬性就可以得到節(jié)點內(nèi)部的文本信息了,就相當于 BeautifulSoup 的 get_text() 方法、PyQuery 的 text() 方法。
我們用一個實例來感受一下:

from selenium import webdriver

browser = webdriver.Chrome()
url = "https://www.zhihu.com/explore"
browser.get(url)
input = browser.find_element_by_class_name("zu-top-add-question")
print(input.text)

在這里們依然是先打開知乎頁面,然后獲取提問按鈕這個節(jié)點,再將其文本值打印出來。
控制臺輸出結(jié)果:

提問
獲取ID、位置、標簽名、大小

另外 WebElement 節(jié)點還有一些其他的屬性,比如 id 屬性可以獲取節(jié)點 id,location 可以獲取該節(jié)點在頁面中的相對位置,tag_name 可以獲取標簽名稱,size 可以獲取節(jié)點的大小,也就是寬高,這些屬性有時候還是很有用的。
我們用實例來感受一下:

 from selenium import webdriver

browser = webdriver.Chrome()
url = "https://www.zhihu.com/explore"
browser.get(url)
input = browser.find_element_by_class_name("zu-top-add-question")
print(input.id)
print(input.location)
print(input.tag_name)
print(input.size)

在這里我們首先獲得了提問按鈕這個節(jié)點,然后調(diào)用其 id、location、tag_name、size 屬性即可獲取對應(yīng)的屬性值。

9. 切換Frame

我們知道在網(wǎng)頁中有這樣一種節(jié)點叫做 iframe,也就是子Frame,相當于頁面的子頁面,它的結(jié)構(gòu)和外部網(wǎng)頁的結(jié)構(gòu)是完全一致的。Selenium 打開頁面后,它默認是在父級Frame 里面操作,而此時如果頁面中還有子 Frame,它是不能獲取到子 Frame 里面的節(jié)點的。所以這時候我們就需要使用 switch_to.frame() 方法來切換 Frame。
我們首先用一個實例來感受一下:

import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException

browser = webdriver.Chrome()
url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"
browser.get(url)
browser.switch_to.frame("iframeResult")
try:
??? logo = browser.find_element_by_class_name("logo")
except NoSuchElementException:
??? print("NO LOGO")
browser.switch_to.parent_frame()
logo = browser.find_element_by_class_name("logo")
print(logo)
print(logo.text)

控制臺輸出:

NO LOGO

RUNOOB.COM

我們還是以上文演示動作鏈操作的網(wǎng)頁為實例,首先我們通過 switch_to.frame() 方法切換到子 Frame 里面,然后我們嘗試獲取父級 Frame 里的 LOGO 節(jié)點,是不能找到的,找不到的話就會拋出 NoSuchElementException 異常,異常被捕捉之后就會輸出 NO LOGO,接下來我們重新切換回父Frame,然后再次重新獲取節(jié)點,發(fā)現(xiàn)就可以成功獲取了。
所以,當頁面中包含子 Frame 時,如果我們想獲取子Frame 中的節(jié)點,需要先調(diào)用 switch_to.frame() 方法切換到對應(yīng)的 Frame,然后再進行操作即可。

10. 延時等待

在 Selenium 中,get() 方法會在網(wǎng)頁框架加載結(jié)束之后就結(jié)束執(zhí)行,此時如果獲取 page_source 可能并不是瀏覽器完全加載完成的頁面,如果某些頁面有額外的 Ajax 請求,我們在網(wǎng)頁源代碼中也不一定能成功獲取到。所以這里我們需要延時等待一定時間確保節(jié)點已經(jīng)加載出來。
在這里等待的方式有兩種,一種隱式等待,一種顯式等待。

隱式等待

當使用了隱式等待執(zhí)行測試的時候,如果 Selenium 沒有在DOM 中找到節(jié)點,將繼續(xù)等待,超出設(shè)定時間后則拋出找不到節(jié)點的異常, 換句話說,當查找節(jié)點而節(jié)點并沒有立即出現(xiàn)的時候,隱式等待將等待一段時間再查找 DOM,默認的時間是 0。
我們用一個實例來感受一下:

from selenium import webdriver

browser = webdriver.Chrome()
browser.implicitly_wait(10)
browser.get("https://www.zhihu.com/explore")
input = browser.find_element_by_class_name("zu-top-add-question")
print(input)

在這里我們用 implicitly_wait() 方法實現(xiàn)了隱式等待。

顯式等待

隱式等待的效果其實并沒有那么好,因為我們只是規(guī)定了一個固定時間,而頁面的加載時間是受到網(wǎng)絡(luò)條件影響的。
所以在這里還有一種更合適的顯式等待方法,它指定好要查找的節(jié)點,然后指定一個最長等待時間。如果在規(guī)定時間內(nèi)加載出來了這個節(jié)點,那就返回查找的節(jié)點,如果到了規(guī)定時間依然沒有加載出該節(jié)點,則會拋出超時異常。
我們用一個實例來感受一下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Chrome()
browser.get("https://www.taobao.com/")
wait = WebDriverWait(browser, 10)
input = wait.until(EC.presence_of_element_located((By.ID, "q")))
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".btn-search")))
print(input, button)

在這里我們首先引入了 WebDriverWait 這個對象,指定好最長等待時間,然后調(diào)用它的 until() 方法,傳入要等待條件 expected_conditions,比如在這里我們傳入了 presence_of_element_located 這個條件,就代表節(jié)點出現(xiàn)的意思,其參數(shù)是節(jié)點的定位元組,也就是 ID 為 q 的節(jié)點搜索框。
所以這樣可以做到的效果就是,在 10 秒內(nèi)如果 ID 為 q 的節(jié)點即搜索框成功加載出來了,那就返回該節(jié)點,如果超過10 秒還沒有加載出來,那就拋出異常。
對于按鈕,可以更改一下等待條件,比如改為 element_to_be_clickable,也就是可點擊,所以查找按鈕時是查找 CSS 選擇器為 .btn-search 的按鈕,如果 10 秒內(nèi)它是可點擊的也就是成功加載出來了,那就返回這個按鈕節(jié)點,如果超過 10 秒還不可點擊,也就是沒有加載出來,那就拋出異常。
運行代碼,在網(wǎng)速較佳的情況下是可以成功加載出來的。
控制臺輸出:


可以看到控制臺成功輸出了兩個節(jié)點,都是 WebElement 類型。
如果網(wǎng)絡(luò)有問題,10 秒內(nèi)沒有成功加載,那就拋出TimeoutException,控制臺輸出如下:

TimeoutException Traceback (most recent call last)
 in ()
      7 browser.get("https://www.taobao.com/")
      8 wait = WebDriverWait(browser, 10)
----> 9 input = wait.until(EC.presence_of_element_located((By.ID, "q")))

關(guān)于等待條件,其實還有很多,比如判斷標題內(nèi)容,判斷某個節(jié)點內(nèi)是否出現(xiàn)了某文字,在這里將所有的加載條件列舉如下:

等待條件 含義
title_is 標題是某內(nèi)容
title_contains 標題包含某內(nèi)容
presence_of_element_located 節(jié)點加載出,傳入定位元組,如(By.ID, "p")
visibility_of_element_located 節(jié)點可見,傳入定位元組
visibility_of 可見,傳入節(jié)點對象
presence_of_all_elements_located 所有節(jié)點加載出
text_to_be_present_in_element 某個節(jié)點文本包含某文字
text_to_be_present_in_element_value 某個節(jié)點值包含某文字
frame_to_be_available_and_switch_to_it frame 加載并切換
invisibility_of_element_located 節(jié)點不可見
element_to_be_clickable 節(jié)點可點擊
staleness_of 判斷一個節(jié)點是否仍在DOM,可判斷頁面是否已經(jīng)刷新
element_to_be_selected 節(jié)點可選擇,傳節(jié)點對象
element_located_to_be_selected 節(jié)點可選擇,傳入定位元組
element_selection_state_to_be 傳入節(jié)點對象以及狀態(tài),相等返回True,否則返回False
element_located_selection_state_to_be 傳入定位元組以及狀態(tài),相等返回True,否則返回False
alert_is_present 是否出現(xiàn)Alert

更多詳細的等待條件的參數(shù)及用法介紹可以參考官方文檔:http://selenium-python.readth...。

11. 前進后退

我們平常使用瀏覽器都有前進和后退功能,使用 Selenium 也可以完成這個操作,使用 back() 方法可以后退,forward() 方法可以前進。
我們用一個實例來感受一下:

import time
from selenium import webdriver

browser = webdriver.Chrome()
browser.get("https://www.baidu.com/")
browser.get("https://www.taobao.com/")
browser.get("https://www.python.org/")
browser.back()
time.sleep(1)
browser.forward()
browser.close()

在這里我們連續(xù)訪問三個頁面,然后調(diào)用 back() 方法就可以回到第二個頁面,接下來再調(diào)用 forward() 方法又可以前進到第三個頁面。

12. Cookies

使用 Selenium 還可以方便地對 Cookies 進行操作,例如獲取、添加、刪除 Cookies 等等。
我們再用實例來感受一下:

from selenium import webdriver

browser = webdriver.Chrome()
browser.get("https://www.zhihu.com/explore")
print(browser.get_cookies())
browser.add_cookie({"name": "name", "domain": "www.zhihu.com", "value": "germey"})
print(browser.get_cookies())
browser.delete_all_cookies()
print(browser.get_cookies())

首先我們訪問了知乎,然后加載完成之后,瀏覽器實際上已經(jīng)生成了 Cookies 了,我們調(diào)用 get_cookies() 方法就可以獲取所有的 Cookies,然后我們添加一個 Cookie,傳入一個字典,有 name、domain、value 等內(nèi)容。接下來我們再次獲取所有的 Cookies,可以發(fā)現(xiàn)結(jié)果就多了這一項 Cookie。最后我們調(diào)用 delete_all_cookies() 方法,刪除所有的 Cookies,再重新獲取,結(jié)果就為空了。
控制臺輸出:

[{"secure": False, "value": ""NGM0ZTM5NDAwMWEyNDQwNDk5ODlkZWY3OTkxY2I0NDY=|1491604091|236e34290a6f407bfbb517888849ea509ac366d0"", "domain": ".zhihu.com", "path": "/", "httpOnly": False, "name": "l_cap_id", "expiry": 1494196091.403418}]
[{"secure": False, "value": "germey", "domain": ".www.zhihu.com", "path": "/", "httpOnly": False, "name": "name"}, {"secure": False, "value": ""NGM0ZTM5NDAwMWEyNDQwNDk5ODlkZWY3OTkxY2I0NDY=|1491604091|236e34290a6f407bfbb517888849ea509ac366d0"", "domain": ".zhihu.com", "path": "/", "httpOnly": False, "name": "l_cap_id", "expiry": 1494196091.403418}]
[]

通過以上方法來操作 Cookies 還是非常方便的。

13. 選項卡管理

我們在訪問網(wǎng)頁的時候會開啟一個個選項卡,那么在 Selenium 中也可以對選項卡進行操作。

import time
from selenium import webdriver

browser = webdriver.Chrome()
browser.get("https://www.baidu.com")
browser.execute_script("window.open()")
print(browser.window_handles)
browser.switch_to_window(browser.window_handles[1])
browser.get("https://www.taobao.com")
time.sleep(1)
browser.switch_to_window(browser.window_handles[0])
browser.get("https://python.org")

控制臺輸出:

["CDwindow-4f58e3a7-7167-4587-bedf-9cd8c867f435", "CDwindow-6e05f076-6d77-453a-a36c-32baacc447df"]

首先我們訪問了百度,然后調(diào)用了 execute_script() 方法,傳入 window.open() 的 JavaScript 語句新開啟一個選項卡,然后接下來我們想切換到該選項卡,可以調(diào)用 window_handles 屬性獲取當前開啟的所有選項卡,返回的是選項卡的代號列表,要想切換選項卡只需要調(diào)用 switch_to_window() 方法,傳入選項卡的代號即可。在這里我們將第二個選項卡代號傳入,即跳轉(zhuǎn)到了第二個選項卡,然后接下來在第二個選項卡下打開一個新的頁面,然后切換回第一個選項卡可以重新調(diào)用 switch_to_window() 方法,再執(zhí)行其他操作即可。
如此以來我們便實現(xiàn)了選項卡的管理。

14. 異常處理

在使用 Selenium 過程中,難免會遇到一些異常,例如超時、節(jié)點未找到等錯誤,一旦出現(xiàn)此類錯誤,程序便不會繼續(xù)運行了,所以異常處理在程序中是十分重要的。
在這里我們可以使用 try except 語句來捕獲各種異常。
首先我們演示一下節(jié)點未找到的異常,示例如下:

from selenium import webdriver

browser = webdriver.Chrome()
browser.get("https://www.baidu.com")
browser.find_element_by_id("hello")

在這里我們打開百度頁面,然后嘗試選擇一個并不存在的節(jié)點,這樣就會遇到異常。
運行之后控制臺輸出如下:

NoSuchElementException Traceback (most recent call last)
 in ()
      3 browser = webdriver.Chrome()
      4 browser.get("https://www.baidu.com")
----> 5 browser.find_element_by_id("hello")

可以看到拋出了 NoSuchElementException 這類異常,這通常是節(jié)點未找到的異常,為了防止程序遇到異常而中斷,我們需要捕獲一下這些異常。

from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException

browser = webdriver.Chrome()
try:
??? browser.get("https://www.baidu.com")
except TimeoutException:
??? print("Time Out")
try:
??? browser.find_element_by_id("hello")
except NoSuchElementException:
??? print("No Element")
finally:
??? browser.close()

如上例所示,這里我們使用 try except 來捕獲各類異常,比如我們對 find_element_by_id() 查找節(jié)點的方法捕獲 NoSuchElementException 異常,這樣一旦出現(xiàn)這樣的錯誤,就進行異常處理,程序也不會中斷了。
控制臺輸出:
No Element
更多的異常累可以參考官方文檔:http://selenium-python.readth...,如果出現(xiàn)了某個異常,我們對它進行捕獲即可。

15. 結(jié)語

到此我們就基本對 Selenium 的常用用法有了大體的了解,有了 Selenium,處理 JavaScript 不再是難事。

上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---36、分析Ajax爬取今日頭條街拍美圖
下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---38、動態(tài)渲染頁面抓取:Splash的使用

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/44108.html

相關(guān)文章

  • Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---36、分析Ajax爬取今日頭條街拍美圖

    摘要:上一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)數(shù)據(jù)爬取下一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)動態(tài)渲染頁面抓取本節(jié)我們以今日頭條為例來嘗試通過分析請求來抓取網(wǎng)頁數(shù)據(jù)的方法,我們這次要抓取的目標是今日頭條的街拍美圖,抓取完成之后將每組圖片分文件夾下載到本地保存下來。 上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---35、 Ajax數(shù)據(jù)爬取下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---37、動態(tài)渲染頁面抓取:Selenium 本節(jié)我們...

    Leck1e 評論0 收藏0
  • Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---1、請求庫安裝:Requests、Selenium、ChromeDr

    摘要:下一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)請求庫安裝爬蟲可以簡單分為幾步抓取頁面分析頁面存儲數(shù)據(jù)。相關(guān)鏈接官方網(wǎng)站官方文檔中文文檔安裝驗證安裝進入命令行交互模式,導(dǎo)入一下包,如果沒有報錯,則證明安裝成功。 下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---2、請求庫安裝:GeckoDriver、PhantomJS、Aiohttp 爬蟲可以簡單分為幾步:抓取頁面、分析頁面、存儲數(shù)據(jù)。 在第一步抓取頁面的過程中,...

    wawor4827 評論0 收藏0
  • 首次公開,整理12年積累的博客收藏夾,零距離展示《收藏夾吃灰》系列博客

    摘要:時間永遠都過得那么快,一晃從年注冊,到現(xiàn)在已經(jīng)過去了年那些被我藏在收藏夾吃灰的文章,已經(jīng)太多了,是時候把他們整理一下了。那是因為收藏夾太亂,橡皮擦給設(shè)置私密了,不收拾不好看呀。 ...

    Harriet666 評論0 收藏0
  • Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---17、爬蟲基本原理

    摘要:在前面我們講到了和的概念,我們向網(wǎng)站的服務(wù)器發(fā)送一個,返回的的便是網(wǎng)頁源代碼。渲染頁面有時候我們在用或抓取網(wǎng)頁時,得到的源代碼實際和瀏覽器中看到的是不一樣的。所以使用基本請求庫得到的結(jié)果源代碼可能跟瀏覽器中的頁面源代碼不太一樣。 上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---16、Web網(wǎng)頁基礎(chǔ)下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---18、Session和Cookies 爬蟲,即網(wǎng)...

    hellowoody 評論0 收藏0
  • Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---2、請求庫安裝:GeckoDriver、PhantomJS、Aioh

    摘要:上一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)請求庫安裝下一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)解析庫的安裝的安裝在上一節(jié)我們了解了的配置方法,配置完成之后我們便可以用來驅(qū)動瀏覽器來做相應(yīng)網(wǎng)頁的抓取。上一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)請求庫安裝下一篇文章網(wǎng)絡(luò)爬蟲實戰(zhàn)解析庫的安裝 上一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)---1、請求庫安裝:Requests、Selenium、ChromeDriver下一篇文章:Python3網(wǎng)絡(luò)爬蟲實戰(zhàn)--...

    Cristalven 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<