Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

上一節中使用了分析 ajax 的方式抓取網頁,但是不是所有的動態網頁都是 ajax 生成的,有的是直接由 Javascript 生成的.


還有一些網頁可能它的 Ajax 接口有加密參數,分析其 Ajax 接口非常困難.
為了解決這些問題,我們可以使用模擬瀏覽器的方式來進行抓取,這樣,在瀏覽器中看到什麼,我們就會抓到什麼,可見即可爬,不用在管網頁內部的 Javascript 用了什麼算法渲染頁面,也不用管後來 ajax 接口有哪些參數.
Python 提供了 Selenium 庫來模擬瀏覽器的運行.

Selenium 的使用.

Selenium 是一個自動化的測試工具,利用它可以驅動瀏覽器執行特定的動作,如點擊\\下拉等操作,同時還能獲取瀏覽器當前呈現的頁面的源代碼.對於一些 Javascript 動態渲染的頁面來說,此種抓取方法非常有效.

準備工作

本節將以 Chrome 瀏覽器為例來講解 Selenium 的用法,在開始本節課程之前,請按照第一節第二節的課程安裝並配置好 Chrome 瀏覽器,ChromeDriver 驅動,Selenium 庫等.

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

運行代碼後,會自動彈出以惡 Chrome 瀏覽器,瀏覽器會先跳轉到百度,然後搜索 Python,接著跳轉到搜索結果頁,然後關閉.

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

後臺也會打印出 HTML 代碼.

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

瀏覽器對象

Selenium 支持多種多樣的瀏覽器如 chrome、Firefox、Internet Explorer、Microsoft Edge 等,還支持 Android 等手機瀏覽器,支持 PhantomJs、ChromeHeadless 無頭瀏覽器等。 可以使用如下方式初始化 browser 對象。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

訪問頁面

瀏覽器對象初始化完成後,我們可以使用 get()方法來請求網頁,參數傳入 URL 即可。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

查找結點

Selenium 可以驅動瀏覽器完成各種操作,如填充表單、模擬點擊等。
比如我們想完成在某個文本框輸入的動作,首先得定位到文本框,而 Selenium 提供了一系列查找節點的方法。

單個節點

如果我們想找到淘寶的搜索框,首先得觀察淘寶網頁的源代碼:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

我們發現,這個 input 的 id 為 q,name 還是為 q。還有一些其他的屬性,比如 class 為 search-combobox-input 等,我們可以利用其這些屬性來定位這個節點。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

我們使用了四種方式來定位 input 節點.

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

Selenium 一共提供了八種獲取單個節點的方法:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

另外,Selenium 還提供了通用方法 find_element(),它需要傳入兩個參數,查找方式 By 和值。如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

多個節點

前面介紹的方法都只能查找單個節點,如果要查找多個節點,怎麼用呢? 比如我們要查找這些節點.

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

我們可以這樣實現:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

運行結果如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

和上面類似, Selenium 一共提供了八種方法定位多個節點:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

Selenium 也提供了通用的獲取多個節點的方法,和上面類似的 find_elements

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

節點交互

Selenium 可以驅動瀏覽器來執行一系列操作,如輸入文字、清空文字、點擊按鈕等。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

動作鏈

Selenium 還支持鼠標拖拽、鍵盤按鍵等操作,比如我們將一個節點從某個位置拖動到另一個位置。


比如我們想拖動這個元素:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

我們先打開網頁,定位到源位置和目標位置,接著聲明 ActionChains 對象,調用其方法實現拖拽操作。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

執行 javascript

如果我們用到了某些 Selenium API 未提供的功能的話,應該怎麼操作呢?
比如下拉進度條,我們可以直接使用 execute_script()方法來執行 Javascript。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

獲取節點信息

我們前面演示過,通過 browser 對象的 page_source 屬性可以獲取到網頁的源代碼,接著我們可以使用解析庫如 beautifulsoup、pyquery 等來解析。當然,Selenium 自身也提供了非常好用的選擇、獲取節點的方法。

獲取屬性

我們可以使用 get_attribute()方法來獲取節點的屬性,如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

運行結果如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

獲取文本

我們可以使用它的 text 屬性來獲取文本信息,類似於 beautifulsoup 的 get_text()方法,pyquery 的 text()方法。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

運行結果如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

獲取 id、位置、標籤名和大小

webelement 節點還有一些其他屬性,如 id、location、tag_name、size 等,如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

運行結果如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

切換 Frame

網頁中有一種節點叫做 iframe,就是子 frame,相當於頁面的子頁面,它的結構和外層的網頁結構是相同的。Selenium 打開頁面後,它默認實在父 frame 中操作的,如果此時頁面中還有子 frame,它是不能獲取到子 frame 中的節點的,下面就看看 Selenium 怎麼獲取子 frame 中的節點。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

執行結果如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

延時等待

Selenium 中,get()方法會在網頁加載結束後停止執行,此時如果獲取 page_source,可能獲取到的源碼並不是網頁完全加載結束後的源碼,某些節點可能在裡面找不到。如某些頁面有額外的 Ajax 請求,那麼我們就不一定能成功獲取到相關信息了。
Selenium 提供了兩種方式來解決這個問題: 一種是顯式等待,一種是隱式等待。

隱式等待

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

顯式等待

隱式等待只規定了一個固定的時間,而頁面的加載方式會受各方面因素的影響,所以這種方式並不好;所以我們可以用顯式等待來指定要查找的節點,然後指定一個最長的等待時間。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

執行結果如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

關於等待條件,其實很多,比如判斷標題內容、判斷是否出現了某文字等等,下面列出一些常用的等待條件。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

前進和後退

我們的瀏覽器上有前進和後退按鈕,Selenium 也提供了前進和後退方法。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

Cookies

Selenium 可以方便的對 Cookie 進行操作,如獲取、添加、刪除、修改等。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

運行結果如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

選項卡管理

我們使用瀏覽器的時候會打開一個個選項卡,在 Selenium 中,我們也可以對選項卡進行操作。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

執行結果如下:

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁

異常處理

在 selenium 中難免會遇到一些異常,比如節點未找到,超時等。一旦出現異常程序便不會執行了,如果我們寫個爬蟲,出現異常爬蟲就終止了,這是不行的,所以我們可以使用 try except 語句來捕獲各種異常。

Python3網絡爬蟲課程 使用 selenium 爬取動態網頁
"


分享到:


相關文章: