结合Selenium 和 Requests完成动态数据爬取
Selenium
簡介
Selenium是一個用于Web應(yīng)用程序測試的工具。Selenium測試直接調(diào)用操作瀏覽器,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。這個工具的主要功能包括:測試與瀏覽器的兼容性——測試你的應(yīng)用程序看是否能夠很好得工作在不同瀏覽器和操作系統(tǒng)之上。測試系統(tǒng)功能——創(chuàng)建回歸測試檢驗軟件功能和用戶需求。支持自動錄制動作和自動生成 .Net、Java、Perl等不同語言的測試腳本。
簡言之,Selenium提供一套API,包含了元素定位、模擬操作(點擊、輸入…)等功能。在運行時會啟動一個處于調(diào)試狀態(tài)下的瀏覽器。需要注意的是,啟動相應(yīng)的瀏覽器需要對應(yīng)的驅(qū)動。下載完成后可以將驅(qū)動放置在環(huán)境變量包含的路徑中,或是在代碼中指定路徑。
# 使用項目的相對路徑
chrome = webdriver.WebDriver(executable_path='./Driver/chromedriver_80.exe')
1
2
安裝
以python為例:
pip install selenium
1
Requests
Requests: HTTP for Humans?
簡介
Requests是一個非常好用的Python的HTTP庫,通過Requests我們可以向服務(wù)器發(fā)起GET、POST等請求。Requests也提供了對會話的支持。
安裝
pip install requests
1
靜態(tài)頁面與動態(tài)頁面
靜態(tài)頁面是用戶發(fā)起請求后,在服務(wù)器端直接生成最終頁面,并發(fā)送回客戶端,客戶端直接進行加載渲染即可。
動態(tài)頁面往往在用戶發(fā)起請求后,服務(wù)器僅僅返回數(shù)據(jù)部分,客戶端接收到數(shù)據(jù)后,再將數(shù)據(jù)填充進頁面中,進行渲染。
動態(tài)頁面占用服務(wù)器資源少,以一個搜索任務(wù)為例,服務(wù)器僅僅是完成一個數(shù)據(jù)庫查詢后,將數(shù)據(jù)以特定格式返回給客戶端;靜態(tài)頁面則要求服務(wù)器完成查詢后,還需要將整個頁面“拼接”出來,再發(fā)送返回給客戶端。
靜態(tài)頁面的爬蟲相對容易完成,因為所有的元素都能在HTML源碼中找到,我們使用相應(yīng)的工具便可以快速定位元素路徑,進行數(shù)據(jù)爬取,也就是說,對于靜態(tài)頁面,我們拿到頁面便拿到了數(shù)據(jù)。靜態(tài)頁面可以直接通過Requests庫來訪問鏈接進行獲取。
動態(tài)頁面在頁面解析時相對復雜麻煩一點,因為我們從瀏覽器看見的是通過js渲染完成后的界面,頁面源碼并不是最終產(chǎn)物,在進行元素定位時,因為頁面的動態(tài)性,頁面源碼是隨著用戶操作而發(fā)生改變的,所以盲目使用元素定位往往結(jié)果難以令人滿意,而且容易丟失元素。如果直接通過Requests庫進行獲取,獲取到的頁面僅僅是一個框架,是js還沒有執(zhí)行過的頁面。
動態(tài)頁面爬取的兩種思路
既然我們直接進行獲取的頁面是沒有執(zhí)行js進行渲染過的界面,那么我們可以嘗試先對其調(diào)用js渲染,再獲取其頁面。(想方法獲取到最終頁面)
模擬瀏覽器,直接向服務(wù)器發(fā)起請求,獲取服務(wù)器返回數(shù)據(jù)。(直接收集數(shù)據(jù))
這里著重講解第二種方法。
如何模擬瀏覽器
構(gòu)造請求
請求是什么
我們發(fā)起的每一個請求,都攜帶了額外的信息,當我們想方設(shè)法將這些信息都通過代碼加入到我們的請求中時,我們就完美模擬了瀏覽器。這些信息組成了請求頭和請求體。請求頭,用來說明服務(wù)器要使用的附加信息,請求體一般承載的內(nèi)容是 POST 請求中的表單數(shù)據(jù)(Payload),而對于 GET 請求,請求體則為空。
請求頭中常見的信息有Cookie、Referer、User-Agent等。
User-Agent
簡稱 UA,它是一個特殊的字符串頭,可以使服務(wù)器識別客戶使用的操作系統(tǒng)及版本、瀏覽器及版本等信息。在做爬蟲時加上此信息,可以偽裝為瀏覽器;如果不加,很可能會被識別出為爬蟲。
Cookie
也常用復數(shù)形式 Cookies,這是網(wǎng)站為了辨別用戶進行會話跟蹤而存儲在用戶本地的數(shù)據(jù)。它的主要功能是維持當前訪問會話。例如,我們輸入用戶名和密碼成功登錄某個網(wǎng)站后,服務(wù)器會用會話保存登錄狀態(tài)信息,后面我們每次刷新或請求該站點的其他頁面時,會發(fā)現(xiàn)都是登錄狀態(tài),這就是 Cookies 的功勞。Cookies 里有信息標識了我們所對應(yīng)的服務(wù)器的會話,每次瀏覽器在請求該站點的頁面時,都會在請求頭中加上 Cookies 并將其發(fā)送給服務(wù)器,服務(wù)器通過 Cookies 識別出是我們自己,并且查出當前狀態(tài)是登錄狀態(tài),所以返回結(jié)果就是登錄之后才能看到的網(wǎng)頁內(nèi)容。
Cookie好比是游樂園里蓋在手背上的章,有了這個章才可以進去玩。每一次進出的時候,只需要給管理員看一下你的章,管理員就知道你是買過票的,就不需要再一次購買。
Referer
此內(nèi)容用來標識這個請求是從哪個頁面發(fā)過來的,服務(wù)器可以拿到這一信息并做相應(yīng)的處理,如做來源統(tǒng)計、防盜鏈處理等。
Payload
Payload是表單數(shù)據(jù),可能是我們搜索的關(guān)鍵字,也可能包含我們的篩選條件。
如何構(gòu)造請求
幸運的是,Requests庫本身已經(jīng)為我們提供了構(gòu)造請求的方法,我們只需要拿到數(shù)據(jù)并填充即可。
Cookies
Cookies在需要登錄的情況下有用,當我們通過Selenium打開網(wǎng)址完成登錄后,可以通過Selenium獲取到Cookies,以下代碼實現(xiàn)一個簡單的示例。
# 實例化一個瀏覽器
chrome = webdriver.WebDriver(executable_path='Driver/chromedriver_80.exe', options=option)
# 打開一個網(wǎng)頁,以bilibili登錄頁面為例
# 在瀏覽器中輸入賬號與密碼,當然也可以通過代碼實現(xiàn)查找對應(yīng)輸入框輸入文本
chrome.get("https://passport.bilibili.com/login")
# 構(gòu)造“會話”
sess = requests.Session()
# 獲取cookies
cookies = chrome.get_cookies()
# 填充
for cookie in cookies:
?? ?sess.cookies.set(cookie['name'], cookie['value'])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
請求其余信息
獲取請求內(nèi)容最準確的方法是直接從瀏覽器的開發(fā)者工具中進行拷貝。可以先通過瀏覽器進行一次手動請求,即可從瀏覽器的開發(fā)者工具中看見請求的詳細信息。
首先打開開發(fā)者工具,以Chrome為例,快捷鍵Ctrl + Shift + I即可。
設(shè)置過濾器為XHR。
點擊按鈕(查詢、提交等,即你發(fā)起請求需要點擊的那個按鈕)。
在開發(fā)者工具下面出現(xiàn)的響應(yīng)中找到你需要的那一條記錄。
復制信息到代碼中。
瀏覽器訪問的url和請求方法。
請求頭
請求體
下面展示一個較為完整的代碼。
import requests
import json?
from selenium.webdriver.chrome import webdriver
# 實例化一個瀏覽器
chrome = webdriver.WebDriver(executable_path='Driver/chromedriver_80.exe', options=option)
# 打開一個網(wǎng)頁,以bilibili登錄頁面為例
# 在瀏覽器中輸入賬號與密碼,當然也可以通過代碼實現(xiàn)查找對應(yīng)輸入框輸入文本
chrome.get("https://passport.bilibili.com/login")
# 構(gòu)造“會話”
sess = requests.Session()
sess.headers.clear()
# 依照實際情況一一復制
# 此處略有省略
sess.headers.setdefault('Accept', 'application/json, text/javascript, */*; q=0.01')
sess.headers.setdefault('Accept-Encoding', 'gzip, deflate, br')
sess.headers.setdefault('Accept-Language', 'en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6')
sess.headers.setdefault('Content-Length', '3293')
sess.headers.setdefault('Content-Type', 'application/json')
sess.headers.setdefault('Origin', 'https://www.bilibili.com')
sess.headers.setdefault('Referer', 'https://www.bilibili.com/v/douga/?spm_id_from=333.5.b_70______________________56c4d656e75.1')
sess.headers.setdefault('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36')
# 獲取cookies
cookies = chrome.get_cookies()
# 填充cookies
for cookie in cookies:
?? ?sess.cookies.set(cookie['name'], cookie['value'])
# 直接將瀏覽器開發(fā)者工具中顯示的Requests Payload復制下來,然后包成一個字符串
payload = '{"uploads":[{"src_id":154,"ad_server":"bilibili","is_ad":1,"area":1,"ad_cb":"CPraDRCfuk4Y3tjgHyCPBygBMPIyOJoBQh8SNS0mLWjLlIG57u16ZizWgblm5vlt51iBuS4luZWQscGxheXBhZ2VjdHI6ZW5hYmxlX25vX2VjcG1fdGhyZXNob2xkLG5vX2FkX2Zsb3dfY29udHJvbDp1bmRlZmluZWQsYnJ1c2h……'
url = 'https://cm.bilibili.com/cm/api/fees/pc'
response = sess.post(url, data=payload)
json_data = response.text
json_data = json.loads(json_data)
————————————————
版權(quán)聲明:本文為CSDN博主「程序猿D」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/JunhuanPeng/article/details/105903626
總結(jié)
以上是生活随笔為你收集整理的结合Selenium 和 Requests完成动态数据爬取的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 准备回老家摆酒,用国吉祥酒有面子吗?
- 下一篇: 女孩子姓宋取什么名字