Python+Selenium+Browsermob-Proxy 爬蟲-獲取瀏覽器Network請求和響應


1.問題
自從發現 Selenium 這塊新大陸后,許多異步加載、js加密、動態Cookie等問題都變得非常簡單,大大簡化了爬蟲的難度。但是有些時候使用 Selenium 仍然有一些缺陷,比如現在很多網站數據都是通過json結構的接口來交互,通過分析報文的方式直接發包可以直接拿到json數據,數據不但全而且還很好解析,這比解析html網頁容易多了。另一個非常重要的問題就是,很多時候一些接口返回的關鍵信息是不在html網頁上顯示的,通過 Selenium 拿到的 page_source 便沒有這些字段。

那么如何解決這些問題呢?我們在做爬蟲開發的時候經常用到瀏覽器的開發者工具,分析網頁元素,查看資源加載(Network)等。Selenium + Webdriver 雖然能夠定位DOM元素、操作頁面、獲取網頁等。但是 Selenium 終歸只能處理“結果”,它無法得知瀏覽器請求的數據接口信息。如果我們能像瀏覽器Network那樣獲取到所有接口的請求和返回信息,那么問題不都解決了么。例如下圖:

 

 

 

而本文介紹的解決方案是:使用 webdriver 通過proxy訪問網絡,再收集proxy端的請求和返回內容,從而獲取到數據,而這個proxy就類似於 fiddler 抓包軟件。而文本介紹使用的是 Browsermob-Proxy

2.Browsermob-Proxy
Browsermob-Proxy是一個開源的Java編寫的基於LittleProxy的代理服務。Browsermob-Proxy的具體流程有點類似與Flidder或Charles。即開啟一個端口並作為一個標准代理存在,當HTTP客戶端(瀏覽器等)設置了這個代理,則可以抓取所有的請求細節並獲取返回內容。

安裝

直接到項目的github上下載打好的壓縮包即可:https://github.com/lightbody/browsermob-proxy/releases ,支持Linux和Windows。

安裝對應的python包:

pip install browsermob-proxy
這里以抓取情咖主播列表為例,目標url:http://www.liuyanlin.cn/ht_list3.html,使用Selenium + Webdriver + Browsermob-Proxy 獲取接口返回的數據。

開啟Proxy

下載好browsermob-proxy之后,放在指定一個目錄,例如我這里是 D:\apk\browsermob-proxy-2.1.4-bin\browsermob-proxy-2.1.4這個路徑下,所以下面示例代碼如:

from browsermobproxy import Server

server = Server("D:\\apk\lyl\\browsermob-proxy-2.1.4\\bin\\browsermob-proxy.bat")
server.start()
proxy = server.create_proxy()

 

配置Proxy啟動WebDriver

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument('--proxy-server={0}'.format(proxy.proxy))

driver = webdriver.Chrome(chrome_options=chrome_options)

 

獲取返回內容

#要訪問的地址
base_url = "http://www.liuyanlin.cn/ht_list3.html"
proxy.new_har("douyin", options={'captureHeaders': True, 'captureContent': True})

driver.get(base_url)
result = proxy.har

for entry in result['log']['entries']:
_url = entry['request']['url']
print(_url)
# # 根據URL找到數據接口,這里要找的是 http://git.liuyanlin.cn/get_ht_list 這個接口
if "http://git.liuyanlin.cn/get_ht_list" in _url:
_response = entry['response']
_content = _response['content']
# 獲取接口返回內容
print(_content)

server.stop()
driver.quit()

 

下面是完整代碼:

from browsermobproxy import Server
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time

server = Server("D:\\apk\lyl\\browsermob-proxy-2.1.4\\bin\\browsermob-proxy.bat")
server.start()
proxy = server.create_proxy()

chrome_options = Options()
chrome_options.add_argument('--proxy-server={0}'.format(proxy.proxy))

driver = webdriver.Chrome(chrome_options=chrome_options)
#要訪問的地址
base_url = "http://www.liuyanlin.cn/ht_list3.html"
proxy.new_har("ht_list2", options={ 'captureContent': True})

driver.get(base_url)
#此處最好暫停幾秒等待頁面加載完成,不然會拿不到結果
time.sleep(3)
result = proxy.har

for entry in result['log']['entries']:
_url = entry['request']['url']
print(_url)
# # 根據URL找到數據接口,這里要找的是 http://git.liuyanlin.cn/get_ht_list 這個接口
if "http://git.liuyanlin.cn/get_ht_list" in _url:
_response = entry['response']
_content = _response['content']
# 獲取接口返回內容
print(_response)

server.stop()
driver.quit()

 

運行結果如圖所示,可以看到,成功拿到數據:

 

 

 

補充知識點:

由於Browsermob-Proxy本身自己就是一個代理服務,那么有時候我們有這種需求,比如某個網站封ip封得厲害,這時候就需要使用代理ip了,那么怎么將Browsermob-Proxy的出口ip改成一個買的代理ip了,也就是所謂的實現二級代理。例如我這里有個代理ip是可以用的:61.155.141.13:20345 接下來我要將這個代理ip掛到Browsermob-Proxy服務上,其實很簡單,只需要在創建server的時候帶上一個參數,例如下面的代碼:

proxy = server.create_proxy({"httpProxy":"61.155.141.13:20345"})

 

參考: 

https://testpappy.wordpress.com/2016/12/30/network-console-for-your-test-scripts/

http://www.softwareishard.com/blog/har-12-spec/ 


————————————————
版權聲明:本文為CSDN博主「劉延林 | 夢陸」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_32502511/article/details/101536325


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM