WebDriver 工作原理
WebDriver是W3C的一個標准,由Selenium主持。
具體的協議標准可以從http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference 查看。
從這個協議中我們可以看到,WebDriver之所以能夠實現與瀏覽器進行交互,是因為瀏覽器實現了這些協議。這個協議是使用JOSN通過HTTP進行傳輸。
它的實現使用了經典的Client-Server模式。客戶端發送一個requset,服務器端返回一個response。
我們明確幾個概念。
Client
編輯代碼,發送代碼。注意:代碼內部已經包裝了webdriver協議。
Server
運行瀏覽器的機器。瀏覽器則通過驅動程序來實現了WebDriver的通訊協議,如:Chrome和IE則是通過ChromeDriver和InternetExplorerDriver實現的。
Session
服務器端需要維護瀏覽器的Session,客戶端首次發送請求的字符串是'/session/$sessionId/url'。服務器端將根據url打開對應的url地址,同時將$sessionId解析成真實的值。然后返回給客戶端。以后客戶端再向瀏覽器發送請求時,將會攜帶session值一起發送。
一.客戶端和瀏覽器在同一台機器上
from selenium import webdriver
import time
browser=webdriver.Chrome()
browser.get("http://www.baidu.com")
1.browser=webdriver.Chrome()這句代碼的解析如下:
通過上面代碼的解析,我們已經知道我們創建了一個實例browser,該實例是webdriver和rmotewebdriver共同擁有的實例。通過webdriver啟動了chromedriver程序,通過rmotewebdriver則啟動了瀏覽器,生成session值。並規定了webdriver協議。
2.driver.get("http://www.google.com")這句代碼的解析:
該get()方法是rmotewebdriver 的方法。該方法直接又調用了rmotewebdriver 的execute()方法。execute()方法就是用來操作瀏覽器做各種事情的。
我們的測試代碼向remote server發送了如下的請求:
POSTsession/285b12e4-2b8a-4fe6-90e1-c35cba245956/url post_data{"url":"http://google.com"}
通過post的方式請求localhost:port/hub/session/session_id/url地址,請求瀏覽器完成跳轉url的操作。
如果上述請求是可接受的,或者說remote server是實現了這個接口,那么remote server會跳轉到該post data包含的url,並返回如下的response
{"name":"get","sessionId":"285b12e4-2b8a-4fe6-90e1-c35cba245956","status":0,"value":""}
該response中包含如下信息
name:remote server端的實現的方法的名稱,這里是get,表示跳轉到指定url;
sessionId:當前session的id;
status:請求執行的狀態碼,非0表示未正確執行,這里是0,表示一切ok不許擔心;
value:請求的返回值,這里返回值為空,如果client調用title接口,則該值應該是當前頁面的title;
如果client發送的請求是定位某個特定的頁面元素,則response的返回值可能是這樣的:
{"name":"findElement","sessionId":"285b12e4-2b8a-4fe6-90e1-c35cba245956","status":0,"value":{"ELEMENT":"{2192893e-f260-44c4-bdf6-7aad3c919739}"}}
name,sessionId,status跟上面的例子是差不多的,區別是該請求的返回值是ELEMENT:{2192893e-f260-44c4-bdf6-7aad3c919739},表示定位到元素的id,通過該id,client可以發送如click之類的請求與 server端進行交互。
二.客戶端遠程瀏覽器
通過上面的實例和以前介紹的內容,我們知道了,客戶端按照webdriver協議編寫一段字符串,這段字符串再通過json的方式發送到瀏覽器端,瀏覽器端則使用chromedriver驅動程序
啟動瀏覽器並跟據發送過來的字符串操作瀏覽器進行相應的工作。
所以,我們想遠程瀏覽器,我們需要有程序去啟動chromedriver程序。然后我們再在客戶端json一段字符串過去。
具體步驟:
1.下載合適的selenium-server,並啟動
目的:啟動chromedriver和設置監聽端口
在win中:
下載地址:https://selenium-release.storage.googleapis.com/index.html?path=3.3/
下載建議:根據您當前的selenium版本下載對應的selenium server版本
在cmd中執行命令:
>> java -Dwebdriver.chrome.driver = “/opt/chromium-browser/chromedriver.exe ” -jar selenium-server-standalone-3.3.1.jar -port 9999
在linux中:
npm install -g selenium-standalone
selenium-standalone install selenium-standalone start
2.編寫客戶端代碼,如下:
from selenium.webdriver.remote import webdriver #這兒直接導入的remote里面的webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities #導入瀏覽器的基本參數 f=webdriver.WebDriver(command_executor="http://192.168.1.103:9999/wd/hub",desired_capabilities=DesiredCapabilities.CHROME) f.get("http://www.baidu.com")
看出這段代碼和上面《一、客戶端和瀏覽器在同一台機器上》里面的代碼有什么不同了嗎?
上面實例化的是chrome 里面的webdriver 。而該實例里實例化的是remote里面的webdriver。這是為什么呢?
因:上面需要啟動chromedriver和設置監聽端口。而該實例里面啟動chromedriver和設置監聽端口是在遠程服務器端通過selenium-server啟動的。