一、webdriver继承关系

在selenium中,无论是常用的Firefox Driver 还是Chrome Driver和Ie Drive,他们都继承至selenium\webdriver\remote下webdriver.py中的WebDriver 类,如下

chrome WebDriver

selenium\webdriver\chrome下webdriver.py中WebDriver定义如下

from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver

class WebDriver(RemoteWebDriver):
"""
Controls the ChromeDriver and allows you to drive the browser.
"""

firefox WebDriver

selenium\webdriver\firefox 下webdriver.py中WebDriver定义如下

from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver

class WebDriver(RemoteWebDriver):
pass

ie WebDriver

selenium\webdriver\ie  下webdriver.py中WebDriver定义如下

from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver

class WebDriver(RemoteWebDriver):

    def __init__(self, executable_path='IEDriverServer.exe', capabilities=None,
port=DEFAULT_PORT, timeout=DEFAULT_TIMEOUT, host=DEFAULT_HOST,
log_level=DEFAULT_LOG_LEVEL, log_file=DEFAULT_LOG_FILE):
......

如上源码:from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver 都是继承至RemoteWebDriver ,并主要重写__init__方法

其他方法主要继承至父类RemoteWebDriver ,因此着重看下RemoteWebDriver 类中的方法

1、find类

编写脚本常用的查找页面元素方法

def find_element_by_id(self, id_):
#Finds an element by id.'''
pass
def find_elements_by_id(self, id_):
#Finds multiple elements by id.
pass
def find_element_by_xpath(self, xpath):
#Finds an element by xpath.
pass
def find_elements_by_xpath(self, xpath):
#Finds multiple elements by xpath.
pass
def find_element_by_link_text(self, link_text):
#Finds an element by link text
pass
def find_elements_by_link_text(self, text):
#Finds elements by link text.
pass
def find_element_by_partial_link_text(self, link_text):
#Finds elements by a partial match of their link text.
pass
def find_elements_by_partial_link_text(self, link_text):
#Finds an element by a partial match of its link text.
pass
def find_element_by_name(self, name):
#Finds an element by name.
pass
def find_elements_by_name(self, name):
#Finds elements by name.
pass
def find_element_by_tag_name(self, name):
#Finds an element by tag name.
pass
def find_elements_by_tag_name(self, name):
#Finds elements by tag name.
pass
def find_element_by_class_name(self, name):
Finds an element by class name.
pass
def find_elements_by_class_name(self, name):
#Finds elements by class name.
pass
def find_element_by_css_selector(self, css_selector):
#Finds an element by css selector.
pass
def find_elements_by_css_selector(self, css_selector):
#Finds elements by css selector.
pass
def find_element(self, by=By.ID, value=None):
#'Private' method used by the find_element_by_* methods.
pass
def find_elements(self, by=By.ID, value=None):
#'Private' method used by the find_elements_by_* methods.
pass

通过查看源码,其实以上方法都是通过调用

self.find_element(by=By.XXX, value=name)或者self.find_elements(by=By.XXX, value=name)方法来重新定义的

    def find_element(self, by=By.ID, value=None):
"""
'Private' method used by the find_element_by_* methods. :Usage:
Use the corresponding find_element_by_* instead of this. :rtype: WebElement
"""
if self.w3c:
if by == By.ID:
by = By.CSS_SELECTOR
value = '[id="%s"]' % value
elif by == By.TAG_NAME:
by = By.CSS_SELECTOR
elif by == By.CLASS_NAME:
by = By.CSS_SELECTOR
value = ".%s" % value
elif by == By.NAME:
by = By.CSS_SELECTOR
value = '[name="%s"]' % value
return self.execute(Command.FIND_ELEMENT, {
'using': by,
'value': value})['value']

其中by.XXX是selenium\webdriver\common下by.py文件中By类定义的静态常量

class By(object):
"""
Set of supported locator strategies.
""" ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"

通过以上分析,不难发现,只要掌握了self.find_element(by=By.XXX, value=name)或者self.find_elements(by=By.XXX, value=name)方法,已就意味着掌握了全部的查找定位页面元素的方法

2、除了常用的find类方法外,以下方法在编写脚本是也是常用的

ef get(self, url):
"""
Loads a web page in the current browser session.
""" @property
def title(self):
"""Returns the title of the current page.""" @property
def current_url(self):
"""Gets the URL of the current page.""" @property
def current_window_handle(self):
"""Returns the handle of the current window.""" def maximize_window(self):
"""Maximizes the current window that webdriver is using""" @property
def switch_to(self):
return self._switch_to # Target Locators
def switch_to_active_element(self):
""" Deprecated use driver.switch_to.active_element""" def switch_to_window(self, window_name):
""" Deprecated use driver.switch_to.window""" def switch_to_frame(self, frame_reference):
""" Deprecated use driver.switch_to.frame""" def switch_to_default_content(self):
""" Deprecated use driver.switch_to.default_content""" def switch_to_alert(self):
""" Deprecated use driver.switch_to.alert"""

其中使用@property修饰的,可以当作为属性来使用,如driver.current_url

3、为什么在实际应用过程中通过from selenium import webdriver引入webdriver,然后通过webdriver.Chrome()就可以实例化Chrome的Driver对象呢?

从以上selenium目录结构,理论上需要通过以下来导入

#导入chrome的WebDriver
from selenium.webdriver.chrome.webdriver import WebDriver
#导入firefox的WebDriver
from selenium.webdriver.firefox.webdriver import WebDriver
#导入ie的WebDriver
from selenium.webdriver.ie.webdriver import WebDriver

selenium项目目录结构

selenium
│ __init__.py

├─common
│ │ exceptions.py
│ │ __init__.py

├─webdriver
│ │ __init__.py
│ │
│ ├─android
│ │ │ webdriver.py
│ │ │ __init__.py
│ │
│ ├─blackberry
│ │ │ webdriver.py
│ │ │ __init__.py
│ │
│ ├─chrome
│ │ │ options.py
│ │ │ remote_connection.py
│ │ │ service.py
│ │ │ webdriver.py
│ │ │ __init__.py
│ │
│ ├─common
│ │ │ action_chains.py
│ │ │ alert.py
│ │ │ by.py
│ │ │ desired_capabilities.py
│ │ │ keys.py
│ │ │ proxy.py
│ │ │ service.py
│ │ │ touch_actions.py
│ │ │ utils.py
│ │ │ __init__.py
│ │ │
│ │ ├─actions
│ │ │ │ action_builder.py
│ │ │ │ input_device.py
│ │ │ │ interaction.py
│ │ │ │ key_actions.py
│ │ │ │ key_input.py
│ │ │ │ mouse_button.py
│ │ │ │ pointer_actions.py
│ │ │ │ pointer_input.py
│ │ │ │ __init__.py
│ │ │
│ │ │
│ │ ├─html5
│ │ │ │ application_cache.py
│ │ │ │ __init__.py
│ │
│ ├─edge
│ │ │ options.py
│ │ │ service.py
│ │ │ webdriver.py
│ │ │ __init__.py
│ ├─firefox
│ │ │ extension_connection.py
│ │ │ firefox_binary.py
│ │ │ firefox_profile.py
│ │ │ options.py
│ │ │ remote_connection.py
│ │ │ service.py
│ │ │ webdriver.py
│ │ │ webdriver.xpi
│ │ │ webdriver_prefs.json
│ │ │ webelement.py
│ │ │ __init__.py
│ │
│ ├─ie
│ │ │ service.py
│ │ │ webdriver.py
│ │ │ __init__.py
│ ├─opera
│ │ │ options.py
│ │ │ webdriver.py
│ │ │ __init__.py
│ ├─phantomjs
│ │ │ service.py
│ │ │ webdriver.py
│ │ │ __init__.py
│ ├─remote
│ │ │ command.py
│ │ │ errorhandler.py
│ │ │ file_detector.py
│ │ │ getAttribute.js
│ │ │ isDisplayed.js
│ │ │ mobile.py
│ │ │ remote_connection.py
│ │ │ switch_to.py
│ │ │ utils.py
│ │ │ webdriver.py
│ │ │ webelement.py
│ │ │ __init__.py
│ ├─safari
│ │ │ service.py
│ │ │ webdriver.py
│ │ │ __init__.py
│ ├─support
│ │ │ abstract_event_listener.py
│ │ │ color.py
│ │ │ events.py
│ │ │ event_firing_webdriver.py
│ │ │ expected_conditions.py
│ │ │ select.py
│ │ │ ui.py
│ │ │ wait.py
│ │ │ __init__.py

通过查看selenium\webdriver下__init__.py文件发现

from .firefox.webdriver import WebDriver as Firefox  # noqa
from .firefox.firefox_profile import FirefoxProfile # noqa
from .chrome.webdriver import WebDriver as Chrome # noqa
from .chrome.options import Options as ChromeOptions # noqa
from .ie.webdriver import WebDriver as Ie # noqa

其实是因为该出已经导入了,所以才可以直接使用Firefox、Chrome

selenium之python源码解读-webdriver继承关系的更多相关文章

  1. selenium之python源码解读-expected_conditions

    一.expected_conditions 之前在 selenium之python源码解读-WebDriverWait 中说到,until方法中method参数,需要传入一个function对象,如果 ...

  2. selenium之python源码解读-WebDriverWait

    一.显示等待 所谓显示等待,是针对某一个特定的元素设置等待时间,如果在规定的时间内找到了该元素,就执行相关的操作,如果在规定的时间内没有找到该元素,在抛出异常 PS:注意显示等待和隐身等待的区别,隐身 ...

  3. 如何判断一个Http Message的结束——python源码解读

    HTTP/1.1 默认的连接方式是长连接,不能通过简单的TCP连接关闭判断HttpMessage的结束. 以下是几种判断HttpMessage结束的方式: 1.      HTTP协议约定status ...

  4. python 源码解读2

    http://www.jianshu.com/users/4d4a2f26740b/latest_articles http://blog.csdn.net/ssjhust123/article/ca ...

  5. DRF(1) - REST、DRF(View源码解读、APIView源码解读)

    一.REST 1.什么是编程? 数据结构和算法的结合. 2.什么是REST? 首先回顾我们曾经做过的图书管理系统,我们是这样设计url的,如下: /books/ /get_all_books/ 访问所 ...

  6. REST、DRF(View源码解读、APIView源码解读)

    一 . REST            前言 1 . 编程 : 数据结构和算法的结合 .小程序如简单的计算器,我们输入初始数据,经过计算,得到最终的数据,这个过程中,初始数据和结果数据都是数据,而计算 ...

  7. Restful 1 -- REST、DRF(View源码解读、APIView源码解读)及框架实现

    一.REST 1.什么是编程? 数据结构和算法的结合 2.什么是REST? - url用来唯一定位资源,http请求方式来区分用户行为 首先回顾我们曾经做过的图书管理系统,我们是这样设计url的,如下 ...

  8. SDWebImage源码解读之SDWebImageDownloaderOperation

    第七篇 前言 本篇文章主要讲解下载操作的相关知识,SDWebImageDownloaderOperation的主要任务是把一张图片从服务器下载到内存中.下载数据并不难,如何对下载这一系列的任务进行设计 ...

  9. SDWebImage源码解读之SDWebImageCache(下)

    第六篇 前言 我们在SDWebImageCache(上)中了解了这个缓存类大概的功能是什么?那么接下来就要看看这些功能是如何实现的? 再次强调,不管是图片的缓存还是其他各种不同形式的缓存,在原理上都极 ...

随机推荐

  1. 【转帖】为什么redis 是单线程的?

    为什么redis 是单线程的? https://cloud.tencent.com/developer/article/1120615 云服务器企业新用户优先购,享双11同等价格 立即抢购 以前一直有 ...

  2. [转帖]Java 2019 生态圈使用报告,这结果你赞同吗?

    Java 2019 生态圈使用报告,这结果你赞同吗? http://www.51testing.com/html/94/n-4462794.html 发表于:2019-10-15 17:10  作者: ...

  3. Java的设计模式(6)— 模板模式

    定义一个操作中算法的骨架,将一些步骤放在子类实现,使得子类可以不改变一个算法结构即子类可以重定义该算法的某些特定步骤. 主要有两个角色: 1. 抽象模板 :是一个抽象类,并实现了一个具体模板方法,这个 ...

  4. python 之 前端开发(form标签、单选框、多选框、file上传文件、按钮、label标签、下拉列表、textarea标签、fieldset标签、table标签)

    11.25 form标签 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  5. 从零开始学Flask框架-004

    Flask-Moment pip install flask-moment 除了moment.js,Flask-Moment 还依赖jquery.js.但是Bootstrap 已经引入了jquery. ...

  6. MySQL容量规划和性能测试

    性能容量关键指标: 每秒tps,峰值tps 基础数据量,日均增长数据量 最大连接数 内存分配 IOPS 重点关注指标: 业务指标: 每秒并发用户请求.每秒订单数.用户请求响应时长 折算成性能指标: q ...

  7. Authorization

    授权,也叫访问控制,即在应用中控制谁访问哪些资源(如访问页面/编辑数据/页面操作等).在授权中需了解的几个关键对象:主体(Subject).资源(Resource).权限(Permission).角色 ...

  8. 如何加入 Skype for Business 会议?

    参加一个线上培训,收到了Skype的参会地址,是这个样子的 然后就是一脸懵逼的不知道怎么参加会议了.找了半天终于在同事的帮助下参加成功. 我的参加方法:在Window上用Skype for Busin ...

  9. VS.NET(C#)--2.1认识控件

    Web控件 四种控件 1.HTML控件 2.HTML服务器控件    在服务器端执行 3.ASP.NET服务器控件   在服务器端执行 4.用户控件和自定义控件  用户自定义控件在服务器端执行 注意: ...

  10. VS.NET(C#)--1.5_VS菜单功能

    VS菜单功能 文件菜单 1.新建 2.添加 编辑菜单 1.快速查找  ctrl+F 2.快速替换   ctrl+H 3.在文件中查找ctrl+shift+F 4.在文件中替换ctrl+shift+H ...