selenium是如何启动浏览器的
前几天有同学问到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()
通过查看跟Service相关的代码复盘得到启动逻辑: 调用chromedriver可执行文件运行chromedirver。这也是为什么我们需要把chromedriver放到系统PATH里的原因。
所以selenium先启动了chromedriver。当然,我们可以手工启动chromedriver来模拟这个启动过程。
在命令行中运行下面的命令chromedirver
你应该可以看来类似的结果
Starting ChromeDriver 2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011) on port 9515
Only 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字符串,如下图所示

点击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协议里的new session协议,创建了webdriver session。具体的细节大家可以参考协议了解更多。
selenium是如何启动浏览器的的更多相关文章
- Selenium自动化测试之启动浏览器
Selenium自动化测试之启动浏览器 一.Eclipse新建java工程 1.新建java工程:File->New->Java Project,输入Project name:如AutoT ...
- Selenium WebDriver原理(二):Selenium是如何操纵浏览器的?
前言 上一篇文章<selenium webdriver 是怎么运行的>用了一个简单的例子--搭出租车,形象地讲解selenium webdriver 是如何运行的,而这一篇文章可以理解为深 ...
- 使用selenium时,使用从系统启动浏览器与通过自动化驱动方式启动浏览器控件ID不一样解决方法
最近遇到一个怪事,通过正常打开浏览器,按照正常的web登录然后点击进入系统流程,将各控件的ID识别成功,然后使用 python3+selenium写好脚本,高高兴兴的用脚本跑时老是提示找不到控件,然后 ...
- selenium+python自动化87-Chrome浏览器静默模式启动(headless)
前言 selenium+phantomjs可以打开无界面的浏览器,实现静默模式启动浏览器完成自动化测试,这个模式是极好的,不需要占用电脑的屏幕. 但是呢,phantomjs这个坑还是比较多的,并且遇到 ...
- 自动化测试-selenium启动浏览器
在自动化测试过程中,通过selenium启动浏览器时,可能需要加载插件(如测试用的firebug.或产品中要求必须添加某插件等).读取用户数据(自己浏览器的配置文件/别人直接给的浏览器配置文件).设置 ...
- Java&Selenium根据实参启动相应浏览器
Java&Selenium根据实参启动相应浏览器 /** * 定义函数initBrowser * @param browser:字符串参数chrome/ie/xx * @return 并返回驱 ...
- python脚本中selenium启动浏览器报错os.path.basename(self.path), self.start_error_message) selenium.common.excep
在python脚本中,使用selenium启动浏览器报错,原因是未安装浏览器驱动,报错内容如下: # -*- coding:utf-8 -*-from selenium import webdrive ...
- 爬虫(五)—— selenium模块启动浏览器自动化测试
目录 selenium模块 一.selenium介绍 二.环境搭建 三.使用selenium模块 1.使用chrome并设置为无GUI模式 2.使用chrome有GUI模式 3.查找元素 4.获取标签 ...
- 基于Selenium2+Java的UI自动化(2) - 启动浏览器
一.准备工作 我们常用的浏览器主要有三个:chrome.Firefox.IE:其中chrome 和 IE 需要下载驱动程序,才能启动浏览器,注意驱动程序有32位和64位两种. 另外:如何查看本机的浏览 ...
随机推荐
- day8--socket文件传输
FTP server 1.读取文件名 2.检测文件是否存在 3.打开文件 4.检测文件大小(告诉客户端发送文件的大小) 5.发送文件大小和MD5值给客户端,MD5 6.等待客户端确认(防止粘包) 7. ...
- 解决/bin/sh: 1: syntax error: "(" unexpected错误,以及更换bash仍然无法解决的问题
编译文件的时候出现 /bin/sh: 1: syntax error: "(" unexpected 错误. 网上查到的资料都是: (1)在脚本前写#!/bin/bash (2)执 ...
- Shell命令 中|| &&使用
转自:https://www.cnblogs.com/aaronLinux/p/8340281.html
- JavaSE| 数据类型| 运算符| 进制与补码反码等
JavaSE JavaSE是学习JavaWeb.JavaEE以及Android开发的基础 边听边思考边做“笔记” 不要完全依赖书和视频: 捷径:敲.狂敲: 规范:加注释: 难点,不懂的记录下时间再回头 ...
- hdu1003 Max Sum【最大连续子序列之和】
题目链接:https://vjudge.net/problem/HDU-1003 题目大意:给出一段序列,求出最大连续子序列之和,以及给出这段子序列的起点和终点. 解题思路:最长连续子序列之和问题其实 ...
- Redis分布式锁实现方式(附有正解及错误示例)
一.前言 本文内容主要来自博客:https://wudashan.com/2017/10/23/Redis-Distributed-Lock-Implement/,本文用于归纳总结及笔记用途,如有需要 ...
- codeforces-1111
https://www.cnblogs.com/31415926535x/p/10397007.html codeforces 537 div2 A 题意就是给你两个字符串,然后如果s,t的对应位上的 ...
- 【Ray Tracing The Next Week 超详解】 光线追踪2-7 任意长方体 && 场景案例
上一篇比较简单,很久才发是因为做了一些好玩的场景,后来发现这一章是专门写场景例子的,所以就安排到了这一篇 Preface 这一篇要介绍的内容有: 1. 自己做的光照例子 2. Cornell box画 ...
- 【nodeJS爬虫】前端爬虫系列
写这篇 blog 其实一开始我是拒绝的,因为爬虫爬的就是cnblog博客园.搞不好编辑看到了就把我的账号给封了:). 言归正传,前端同学可能向来对爬虫不是很感冒,觉得爬虫需要用偏后端的语言,诸如 ph ...
- ARM总线架构
S3C2440集成了丰富了外设控制器(LCD控制器.USB Device控制器.USB Host控制器.NAND FLASH控制器.I2C控制器.SPI控制器等).要控制这些外设就要设置相应控制器的寄 ...