第四章 Python 動態網頁爬取

關於靜態網頁

我們知道靜態網頁在瀏覽器中展示的內容都在HTML源代碼中。但是,由於主流網站都使用JavaScript展現網頁內容,和靜態網頁不同的是,在使用JavaScript 時,很多內容並不會出現在HTML源代碼中,所以爬取靜態網頁的技術可能無法正常使用。因此,我們需要用到動態網頁抓取的兩種技術:
(1)通過瀏覽器審查元素解析真實網頁地址
(2)使用selenium模擬瀏覽器的方法


異步更新技術

AJAX(Asynchronous Javascript And XML,異步JavaScript和XML)
它的價值在於通過在後臺與服務器進行少量的數據交換就可以使網頁實現異步更新。這意味着可以在不重新加載整個網頁的情況下對網頁的某部分進行更新。一方面減少了網頁重複內容的下載,另一方面節省了流量。

解析真實網頁地址

http://www.santostang.com/2018/07/04/hello-world/
我們的目標是抓取目標文章的全部評論。
(1)首先,打開網頁的“檢查”功能。
(2)找到真實的數據地址。單擊頁面中的Network選項,然後刷新網頁。這個過程一般稱爲“抓包”。
在這裏插入圖片描述
(3)找到真實評論的數據地址,然後用requests請求這個地址來獲取數據。
在這裏插入圖片描述

import requests
import json
link = 'https://api-zero.livere.com/v1/comments/list?callback=jQuery112405205264113983896_1582798704769&limit=10&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1582798704771'
headers = {'User-Agent' : 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
r = requests.get(link, headers= headers)
print(r.text)

在這裏插入圖片描述
(4)從 json數據中提取評論。上述的結果比較雜亂,但是它其實是 json 數據,我們可以使用 json 庫解析數據,從中提取我們想要的數據。

import requests
import json
def single_page_comment(link):
    headers = {'User-Agent' : 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
    r = requests.get(link, headers= headers)
    # 獲取 json 的 string
    json_string = r.text
    json_string = json_string[json_string.find('{'):-2]
    json_data = json.loads(json_string)
    comment_list = json_data['results']['parents']
    for eachone in comment_list:
        message = eachone['content']
        print (message)

for page in range(1,4): #打印前4頁的評論
    link1 = "https://api-zero.livere.com/v1/comments/list?callback=jQuery112403473268296510956_1531502963311&limit=10&offset="
    link2 = "&repSeq=4272904&requestPath=%2Fv1%2Fcomments%2Flist&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&_=1531502963316"
    page_str = str(page)
    link = link1 + page_str + link2
    print (link)
    single_page_comment(link)

(5)上述只是爬取文章的第一頁評論,十分簡單。其實,我們經常需要爬取所有頁面,如果我們還是用人工一頁頁地翻頁,找到評論數據的地址,就十分費力了。因此,下面將介紹網頁 URL地址的規律,並用for循環爬取,就會非常輕鬆。
如果我們對比上面的兩個地址,可以發現 URL 地址中有兩個特別重要的變量,offset 和 limit,稍微理解一下可以知道,limit 代表的是每一頁評論數量的最大值,也就是說,這裏每一頁評論最多顯示30條;offset 代表的是第幾頁,第一頁 offset 爲0,第二頁爲1,那麼第三頁 offset 會是3。
因此,我們只需在URL中改變 offset 的值,便可以實現換頁。

在這裏插入圖片描述

通過Selenium模擬瀏覽器抓取

一、Selenium+Python環境搭建及配置

1.1 selenium 介紹
selenium 是一個 web 的自動化測試工具,不少學習功能自動化的同學開始首選 selenium ,因爲它相比 QTP 有諸多有點:

(1)免費,也不用再爲破解 QTP 而大傷腦筋
(2)小巧,對於不同的語言它只是一個包而已,而 QTP 需要下載安裝1個多 G 的程序。這也是最重要的一點,不管你以前更熟悉 C、 java、ruby、python、或都是 C# ,你都可以通過 selenium 完成自動化測試,QTP 只支持 VBS,selenium支持多平臺:windows、linux、MAC ,支持多瀏覽器:ie、firefox、safari、opera、chrome


1.2 selenium+Python環境配置
前提條件:已安裝好Python開發環境(推薦安裝Python3.5及以上版本)
安裝步驟:
(1)安裝selenium
Win:pip install selenium
Mac: pip3 install selenium
(2)安裝webdriver
Firefox:https://github.com/mozilla/geckodriver/releases/
Chrome:http://chromedriver.storage.googleapis.com/index.html
(3)這裏我以Windows Chrome爲例:
在這裏插入圖片描述
比如我的版本是:版本 80.0.3987.122(正式版本) (64 位)
那麼下載80.0.3937.106即可
在這裏插入圖片描述
注:webdriver需要和對應的瀏覽器版本以及selenium版本對應

二、元素定位及瀏覽器基本操作

2.1 啓動瀏覽器

from selenium import webdriver

browser = webdriver.Chrome()
browser.get('http://www.baidu.com/')

在這裏插入圖片描述

2.2 使用Selenium選擇元素的方法

(1)id定位

find_element_by_id()
比如<div id="bdy-inner">text</div>可以使用find_element_by_id("bdy-inner")

(2)name定位

find_element_by_name()
比如<input name="username" type="text" />可以使用find_element_by_name("username")

(3)class_name定位

class標準屬性,不唯一,通常找一類元素
find_element_by_class_name()
比如<div class='cheese'>test</div>可以使用find_element_by_class_name("cheese")
還有另一個函數可以選擇元素的class屬性:
find_element_by_css_selector()
比如<div class='cheese'>test</div>可以使用find_element_by_css_selector()("div.cheese")

(4)tag_name定位

driver.find_element_by_tag_name()
通過元素的名稱選擇,如<h1>Welcome</h1>可以使用driver.find_element_by_tag_name('h1')

(5)通過鏈接地址定位

find_element_by_link_text()
<a href="continue.html">Continue</a>可以使用driver.find_element_by_link_text("Continue")

(6)通過鏈接的部分地址選擇

find_element_by_partial_link_text()
<a href="continue.html">Continue</a>可以使用driver.find_element_by_partial_link_text("Conti")

(7)通過xpath選擇

find_element_by_xpath()
<form id="loginForm">可以使用driver.find_element_by_xpath("//form[@id='loginForm']")


有時,我們需要查找多個元素,在上述的element後加上s即可。
其中,xpathcss_selector是比較好的方法,一方面比較清晰,另一方面相對其他方法定位元素比較準確

Selenium的高級操作:

(1)控制CSS的加載。
(2)控制圖片文件的顯示。
(3)控制JavaScript的運行。

這三種方法可以加快Selenium的爬取速度。

另外,也可以使用Selenium的click操作元素方法。常見的操作元素方法如下:

(1)Clear 清除元素的內容
(2)send_keys 模擬按鍵輸入
(3)Click 單擊元素
(4)Submit 提交表單

比如:

user = driver.find_element_by_name("username") #找到用戶名輸入框
user.clear() #清除用戶名輸入框內容
user.send_keys("1234567") #在框中輸入用戶名
pwd = driver.find_element_by_name("password") #找到密碼輸入框
pwd.clear() #清除密碼輸入框的內容
pwd.send_keys("******") #在框中輸入密碼
driver.find_element_by_id("loginBtn").click() #單擊登錄

具體一點的例子,比如我想要打開百度,然後自動查詢“你的名字”:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.baidu.com/')

input_text = driver.find_element_by_id("kw")
input_text.send_keys("你的名字")
driver.find_element_by_id("su").click()

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章