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启动的。