背景
前面的教程實現了在遠程服務器上部署selenium+chrome/firefox+vncserver實現了遠程服務器端腳本運行的GUI可視化。這樣不方便的地方是,腳本需要在服務器端編輯或者上傳腳本到服務器端,對于調試中的項目來說十分不方便。
看了selenium remote server 的介紹,selenium可以實現不同機器之間的交互控制。在機器A上運行remote server控制機器B上的瀏覽器。 這樣配上VNC Viewer可以很方便的進行可視化操作了。
這方面的資料很少,因為上面提到的東西其實完全可以在本地機器上實現,本地運行腳本,本地瀏覽器可視化。但是筆主由于要使用國外代理PROXY,在國內網絡環境下,腳本十分緩慢。如果瀏覽器環境在境外服務器運行(網絡是國外的網絡),然后實現本地腳本遠程控制,同時GUI進行可視化,就完美實現了自己的需求。廢話不多說進入正題,希望對有需要的朋友提供幫助,畢竟國內資料太少,很多selenium教程還停留在selenium1 或者 selenium2,很多東西發生了變化。
思路
思路其實很簡單,根據官方網站介紹,只需要在服務器端安裝selenium server就行了。
需要安裝JRE
(centos7 上有默認安裝的openjdk,最好卸載后安裝完整版,過程掠過)
下載地址:https://pypi.python.org/pypi/selenium
筆者當前版本為:Selenium Standalone Server 3.11.0
在服務器終端運行:java -jar selenium-server-standalone-3.11.0.jar
由于有VNC Server可以在GUI的瀏覽器“http://127.0.0.1:4444/wd/hub”上查看selenium server的控制面板:
根據教程介紹,本地客戶端的代碼如下:
driver = RemoteWebDriver(command_executor='http://<remoteserver external IP>:4444/wd/hub', desired_capabilities=desired_capabilities)
driver.get('http://www.google.com')
print('ok, it is done')
按照教程就可以正常運行了,但是遇到的問題很多。
遇到的問題以及解決方法
1.服務器端,root用戶是不能直接運行chrome的。不然無法啟動chrome。可行的方法是切換用戶,或者在啟動chrome時添加‘--no-sandbox'參數
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--user-data-dir')
chrome_options.add_argument('--dns-prefetch-disable')
chrome_options.add_argument('--lang=en-US')
chrome_options.add_argument('--disable-setuid-sandbox')
chrome_options.add_argument('--disable-gpu')
driver = RemoteWebDriver(command_executor='http://<remoteserver external IP>:4444/wd/hub'', desired_capabilities=chrome_options.to_capabilities())
中間部分參數是可選的,‘--no-sandbox'不能去掉。
- 遇到無法連接遠程服務器的問題,連接無響應。
在測試過程中遇到連接無響應的情況,嘗試開放服務器端口,以及關閉防火墻都無法解決。目前還沒有找到正確的解決方案。猜想是因為selenium server 沒有綁定到外部IP上。
但是查看selenium的幫助文檔:
java -jar selenium-server-standalone-3.11.0.jar -h
沒有查看到有綁定IP的選項。
查詢了很多資料,發現有selenium2可以直接綁定外部IP的教程,但是按照教程運行,提示無法找到執行參數。
最后經過考慮,選用了使用selenium grid的替代方案。
1.首先啟動設置hub
java -Dwebdriver.chrome.whitelistedIps="" -jar selenium-server-standalone-3.11.0.jar -role hub -host <外部IP>
這里要用到-Dwebdriver.chrome.whitelistedIps這個參數,不然會報錯only local connect allowed.
2.啟動設置一個node
java -Dwebdriver.chrome.whitelistedIps="" -jar selenium-server-standalone-3.11.0.jar -role node -port <端口號>
這里最好不要設置4444,第一次設置4444報錯,可能和hub的端口沖突了,但是我沒有第二次實驗。
同時一定要設置開放防火墻的端口。
完整代碼如下:
from selenium.webdriver.chrome.webdriver import RemoteWebDriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--user-data-dir')
chrome_options.add_argument('--dns-prefetch-disable')
chrome_options.add_argument('--lang=en-US')
chrome_options.add_argument('--disable-setuid-sandbox')
chrome_options.add_argument('--disable-gpu')
driver = RemoteWebDriver(command_executor='http://<服務器IP>:<設置的node端口>/wd/hub', desired_capabilities=chrome_options.to_capabilities())
driver.get('http://www.google.com')
print('ok it is done')
經過測試,可以正常運行。
遺留的問題是:
不能直接使用selenium rc,需要用selenium grid才能實現。
有知道的朋友,如能告知不勝感謝。