• selenium之python源码解读-webdriver继承关系


    一、webdriver继承关系

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

    chrome WebDriver

    seleniumwebdriverchrome下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

    seleniumwebdriverfirefox 下webdriver.py中WebDriver定义如下

    from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
    
    class WebDriver(RemoteWebDriver):
        pass

    ie WebDriver

    seleniumwebdriverie  下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是seleniumwebdrivercommon下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

    通过查看seleniumwebdriver下__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

  • 相关阅读:
    引用传递函数值
    关于引用(python中的伪指针)的理解
    学生管理系统_排序后通过name删除列表里的字典
    学生管理系统(函数版)
    全局变量和局部变量的理解
    lambda隐藏函数的嵌套
    lambda函数常见用法
    函数的多个返回值
    函数的函数名重名
    函数的嵌套
  • 原文地址:https://www.cnblogs.com/yaoqingzhuan/p/8909126.html
Copyright © 2020-2023  润新知