2020-02-23 晴 鄭州
出場人物
- 沉瓶 - 產品經理
- 飯鹹 - 程序員
故事
沉瓶:有個網站,我想根據拿到原始數據,然後自己分析一下,有什麼好的方法沒有?
飯鹹:這個就是傳說中的爬蟲了,通過網絡請求,獲取自己想要的數據。python很多庫都可以實現這個功能,比如:requests、Scrapy、PySpider、Crawley、selenium等等
沉瓶:爬蟲工具竟然這麼多,那麼網站會不會有反爬蟲的方案呢?
飯鹹:魔高一尺道高一丈,爲了保護自己網站的健康成長,現在出現了很多反爬蟲技術,使得爬蟲越來越有挑戰性。
沉瓶:那有沒有比較通用的方案完成爬蟲任務呢?
飯鹹:肯定有的,記得以前有人通過“機械臂”,模擬人手,進行點擊手機屏幕,實現薅羊毛。同樣的,網站最終要顯示出來,肯定是得讓瀏覽器認識的,如果模擬點擊瀏覽器,分析瀏覽器的內容,自然也就可以拿到你想要的的數據。
沉瓶:這麼說到也還真是,可是模擬點擊瀏覽器,再從瀏覽器拿數據,聽着很複雜呢?
飯鹹:不用擔心,現在的瀏覽器霸主,Chrome自己出了一個軟件叫chromedriver,可以用來操作chrome,而據此產生的python庫也很多,比如selenium就能很好的操作瀏覽器。
沉瓶:那你幫我看看這個網站的數據怎麼拿到呢?
飯鹹:好的,盤它。
需求
- 爬取某網站數據
實驗環境
下面版本爲博主自己的工作環境,您也可使用其它版本進行操作
- python(3.5.2)
- selenium=3.141.0
- browsermob-proxy=0.8.0
- chromedriver(80.0.3987.106)
- browsermob-proxy 2.1.4
實現步驟實現
1. 準備實驗環境
1.1 安裝python環境
安裝python應用,然後切換到python安裝路徑下的Scripts目錄(如:D:\Python\Python352\Scripts),然後安裝selenium和browsermob-proxy模塊。
cd /d D:\Python\Python352\Scripts
pip install selenium==3.141.0
pip install browsermob-proxy==0.8.0
1.2 安裝chromedriver
首先我們需要查看當前chrome版本,如下圖所示:
然後下載對應版本的chromedriver: chromedriver(80.0.3987.106)。
最後將下載好的chromedriver.exe放到系統目錄下(C:\Windows\System32)即可。這樣才能保證我們的程序可以找到chromedriver.exe。
1.3 安裝browsermob-proxy
Browsermob-Proxy是一個開源的Java編寫的基於LittleProxy的代理服務。Browsermob-Proxy的具體流程有點類似與Flidder或Charles。即開啓一個端口並作爲一個標準代理存在,當HTTP客戶端(瀏覽器等)設置了這個代理,則可以抓取所有的請求細節並獲取返回內容。
直接到項目的github上下載打好的壓縮包即可:https://github.com/lightbody/browsermob-proxy/releases ,支持Linux和Windows。
下載解壓後,我們可以看到bin目錄下的browsermob-proxy.bat文件,如下圖所示:
該bat文件用於啓動代理服務器,由於裏面使用的是JAVA,所以我們需要安裝java環境,我這裏使用的是1.8.0_73的版本。
2. 編寫代碼進行爬蟲
代碼內容格式是固定的,具體分爲如下幾步:
- 開啓Proxy:注意指定自己下載解壓後路徑。
- 配置Proxy啓動WebDriver。
- 獲取返回內容。
- 停止代理服務,退出selenium。
from selenium import webdriver
from browsermobproxy import Server
from selenium.webdriver.chrome.options import Options
# 開啓Proxy:注意指定自己下載解壓後路徑
server = Server(r'C:\Users\Administrator\Downloads\browsermob-proxy-2.1.4-bin\browsermob-proxy-2.1.4\bin\browsermob-proxy.bat')
server.start()
proxy = server.create_proxy()
# 配置Proxy啓動WebDriver
chrome_options = Options()
chrome_options.add_argument('--proxy-server={0}'.format(proxy.proxy))
chrome_options.add_argument('--incognito')
driver = webdriver.Chrome(chrome_options=chrome_options)
# 獲取返回內容
base_url = "http://webapi.cninfo.com.cn/#/marketDataDate"
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找到數據接口
if "api/sysapi/p_sysapi" in _url:
_response = entry['response']
_content = _response['content'] # ['text']
# 獲取接口返回內容
print(_content)
# 停止代理服務,退出selenium
server.stop()
driver.quit()
3. 踩坑
兩個庫使用都很簡單,模式是固定的,不過一開始我始終未能拿到數據,一直顯示數據爲空,具體調試信息如下:
我們可以通過設置無痕模式chrome_options.add_argument('--incognito')
處理緩存,但只有第一次有效果。
針對緩存問題,我們可以每次運行程序前,手動清理下緩存(在Chrome瀏覽器中打開chrome://settings/clearBrowserData頁面進行清理)。
如果有好的建議歡迎留言!
參考資料
- selenium+python配置chrome瀏覽器的選項
- Python3+Selenium 配置Chrome選項
- Selenium爬蟲-獲取瀏覽器Network請求和響應
- Selenium 3 + BrowserMobProxy 2.1.4 模擬瀏覽器訪問 (含趟坑)
- HOW TO CLEAR THE CHROME BROWSER CACHE WITH SELENIUM WEBDRIVER/CHROMEDRIVER
聲明
本文章僅供用於技術研究用途,請勿利用文章內容操作用於違反法律的事情。
關於作者
歡迎各位關注公衆號和QQ羣進行技術交流,關注有福利喔。
微信公衆號:
qq羣:IT技術控/953949723