Selenium实例化+WebDriver工作原理及协议

(一)Selenium实例化过程分析

1、在SE的执行过程中,一般都会有如下一行代码,代表着引入webdriver模板:

from selenium import webdriver

因为我用的是Chrome浏览器来进行自动化测试,那么会通过webdriver.Chrome()方法对webdriver进行实例化:

driver = webdriver.Chrome()

2、因为我们也可以用其他的浏览器,比如火狐FireFox,所以点击webdriver进入一个__init__.py的文件,可以看到有多个浏览器对应的webriver在这里做了个重命名,如下图所示:

Selenium实例化+WebDriver工作原理及协议_第1张图片

3、点击上图中的“.chrome.webdriver”中的“webdriver”就会打开一个webdriver.py文件,可以看到他的初始化方法:

Selenium实例化+WebDriver工作原理及协议_第2张图片

(1)其中executable_path的值就是对应我们安装时,环境变量配置的chromedriver文件的路径名称(默认),我的是在D盘,如下图所示:

(2)要注意的是两者的名称必须相同,如果说我把D盘下的chromewebdriver.exe重命名,那么就会报错。当然,也可以把配置的那个文件路径全部写入Chrome()方法中,代码如下:

driver = webdriver.Chrome(executable_path='D:\ChromeDriver\chromedriver.exe')
或
driver = webdriver.Chrome(r'D:\ChromeDriver\chromedriver.exe')

(3)如果还要设置Chrome()方法中的其他参数,也可以用(参数1=值1,参数2=值2...参数N=值N)得方式去设置。参数的释义如下:

  • executable_path          可执行文件的路径。如果使用默认值,则假定可执行文件位于$PATH中

  • port                               希望服务运行的端口,如果保留为0,则会找到一个空闲端口。

  • options                          ChromeOptions的一个实例

  • service_args                 要传递给驱动程序服务的参数列表

  • desired_capabilities    字典对象与非浏览器特定仅限功能,如“proxy”或“loggingPref”。

  • service_log_path         从驱动程序记录信息的位置

  • chrome options           选项的参数,已弃用

  • keep alive                     是否将Chrome远程连接配置为使用HTTP keep alive。

4、那么当我们设置之后,又是怎么调用的呢?在webdriver.py文件里面我们会看到有这样一段代码:

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

可以看到的是,这里实例化了一个Service,调用了它的start()方法,查看start()方法则可以看到在这里利用的是进程间的调用,即利用子进程subprocess调用了Popen方法,把chromedriver(也就是源码中的“cmd”)传过去,代码如下图所示:

self.process = subprocess.Popen(cmd, env=self.env,
                                close_fds=platform.system() != 'Windows',
                                stdout=self.log_file,
                                stderr=self.log_file,
                                stdin=PIPE)

因此我们也可以直接写一个方法去代替webdriver.Chrome()达到实例化SE的效果,如下面的代码所示:

def test():
    import subprocess
    p = subprocess.Popen("chromedriver") #把chromedriver传进去
    p.communicate() #调用进程间的通信方法

同样地,我们是把chromedriver作为参数放入subprocess的Popen方法中,执行后成功打开了Chrome浏览器,具体见下图:

当然,比起“webdriver.Chrome()”,两者还是有区别的,区别在于webdriver.Chrome()方法可以设置更多的参数,这就是SE实例化的主要内容。

(二)Selenium WebDriver的工作原理

(1)工程师编写自动化测试代码(Python、Java等多种语言不限),通过http协议把代码发送给浏览器驱动;

(2)浏览器驱动里面有个Http Server,它根据特定的端口号(port)监听到请求,对代码进行解析,再发送指令给浏览器;

(3)浏览器接收到后根据指令执行操作,执行完之后再把执行结果反馈给驱动;

(4)浏览器驱动再把结果返回给客户端,如果说是错误的http代码,那么也会把相应的报错信息显示在控制台。

具体图示如下:

Selenium实例化+WebDriver工作原理及协议_第3张图片

要注意的是,API和浏览器驱动是一个C/S架构,也就是说客户机与服务器,客户端产生的每一条Selenium脚本,都会创建一个http请求发送给浏览器驱动。

(三)WebDriver协议

为什么客户端的语言既可以用Java,也可以是Python呢?同一个驱动即可以接受Java请求,也可以接受Python请求?

因为WebDriver使用的是一个公共遵循的协议:Json Wire protocol,且通信格式也是Json。

 

你可能感兴趣的:(Python,Selenium学习)