文檔:https://github.com/SeleniumHQ/docker-selenium
1.背景
在無法使用的正常的接口請求數據時,我們想到最多的就是使用了瀏覽器進行抓取
2.正常流程
windows下使用selenium找標籤,定位標籤,最終在windows下完成初步代碼測試
selenium-->定位標籤-->執行執行相應的瀏覽器操作-->測試(這一切測試過程是可見)
3.問題
1.我們如何將寫好的代碼放到Linux系統,長期的運行呢?
2.是否在windows下能夠正常運行的代碼,放到Linux下,就可以正常跑呢?
答案是:
1.我們可以將代碼放到Linux下長期跑,並且我們做到分佈式,這一點對於大數據非常有用!
2.windows下的代碼也許可以跑,放到Linux下不一定正確,大部分人Linux的瀏覽器估計想到的都是Phantomjs,這種瀏覽器,其實有很多bug,比如:
a) 如果你有登錄操作,他不一定能處理登陸的彈框
b) Phantomjs的渲染方式與正常瀏覽器渲染方式相差很大
c) Phantomjs最大的作用在於執行js
所以你如果遇到比較複雜的網站,Phantomjs不一定能跑通帶代碼
4.解決辦法
使用docker的selenium瀏覽器
好處:
a) Linux下可以運行
b) 支持遠程連接瀏覽器
c) 便於搭建分佈式
d) 無需在關心無界面與有界面的區別
e) 可以使用市場上最火的firefox,chrome,sarifi等,靈活性非常強
5.使用樣例
1.拉取官方鏡像
[root@i ~]# docker pull selenium/standalone-chrome
2.運行瀏覽器容器
[root@i ~]# docker run -d -p 4444:4444 selenium/standalone-chrome
or
[root@i ~]# docker run -d -p 4444:4444 -v /dev/shm:/dev/shm selenium/standalone-chrome
3.測試用例
import multiprocessing
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
def test():
driver = webdriver.Remote( command_executor="http://127.0.0.1:4444/wd/hub", desired_capabilities=DesiredCapabilities.CHROME )
driver.get("http://www.baidu.com")
print(driver.title)
driver.close()
def main():
pool = multiprocessing.Pool(10)
for one in range(100):
pool.apply_async(test)
pool.close()
pool.join()
if __name__ == '__main__':
main()
4.運行結果
...
百度一下,你就知道
百度一下,你就知道
百度一下,你就知道
...
6.如何搭建分佈式
官方中給出selenium/hub這個鏡像,該鏡像的作用類似於中央處理器,可以管理每一個瀏覽器節點
https://github.com/SeleniumHQ/docker-selenium文檔中提到selenium grid給我們提供了兩個東西。一個叫hub,一個叫node,hub被稱爲總控節點,node稱之爲節點
結構如下 :
1.拉取官方鏡像hub
[root@i ~]# docker pull selenium/node-chrome
[root@i ~]# docker pull selenium/hub
[root@i ~]# docker pull selenium/node-firefox
2.啓動鏡像
[root@i ~]# docker run -p 5555:4444 -d --name selenium_hub selenium/hub
[root@i ~]# docker run -P -d --link selenium_hub:hub selenium/node-firefox
3.驗證
瀏覽器中輸入http://xx.xx.xx.xx:5555/grid/console
你會發現有一個火狐節點被註冊管理了
4.測試用例
#coding=utf-8
from selenium import webdriver
firefox_capabilities ={
"browserName": "firefox",
"version": "50.0",#注意版本號一定要寫對
"platform": "ANY",
"javascriptEnabled": True,
"marionette": True,
}
browser=webdriver.Remote("http://192.168.99.100:5555/wd/hub",desired_capabilities=firefox_capabilities) #注意端口號5555是我們上文中映射的宿主機端口號
browser.get("http://www.baidu.com")
print(browser.title)
browser.close()
問題:
再次在IDE運行下這個腳本,發現一直處於阻塞狀態也不報錯,得不到hub遠程的執行信息
我認爲這種分佈式一般只是針對專用於測試用的,並非爬蟲分佈式
5.另外思路
利用單節點docker,我們分別部署後,對每次請求瀏覽器實例時可以隨機分配,這種分佈式既好搭,並且不會消耗太多內存(經測試)
利用k8s搭建真正的分佈式瀏覽器,搭建方法:https://blog.csdn.net/xzpdxz/article/details/89179316