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"})

 

 

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