博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
selenium是如何启动浏览器的
阅读量:6961 次
发布时间:2019-06-27

本文共 6401 字,大约阅读时间需要 21 分钟。

前几天有同学问到selenium是怎么样启动浏览器的(selenium启动浏览器的原理),当时稍微讲解了一下,不过自我感觉不够具体,现在特地把启动原理通过代码和一系列操作给串联起来,希望可以帮助大家更好的理解。

以chrome浏览器为例,selenium启动chrome浏览器的代码如下:

def __init__(self, executable_path="chromedriver", port=0,                 options=None, service_args=None,                 desired_capabilities=None, service_log_path=None,                 chrome_options=None):        """        Creates a new instance of the chrome driver.        Starts the service and then creates new instance of chrome driver.        :Args:         - executable_path - path to the executable. If the default is used it assumes the executable is in the $PATH         - port - port you would like the service to run, if left as 0, a free port will be found.         - desired_capabilities: Dictionary object with non-browser specific           capabilities only, such as "proxy" or "loggingPref".         - options: this takes an instance of ChromeOptions        """        if chrome_options:            warnings.warn('use options instead of chrome_options', DeprecationWarning)            options = chrome_options        if options is None:            # desired_capabilities stays as passed in            if desired_capabilities is None:                desired_capabilities = self.create_options().to_capabilities()        else:            if desired_capabilities is None:                desired_capabilities = options.to_capabilities()            else:                desired_capabilities.update(options.to_capabilities())        self.service = Service(            executable_path,            port=port,            service_args=service_args,            log_path=service_log_path)        self.service.start()        try:            RemoteWebDriver.__init__(                self,                command_executor=ChromeRemoteConnection(                    remote_server_addr=self.service.service_url),                desired_capabilities=desired_capabilities)        except Exception:            self.quit()            raise        self._is_remote = False

其中跟浏览器启动密切相关的是这几句

self.service = Service(    executable_path,    port=port,    service_args=service_args,    log_path=service_log_path)self.service.start()

通过查看跟相关的代码复盘得到启动逻辑: 调用chromedriver可执行文件运行chromedirver。这也是为什么我们需要把chromedriver放到系统PATH里的原因。

所以selenium先启动了chromedriver。当然,我们可以手工启动chromedriver来模拟这个启动过程。

在命令行中运行下面的命令chromedirver

你应该可以看来类似的结果

Starting ChromeDriver 2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011) on port 9515Only local connections are allowed.

这样我们就手工启动了chromedriver。driver监听的端口是9515.

启动了driver之后,我们需要告诉driver打开浏览器。selenium的里这一过程如下

def start_session(self, capabilities, browser_profile=None):        """        Creates a new session with the desired capabilities.        :Args:         - browser_name - The name of the browser to request.         - version - Which browser version to request.         - platform - Which platform to request the browser on.         - javascript_enabled - Whether the new session should support JavaScript.         - browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object. Only used if Firefox is requested.        """        if not isinstance(capabilities, dict):            raise InvalidArgumentException("Capabilities must be a dictionary")        if browser_profile:            if "moz:firefoxOptions" in capabilities:                capabilities["moz:firefoxOptions"]["profile"] = browser_profile.encoded            else:                capabilities.update({'firefox_profile': browser_profile.encoded})        w3c_caps = _make_w3c_caps(capabilities)        parameters = {"capabilities": w3c_caps,                      "desiredCapabilities": capabilities}        response = self.execute(Command.NEW_SESSION, parameters)        if 'sessionId' not in response:            response = response['value']        self.session_id = response['sessionId']        self.capabilities = response.get('value')        # if capabilities is none we are probably speaking to        # a W3C endpoint        if self.capabilities is None:            self.capabilities = response.get('capabilities')        # Double check to see if we have a W3C Compliant browser        self.w3c = response.get('status') is None        self.command_executor.w3c = self.w3c

这一过程的核心就是就是向localhost:9515/session发送1个POST请求,并发送1个json对象,默认情况下,这个对象应该是下面这个样子。

{    "capabilities": {        "alwaysMatch": {            "browserName": "chrome",            "goog:chromeOptions": {                "args": [],                "extensions": []            },            "platformName": "any"        },        "firstMatch": [            {}        ]    },    "desiredCapabilities": {        "browserName": "chrome",        "goog:chromeOptions": {            "args": [],            "extensions": []        },        "platform": "ANY",        "version": ""    }}

简单理解就是告诉remote driver打开什么浏览器,上面的例子里我们打开的是chrome浏览器。

我们可以手工还原这个过程。

确保chromedriver是在运行中的,然后打开postman,构造1个POST请求,路径是localhost:9515/session。在Body里选择raw和JSON(application/json), 贴入上面的json字符串,如下图所示

postman

点击send,几秒之后chrome浏览器应该可以正常启动,并且postman的response里会有大致如下的返回值

{    "sessionId": "ad4407e133cfd5f3f49bff4c2f1f087a",    "status": 0,    "value": {        "acceptInsecureCerts": false,        "acceptSslCerts": false,        "applicationCacheEnabled": false,        "browserConnectionEnabled": false,        "browserName": "chrome",        "chrome": {            "chromedriverVersion": "2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011)",            "userDataDir": "/var/folders/s6/f2_brc114wv2g8w0qggk_m2c0000gn/T/.org.chromium.Chromium.NMsAKJ"        },        "cssSelectorsEnabled": true,        "databaseEnabled": false,        "handlesAlerts": true,        "hasTouchScreen": false,        "javascriptEnabled": true,        "locationContextEnabled": true,        "mobileEmulationEnabled": false,        "nativeEvents": true,        "networkConnectionEnabled": false,        "pageLoadStrategy": "normal",        "platform": "Mac OS X",        "rotatable": false,        "setWindowRect": true,        "takesHeapSnapshot": true,        "takesScreenshot": true,        "unexpectedAlertBehaviour": "",        "version": "66.0.3359.181",        "webStorageEnabled": true    }}

上面的返回里最重要的就是sessionId,因为后面所有跟浏览器的交互都是基于该id进行的。

总结

  • selenium里,selenium client先打开chromedriver
  • chromedirver创建session时打开了浏览器,所以浏览器的打开跟selenium无关,完全是chromedriver的能力

更多

其实上面的例子里我们手工调用了里的协议,创建了webdriver session。具体的细节大家可以参考协议了解更多。

转载地址:http://eywsl.baihongyu.com/

你可能感兴趣的文章
单臂路由的实现
查看>>
还有人不认识通讯诈骗,短信验证码带你认识一下
查看>>
用maven时出现,报错 miss 一些包,但是发现项目里已经引入了,但还是报错
查看>>
大快DKhadoop大数据处理平台详解
查看>>
摄影菜鸟使用的相机镜头术语大全分享
查看>>
XenServer部署系列之06——网络配置
查看>>
Python黑科技:50行代码运用Python+OpenCV实现人脸追踪+详细教程+快速入门+图像识...
查看>>
软件测试质量和效率评价之我见
查看>>
kloxo增加了域名,怎么不能访问?如何重启web服务?
查看>>
国学题库整理
查看>>
jquery chosen 插件 动态设置+更新选项值
查看>>
求最大值及其下标
查看>>
战力会议1
查看>>
水印情缘。。。
查看>>
为什么重写equals一定要重写hashCode?
查看>>
HDU Problem 4006 The kth great number 【队列】
查看>>
win8阉割版中文输入法
查看>>
Codeforces VK Cup 2015 A.And Yet Another Bracket Sequence(后缀数组+平衡树+字符串)
查看>>
以Drools5.5为例说明“规则引擎在业务系统中应用”---起始篇
查看>>
linux清理内存
查看>>