0


selenium库浅析,基于4.3

selenium库浅析

基于4.3

pip install selenium

安装好后,在sitepackages下

2个主要的目录,

common

webdriver

1- common

该目录一共就一个模块

exceptions.py

① exceptions.py

其中定义了

32个异常

,竟然有个同学面试的时候被问过
异常说明WebDriverException主异常,下面的都继承于它InvalidSwitchToTargetExceptionThrown when frame or window target to be switched doesn’t exist.NoSuchFrameExceptionThrown when frame target to be switched doesn’t exist.NoSuchWindowExceptionThrown when window target to be switched doesn’t exist.NoSuchElementExceptionThrown when element could not be found.NoSuchAttributeExceptionThrown when the attribute of element could not be found.NoSuchShadowRootExceptionThrown when trying to access the shadow root of an element when it does not have a shadow root attached.StaleElementReferenceExceptionThrown when a reference to an element is now “stale”.InvalidElementStateExceptionThrown when a command could not be completed because the element is in an invalid state.UnexpectedAlertPresentExceptionThrown when an unexpected alert has appeared.NoAlertPresentExceptionThrown when switching to no presented alert.ElementNotVisibleExceptionThrown when an element is present on the DOM, but it is not visible, and so is not able to be interacted with.ElementNotInteractableExceptionThrown when an element is present in the DOM but interactions with that element will hit another element due to paint orderElementNotSelectableExceptionThrown when trying to select an unselectable element.InvalidCookieDomainExceptionThrown when attempting to add a cookie under a different domain than the current URL.UnableToSetCookieExceptionThrown when a driver fails to set a cookie.RemoteDriverServerException源码没有给

__doc__

TimeoutExceptionThrown when a command does not complete in enough time.MoveTargetOutOfBoundsExceptionThrown when the target provided to the

ActionsChains

move() method is invalid, i.e. out of document.UnexpectedTagNameExceptionThrown when a support class did not get an expected web element.InvalidSelectorExceptionThrown when the selector which is used to find an element does not return a WebElementImeNotAvailableExceptionThrown when IME support is not available.ImeActivationFailedExceptionThrown when activating an IME engine has failed.InvalidArgumentExceptionThe arguments passed to a command are either invalid or malformed.JavascriptExceptionAn error occurred while executing JavaScript supplied by the user.NoSuchCookieExceptionNo cookie matching the given path name was found amongst the associated cookies of the current browsing context’s active document.ScreenshotExceptionA screen capture was made impossible.ElementClickInterceptedExceptionThe Element Click command could not be completed because the element receiving the events is obscuring the element that was requested to be clicked.InsecureCertificateExceptionNavigation caused the user agent to hit a certificate warning, which is usually the result of an expired or invalid TLS certificate.InvalidCoordinatesExceptionThe coordinates provided to an interaction’s operation are invalid.InvalidSessionIdExceptionOccurs if the given session id is not in the list of active sessions, meaning the session either does not exist or that it’s not active.SessionNotCreatedExceptionA new session could not be created.UnknownMethodExceptionThe requested command matched a known URL but did not match any methods for that URL.

  1. Stale means the element no longer appears on the DOM of the page.
  2. WebDriverException3个初始化参数,msg/screen/stacktrace,仅仅定义了__str__
  3. UnexpectedAlertPresentException就它定义了自己的__str__,加了alert_text进来

2- webdriver

这是selenium的核心,主要包括11个文件夹

chrome
chromium
common
edge
firefox
ie
remote
safari
support
webkitgtk
wpewebkit

浏览器包

其中

chrome
chromium
edge
firefox
ie
safari
webkitgtk
wpewebkit

这是8个典型的浏览器

每个目录下存在三个主要的文件

options.py
service.py
webdriver.py

其中有点特殊的就是

chromium多了

remote_connection.py

firefox多了

extension_connection.py
firefox_binary.py
firefox_profile.py
remote_connection.py
webdriver_prefs.json

safari多了

permissions.py
remote_connection.py

通用包

主要是3个包,

common

support

remote

这是selenium的核心功能所在

① chrome包

puml源码见附录

  1. service的Service这个类原名是Service,但如果这么写,由于有重名就会关联错误
  2. 下面展示了chrome下3个文件中每个类的继承关系

② common包

File-Dir作用actions动作链的底层bidiW3C WebDriver的下一代协议, 旨在提供由所有浏览器实现稳定的APIdevtools开发者工具,适配不同的浏览器版本v85 v101等等,实现会有细微差异html5后续会移除

__init__.py
action_chains.py

鼠标动作链的所有方法(21个)

alert.py

警告框

by.py

8个定位方法desired_capabilities.py预期能力

keys.py

65个按键log.pyBidi相关的日志处理mutation-listener.js被log.py使用options.py选项类的实现print_page_options.py页面打印选项?proxy.py代理?service.pyService基类timeouts.py超时类utils.py工具类virtual_authenticator.py虚拟身份验证器window.py窗口类型

action_chains

鼠标方法参数说明click★★on_element=None点击click_and_hold★on_element=None点击并按住context_click★on_element=None右键double_click★on_element=None双击drag_and_drop★★source, target拖拽drag_and_drop_by_offset★source, xoffset, yoffset拖拽(依据偏移量)key_down★value, element=None按下某个键key_up★value, element=None抬起某个键move_by_offset★xoffset, yoffset移动(依据偏移量)move_to_element★★to_element移动到元素move_to_element_with_offsetto_element, xoffset, yoffset移动到元素(依据偏移量)pauseseconds暂停perform★★★无参数执行release★on_element=None释放reset_actions无参数重置动作scrollx: int, y: int, delta_x: int, delta_y: int, duration: int = 0, origin: str = “viewport”滚动(废弃)scroll_by_amountdelta_x: int, delta_y: int通过给定的偏差滚动scroll_from_originscroll_origin: ScrollOrigin, delta_x: int, delta_y: int通过给定的原始位置+偏差滚动scroll_to_elementelement滚动到元素send_keys★*keys_to_send发送按键send_keys_to_element★element, *keys_to_send发送按键到元素

alert

这个比较简单

一个类

Alert

包括

  • 一个属性text
  • 三个方法dismiss``````accept``````send_keys

by

一个类

By

8个定位方式
定位方式说明id元素id属性的值xpathxpath表达式link texta标签的文本partial link texta标签的部分文本name元素name属性的值tag name标签名class name元素class属性的值css selectorcss 选择器表达式

keys

NULL ='\ue000'
CANCEL ='\ue001'  
HELP ='\ue002'
BACKSPACE ='\ue003'
BACK_SPACE = BACKSPACE
TAB ='\ue004'
CLEAR ='\ue005'
RETURN ='\ue006'
ENTER ='\ue007'
SHIFT ='\ue008'
LEFT_SHIFT = SHIFT
CONTROL ='\ue009'
LEFT_CONTROL = CONTROL
ALT ='\ue00a'
LEFT_ALT = ALT
PAUSE ='\ue00b'
ESCAPE ='\ue00c'
SPACE ='\ue00d'
PAGE_UP ='\ue00e'
PAGE_DOWN ='\ue00f'
END ='\ue010'
HOME ='\ue011'
LEFT ='\ue012'
ARROW_LEFT = LEFT
UP ='\ue013'
ARROW_UP = UP
RIGHT ='\ue014'
ARROW_RIGHT = RIGHT
DOWN ='\ue015'
ARROW_DOWN = DOWN
INSERT ='\ue016'
DELETE ='\ue017'
SEMICOLON ='\ue018'
EQUALS ='\ue019'
NUMPAD0 ='\ue01a'  
NUMPAD1 ='\ue01b'
NUMPAD2 ='\ue01c'
NUMPAD3 ='\ue01d'
NUMPAD4 ='\ue01e'
NUMPAD5 ='\ue01f'
NUMPAD6 ='\ue020'
NUMPAD7 ='\ue021'
NUMPAD8 ='\ue022'
NUMPAD9 ='\ue023'
MULTIPLY ='\ue024'
ADD ='\ue025'
SEPARATOR ='\ue026'
SUBTRACT ='\ue027'
DECIMAL ='\ue028'
DIVIDE ='\ue029'
F1 ='\ue031'  
F2 ='\ue032'
F3 ='\ue033'
F4 ='\ue034'
F5 ='\ue035'
F6 ='\ue036'
F7 ='\ue037'
F8 ='\ue038'
F9 ='\ue039'
F10 ='\ue03a'
F11 ='\ue03b'
F12 ='\ue03c'
META ='\ue03d'
COMMAND ='\ue03d'
ZENKAKU_HANKAKU ='\ue040'

③ remote包

File作用

__init__.py

空bidi_connection.pybidi连接command.py元命令errorhandler.py错 误处理file_detector.py文件检测findElements.js定位元素的jsgetAttribute.js获取属性的jsisDisplayed.js是否显示的jsmobile.py移动设备相关remote_connection.py远程连接script_key.py一个uuid的处理shadowroot.pyShadow DOM 下的根相关内容switch_to.py切换utils.py工具模块

webdriver.py

webdriver核心技术

webelement.py

webelement核心技术

webdriver

属性方法说明add_cookie添加cookieadd_credentialadd_virtual_authenticator添加虚拟身份验证器application_cacheback浏览器后腿bidi_connectioncapabilitiescapsclose关闭tab页command_executorcreate_optionscreate_web_elementcurrent_url当前的URL地址current_window_handle当前的窗口句柄delete_all_cookies删除所有cookiesdelete_cookie删除某个cookiedelete_network_conditionsdesired_capabilitieserror_handlerexecuteexecute_async_scriptexecute_cdp_cmdexecute_script执行jsfile_detectorfile_detector_contextfind_element单个元素定位find_elements多个元素定位forward前进fullscreen_window全屏get打开网址get_cookie获取某个cookie值get_cookies获取所有cookieget_credentialsget_issue_messageget_logget_network_conditionsget_pinned_scriptsget_screenshot_as_base64get_screenshot_as_fileget_screenshot_as_pngget_sinksget_window_position获取窗口位置(xy值)get_window_rect获取窗口矩形数据(包括position和size)get_window_size获取窗口大小(width和height)implicitly_wait隐式等待launch_applog_typesmaximize_window最大化minimize_window最小化mobilename浏览器名orientationpage_source页面源码pin_scriptpinned_scriptsportprint_pagequit退出浏览器进程refresh刷新remove_all_credentialsremove_credentialremove_virtual_authenticatorsave_screenshot保存页面截图servicesession_idset_network_conditionsset_page_load_timeoutset_permissionsset_script_timeoutset_sink_to_useset_user_verifiedset_window_position设置窗口位置set_window_rect设置窗口矩形set_window_size设置窗口大小start_clientstart_desktop_mirroringstart_sessionstart_tab_mirroringstop_castingstop_clientswitch_to切换timeoutstitle标题unpinvendor_prefixvirtual_authenticator_idwindow_handles窗口句柄组成的列表

WebElement

属性方法说明accessible_namearia_roleclear清空内容click点击元素find_element元素上定位单个子元素find_elements元素上定位多个子元素get_attribute获取html属性get_dom_attributeget_propertyidis_displayed是否显示is_enabled是否使能is_selected是否选中location位置location_once_scrolled_into_view滚动到可见parentrect矩形screenshotscreenshot_as_base64元素截图base64编码screenshot_as_png元素截图保存为pngsend_keys发送按键信息(输入内容)shadow_rootsize元素大小submit提交内容tag_name标签名text标签文本value_of_css_propertycss属性值

④ support包

File作用

__init__.py

空abstract_event_listener.py

color.py

颜色处理event_firing_webdriver.pyevents.py

expected_conditions.py

预期条件

relative_locator.py

相对定位

select.py

select控件ui.py暂未实现

wait.py

等待处理

expected_conditions

方法说明alert_is_present判断alert是否存在,若存在则切换到alert,若不存在则返回Falseall_of传入多个条件,都成立才返回Trueany_of传入多个条件,任意一个成立就返回Trueelement_attribute_to_include判断元素属性是否存在,传入元素定位器和属性名element_located_selection_state_to_be判断某元素是否与预期相同,相同则返回True,不同则返回False,locator为一个(by, path)元组element_located_to_be_selected判断某元素是否被选,locator为一个(by, path)元组element_selection_state_to_be判断某元素的选中状态是否与预期相同,相同则返回True,不同则返回Falseelement_to_be_clickable判断某元素是否可访问并且可启用,比如能够点击,若可以则返回元素本身,否则返回Falseelement_to_be_selected判断某元素是否被选中frame_to_be_available_and_switch_to_it判断某个frame是否可以切换过去,若可以则切换到该frame,否则返回Falseinvisibility_of_element判断元素是否隐藏[吴],继承自invisibility_of_element_located,入参可以是一个locator也可以是webelementinvisibility_of_element_locate判断元素是否隐藏,入参是locatornew_window_is_opened新窗口是否打开,入参是当前的句柄列表none_of传入多个条件,都不成立才返回Truenumber_of_windows_to_be判断window数量是否为N,入参N是数字presence_of_all_elements_located用于判断定位的元素范围内,至少有一个元素存在于页面当中,存在则以list形式返回元素本身,不存在则报错presence_of_element_located用于判断一个元素存在于页面DOM树中,存在则返回元素本身,不存在则报错staleness_of判断某个元素是否不再附加于于DOM树中,不再附加的话返回True,依旧存在返回False。可以用于判断页面是否刷新了text_to_be_present_in_element判断某文本是否是存在于特定元素的value值中,存在则返回True,不存在则返回False,对于查看没有value值的元素,也会返回Falsetext_to_be_present_in_element_value文本在指定元素的value属性值中,入参是locator和文本text_to_be_present_in_element_attribute文本出现在元素的属性中,传入元素定位器、属性和文本title_contains用于判断网页title是否包含特定文本(英文区分大小写),若包含则返回True,不包含返回False。title_is用于判断网页title是否是特定文本(英文区分大小写),若完全相同则返回True,否则返回Falseurl_changesurl是否改变,入参是urlurl_containsurl是否包含,入参是url,入参in当前的urlurl_matchesurl是否匹配指定模式,传入一个正则表达式模式url_to_beurl应该是,入参和当前的url比较visibility_ofvisibility_of(element)同面visibility_of_element_located(locator),不过参数从locator的元组变为元素visibility_of_all_elements_located所有元素都可见,传入一个locator定位一组元素visibility_of_any_elements_located只要有一个元素可见,传入一个locator定位一组元素visibility_of_element_located用于判断特定元素是否存在于DOM树中并且可见,可见意为元素的高和宽都大于0,元素存在返回元素本身,否则返回False

relative_locator

2个函数

with_tag_name

locate_with

一个类

RelativeBy

主要是5个方法

above

below

to_left_of

to_right_of

near

select

定义了一个

Select

3个属性options、all_selected_options、first_selected_option

七个方法

select_by_value
select_by_index
select_by_visible_text
deselect_all

deselect_by_value
deselect_by_index
deselect_by_visible_text

wait

显式等待的核心逻辑

一个类

WebDriverWait

2个方法

until

until_not

其中

until

是核心

原始定义如下

defuntil(self, method, message:str=""):"""Calls the method provided with the driver as an argument until the \
        return value does not evaluate to ``False``.

        :param method: callable(WebDriver)
        :param message: optional message for :exc:`TimeoutException`
        :returns: the result of the last call to `method`
        :raises: :exc:`selenium.common.exceptions.TimeoutException` if timeout occurs
        """
        screen =None
        stacktrace =None

        end_time = time.monotonic()+ self._timeout
        from time import ctime
        whileTrue:try:
                value = method(self._driver)if value:return value
            except self._ignored_exceptions as exc:
                screen =getattr(exc,'screen',None)
                stacktrace =getattr(exc,'stacktrace',None)
            time.sleep(self._poll)if time.monotonic()> end_time:breakraise TimeoutException(message, screen, stacktrace)

核心是

        end_time = time.monotonic()+ self._timeout
        from time import ctime
        whileTrue:try:
                value = method(self._driver)if value:return value
            time.sleep(self._poll)if time.monotonic()> end_time:breakraise TimeoutException(message, screen, stacktrace)

这么解释

  1. 用传过来的method,call它,传入self._driver
  2. 得到一个value,如果有value就直接return
  3. 如果没有得到就time.sleep(轮询间隔)
  4. 加个判断如果当前时间超过了你的预设时间end_time(就是程序开始的时间+最大等待时间self._time_out),那就退出循环,抛出TimeoutException异常

3- 实例浅析

下面的代码

from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('http://121.5.150.55:8090/')
driver.find_element('id','ls_username').send_keys('admin')
driver.find_element('id','ls_password').send_keys('123456')
driver.find_element('css selector','.pn.vm').click()

① 导包

from selenium import webdriver

你执行了

webdriver/__init__.py

这里做了很多命名,如,你才可以用上面代码的第二行

from.chrome.webdriver import WebDriver as Chrome

② 实例化某个浏览器

driver = webdriver.Chrome()

做完这个,正常情况你会打开一个浏览器

这是相对比较复杂的一个过程

其继承关系如下

  1. 其中RemoteWebDriver是别名,实际是WebDriver,不过是remote下的,跟第一个不同
  2. BaseWebDriver是个抽象基类
  3. RemoteWebDriver中会执行self.start_session(capabilities, browser_profile)
  4. start_session源码如下,作用就是用提供的预期能力值启动会话
defstart_session(self, capabilities:dict, browser_profile=None)->None:"""
       Creates a new session with the desired capabilities.

       :Args:
        - capabilities - a capabilities dict to start the session with.
        - browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object. Only used if Firefox is requested.
       """ifnotisinstance(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}
       response = self.execute(Command.NEW_SESSION, parameters)if'sessionId'notin response:
           response = response['value']
       self.session_id = response['sessionId']
       self.caps = response.get('value')# if capabilities is none we are probably speaking to# a W3C endpointifnot self.caps:
           self.caps = response.get('capabilities')
  1. 就是这句
response = self.execute(Command.NEW_SESSION, parameters)

③ driver操作

driver.maximize_window()
driver.get('http://121.5.150.55:8090/')
driver.find_element('id','ls_username').send_keys('admin')
driver.find_element('id','ls_password').send_keys('123456')
driver.find_element('css selector','.pn.vm').click()

上面所有的driver的操作本质都是类似的
操作源码driver.maximize_window()driver.execute(Command.W3C_MAXIMIZE_WINDOW,None)driver.get(url)driver.execute(Command.GET, {‘url’: url})driver.find_element(‘id’,‘ls_username’)driver.execute(Command.FIND_ELEMENT, { ‘using’: ‘id’, ‘value’: ‘ls_username’})[‘value’]

  1. 其中Command类定义了JsonWireProtocol,比如Command.W3C_MAXIMIZE_WINDOW='w3cMaximizeWindow'
  2. execute这个方法接收2个参数driver_commandparams,核心是response = self.command_executor.execute(driver_command, params)
  3. 其中command_executor你可以理解为是chromedriver这个驱动(REST API SERVER),虽然默认值是'http://127.0.0.1:4444' Grid的地址。它的本质会去调度self._request(command_info[0], url, body=data)这里跟requests库的调用就即可相似了,虽然底层的差异还是蛮多的
  4. 举个例子,调试第二行实例化得到的method/url/body分别是
POST 
http://localhost:11721/session 
{"capabilities":{"firstMatch":[{}], "alwaysMatch":{"browserName":"chrome", "pageLoadStrategy":"normal", "goog:chromeOptions":{"extensions":[], "args":[]}}}}

第三行最大化

POST http://localhost:11721/session/3e0775932ad7ee1828609d5e38bb6984/window/maximize {}

第四行

POST http://localhost:11721/session/3e0775932ad7ee1828609d5e38bb6984/url {"url":"http://121.5.150.55:8090/"}

附录

代码结构

+-- common (25.62KB)|+-- exceptions.py (9.01KB)|+-- __init__.py (3.68KB)+-- py.typed (0b)+-- selenium.txt (88.12KB)+-- types.py (932b)+-- webdriver (7.54MB)|+-- chrome (12.5KB)||+-- options.py (1.4KB)||+-- service.py (1.71KB)||+-- webdriver.py (3.57KB)||+-- __init__.py (787b)|+-- chromium (38.02KB)||+-- options.py (6.08KB)||+-- remote_connection.py (2.53KB)||+-- service.py (1.93KB)||+-- webdriver.py (9.17KB)||+-- __init__.py (787b)|+-- common (6.85MB)||+-- actions (44.26KB)|||+-- action_builder.py (3.41KB)|||+-- input_device.py (1.24KB)|||+-- interaction.py (1.4KB)|||+-- key_actions.py (1.67KB)|||+-- key_input.py (1.76KB)|||+-- mouse_button.py (88b)|||+-- pointer_actions.py (5.38KB)|||+-- pointer_input.py (2.88KB)|||+-- wheel_actions.py (1.29KB)|||+-- wheel_input.py (2.55KB)|||+-- __init__.py (787b)||+-- action_chains.py (13.03KB)||+-- alert.py (2.52KB)||+-- bidi (36.56KB)|||+-- cdp.py (17.89KB)|||+-- console.py (886b)|||+-- __init__.py (787b)||+-- by.py (1.08KB)||+-- desired_capabilities.py (2.86KB)||+-- devtools (6.62MB)|||+-- v101 (1.73MB)||||+-- accessibility.py (21.4KB)||||+-- animation.py (10.85KB)||||+-- audits.py (43.67KB)||||+-- background_service.py (5.62KB)||||+-- browser.py (20.2KB)||||+-- cache_storage.py (7.63KB)||||+-- cast.py (4.28KB)||||+-- console.py (2.7KB)||||+-- css.py (54.31KB)||||+-- database.py (3.83KB)||||+-- debugger.py (42.92KB)||||+-- device_orientation.py (1.18KB)||||+-- dom.py (57.98KB)||||+-- dom_debugger.py (9.24KB)||||+-- dom_snapshot.py (35.48KB)||||+-- dom_storage.py (4.91KB)||||+-- emulation.py (24.4KB)||||+-- event_breakpoints.py (1.26KB)||||+-- fetch.py (18.17KB)||||+-- headless_experimental.py (4.68KB)||||+-- heap_profiler.py (11.47KB)||||+-- indexed_db.py (12.46KB)||||+-- input_.py (27.19KB)||||+-- inspector.py (1.68KB)||||+-- io.py (2.96KB)||||+-- layer_tree.py (14.7KB)||||+-- log.py (5.14KB)||||+-- media.py (6.45KB)||||+-- memory.py (6.65KB)||||+-- network.py (120.84KB)||||+-- overlay.py (49.08KB)||||+-- page.py (99.17KB)||||+-- performance.py (2.86KB)||||+-- performance_timeline.py (6.47KB)||||+-- profiler.py (15.4KB)||||+-- py.typed (0b)||||+-- runtime.py (54.73KB)||||+-- schema.py (1.08KB)||||+-- security.py (16.47KB)||||+-- service_worker.py (10.81KB)||||+-- storage.py (15.95KB)||||+-- system_info.py (10.79KB)||||+-- target.py (20.42KB)||||+-- tethering.py (1.5KB)||||+-- tracing.py (12.17KB)||||+-- util.py (455b)||||+-- web_audio.py (16.5KB)||||+-- web_authn.py (12.06KB)||||+-- __init__.py (1.26KB)|||+-- v102 (1.74MB)||||+-- accessibility.py (21.4KB)||||+-- animation.py (10.85KB)||||+-- audits.py (44.04KB)||||+-- background_service.py (5.62KB)||||+-- browser.py (20.2KB)||||+-- cache_storage.py (7.63KB)||||+-- cast.py (4.28KB)||||+-- console.py (2.7KB)||||+-- css.py (54.31KB)||||+-- database.py (3.83KB)||||+-- debugger.py (42.92KB)||||+-- device_orientation.py (1.18KB)||||+-- dom.py (57.98KB)||||+-- dom_debugger.py (9.24KB)||||+-- dom_snapshot.py (35.48KB)||||+-- dom_storage.py (4.91KB)||||+-- emulation.py (24.4KB)||||+-- event_breakpoints.py (1.26KB)||||+-- fetch.py (18.17KB)||||+-- headless_experimental.py (4.68KB)||||+-- heap_profiler.py (11.47KB)||||+-- indexed_db.py (12.46KB)||||+-- input_.py (27.19KB)||||+-- inspector.py (1.68KB)||||+-- io.py (2.96KB)||||+-- layer_tree.py (14.7KB)||||+-- log.py (5.14KB)||||+-- media.py (7.45KB)||||+-- memory.py (6.65KB)||||+-- network.py (120.84KB)||||+-- overlay.py (49.08KB)||||+-- page.py (99.71KB)||||+-- performance.py (2.86KB)||||+-- performance_timeline.py (6.47KB)||||+-- profiler.py (15.4KB)||||+-- py.typed (0b)||||+-- runtime.py (56.5KB)||||+-- schema.py (1.08KB)||||+-- security.py (16.47KB)||||+-- service_worker.py (10.81KB)||||+-- storage.py (15.95KB)||||+-- system_info.py (10.79KB)||||+-- target.py (20.42KB)||||+-- tethering.py (1.5KB)||||+-- tracing.py (12.17KB)||||+-- util.py (455b)||||+-- web_audio.py (16.5KB)||||+-- web_authn.py (12.06KB)||||+-- __init__.py (1.26KB)|||+-- v103 (1.76MB)||||+-- accessibility.py (21.4KB)||||+-- animation.py (10.85KB)||||+-- audits.py (46.55KB)||||+-- background_service.py (5.62KB)||||+-- browser.py (20.2KB)||||+-- cache_storage.py (7.63KB)||||+-- cast.py (4.28KB)||||+-- console.py (2.7KB)||||+-- css.py (54.31KB)||||+-- database.py (3.83KB)||||+-- debugger.py (43.44KB)||||+-- device_orientation.py (1.18KB)||||+-- dom.py (57.98KB)||||+-- dom_debugger.py (9.24KB)||||+-- dom_snapshot.py (35.48KB)||||+-- dom_storage.py (6.11KB)||||+-- emulation.py (24.76KB)||||+-- event_breakpoints.py (1.26KB)||||+-- fetch.py (18.17KB)||||+-- headless_experimental.py (4.7KB)||||+-- heap_profiler.py (12.05KB)||||+-- indexed_db.py (12.46KB)||||+-- input_.py (27.19KB)||||+-- inspector.py (1.68KB)||||+-- io.py (2.96KB)||||+-- layer_tree.py (14.7KB)||||+-- log.py (5.14KB)||||+-- media.py (7.45KB)||||+-- memory.py (6.65KB)||||+-- network.py (120.84KB)||||+-- overlay.py (49.08KB)||||+-- page.py (101.57KB)||||+-- performance.py (2.86KB)||||+-- performance_timeline.py (6.47KB)||||+-- profiler.py (15.4KB)||||+-- py.typed (0b)||||+-- runtime.py (56.63KB)||||+-- schema.py (1.08KB)||||+-- security.py (16.47KB)||||+-- service_worker.py (10.81KB)||||+-- storage.py (16.22KB)||||+-- system_info.py (10.79KB)||||+-- target.py (20.42KB)||||+-- tethering.py (1.5KB)||||+-- tracing.py (12.17KB)||||+-- util.py (455b)||||+-- web_audio.py (16.5KB)||||+-- web_authn.py (12.54KB)||||+-- __init__.py (1.26KB)|||   `-- v85 (1.39MB)|||+-- accessibility.py (14.66KB)|||+-- animation.py (10.85KB)|||+-- application_cache.py (5.6KB)|||+-- audits.py (16.67KB)|||+-- background_service.py (5.62KB)|||+-- browser.py (16.89KB)|||+-- cache_storage.py (7.63KB)|||+-- cast.py (3.89KB)|||+-- console.py (2.7KB)|||+-- css.py (41.9KB)|||+-- database.py (3.83KB)|||+-- debugger.py (42.45KB)|||+-- device_orientation.py (1.18KB)|||+-- dom.py (53.12KB)|||+-- dom_debugger.py (8.39KB)|||+-- dom_snapshot.py (33.27KB)|||+-- dom_storage.py (4.91KB)|||+-- emulation.py (20.29KB)|||+-- fetch.py (15.68KB)|||+-- headless_experimental.py (4.68KB)|||+-- heap_profiler.py (10.94KB)|||+-- indexed_db.py (12.46KB)|||+-- input_.py (19.24KB)|||+-- inspector.py (1.68KB)|||+-- io.py (2.96KB)|||+-- layer_tree.py (14.7KB)|||+-- log.py (4.94KB)|||+-- media.py (6.45KB)|||+-- memory.py (6.65KB)|||+-- network.py (84.85KB)|||+-- overlay.py (24.24KB)|||+-- page.py (69.14KB)|||+-- performance.py (2.86KB)|||+-- profiler.py (16.77KB)|||+-- py.typed (0b)|||+-- runtime.py (50.48KB)|||+-- schema.py (1.08KB)|||+-- security.py (16.52KB)|||+-- service_worker.py (10.81KB)|||+-- storage.py (8.08KB)|||+-- system_info.py (10.79KB)|||+-- target.py (18.08KB)|||+-- tethering.py (1.5KB)|||+-- tracing.py (10.31KB)|||+-- util.py (455b)|||+-- web_audio.py (16.5KB)|||+-- web_authn.py (9.2KB)|||+-- __init__.py (1.23KB)||+-- html5 (3.82KB)|||+-- application_cache.py (1.59KB)|||+-- __init__.py (787b)||+-- keys.py (2.29KB)||+-- log.py (5.92KB)||+-- mutation-listener.js (1.9KB)||+-- options.py (8.79KB)||+-- print_page_options.py (8.3KB)||+-- proxy.py (10.52KB)||+-- service.py (5.66KB)||+-- timeouts.py (3.74KB)||+-- utils.py (4.37KB)||+-- virtual_authenticator.py (8.65KB)||+-- window.py (929b)||+-- __init__.py (787b)|+-- edge (13.8KB)||+-- options.py (1.66KB)||+-- service.py (2.21KB)||+-- webdriver.py (3.23KB)||+-- __init__.py (787b)|+-- firefox (90.62KB)||+-- extension_connection.py (2.77KB)||+-- firefox_binary.py (8.58KB)||+-- firefox_profile.py (14.14KB)||+-- options.py (5.25KB)||+-- remote_connection.py (1.68KB)||+-- service.py (2.62KB)||+-- webdriver.py (13.15KB)||+-- webdriver_prefs.json (2.76KB)||+-- __init__.py (787b)|+-- ie (36.68KB)||+-- options.py (11.26KB)||+-- service.py (2.28KB)||+-- webdriver.py (5.38KB)||+-- __init__.py (787b)|+-- remote (341.63KB)||+-- bidi_connection.py (968b)||+-- command.py (4.89KB)||+-- errorhandler.py (11.7KB)||+-- file_detector.py (1.77KB)||+-- findElements.js (52.56KB)||+-- getAttribute.js (42.15KB)||+-- isDisplayed.js (42.96KB)||+-- mobile.py (2.61KB)||+-- remote_connection.py (17.59KB)||+-- script_key.py (1009b)||+-- shadowroot.py (2.94KB)||+-- switch_to.py (4.96KB)||+-- utils.py (978b)||+-- webdriver.py (42.39KB)||+-- webelement.py (16.79KB)||+-- __init__.py (787b)|+-- safari (27.63KB)||+-- options.py (4.14KB)||+-- permissions.py (934b)||+-- remote_connection.py (1.47KB)||+-- service.py (2.44KB)||+-- webdriver.py (6.12KB)||+-- __init__.py (787b)|+-- support (115.69KB)||+-- abstract_event_listener.py (1.98KB)||+-- color.py (12.01KB)||+-- events.py (92b)||+-- event_firing_webdriver.py (8.79KB)||+-- expected_conditions.py (15.25KB)||+-- relative_locator.py (5.89KB)||+-- select.py (9.04KB)||+-- ui.py (863b)||+-- wait.py (5.02KB)||+-- __init__.py (787b)|+-- webkitgtk (13.78KB)||+-- options.py (2.61KB)||+-- service.py (1.59KB)||+-- webdriver.py (2.9KB)||+-- __init__.py (787b)|+-- wpewebkit (12.68KB)||+-- options.py (2.16KB)||+-- service.py (1.59KB)||+-- webdriver.py (2.69KB)||+-- __init__.py (787b)|+-- __init__.py (2.37KB)+-- __init__.py (811b)

puml

@startuml

package chrome <<folder>> {
    package options.py <<Frame>> {
        class Options
        {
        +default_capabilities
        +enable_mobile()
        }
    }
    package service.py <<Frame>> {
        class Service
        {
        +__init__()
        }
    }
    package webdriver.py <<Frame>> {
        class WebDriver
        {
        +__init__()
        }
    }
    }

package chromium <<folder>> {
    package options.py <<Frame>> {
        class ChromiumOptions
        {
        +__init__()
        +binary_location
        +debugger_address
        +extensions
        +add_extension()
        +add_encoded_extension()
        +experimental_options
        +add_experimental_option()
        +headless
        +to_capabilities()
        +default_capabilities
        }
    }
    package remote_connection.py <<Frame>> {
        class ChromiumRemoteConnection
        {
        +__init__()
        }
    }
    package service.py <<Frame>> {
        class ChromiumService
        {
        +__init__()
        +command_line_args()
        }
    }
    package webdriver.py <<Frame>> {
        class ChromiumDriver
        {
        +__init__()
        +launch_app()
        +get_network_conditions()
        +set_network_conditions()
        +delete_network_conditions()
        +set_permissions()
        +execute_cdp_cmd()
        +get_sinks()
        +get_issue_message()
        +set_sink_to_use()
        +start_desktop_mirroring()
        +start_tab_mirroring()
        +stop_casting()
        +quit()
        +create_options()
        }
    }
    }

package common <<folder>> {
    package options.py <<Frame>> {
        class BaseOptions {}
        class ArgOptions {
        +__init__()
        +arguments
        +add_argument()
        +ignore_local_proxy_environment_variables()
        +to_capabilities()
        +default_capabilities
        }

    }
    package service.py <<Frame>> {
        class service的Service
        {
        +__init__()
        +service_url
        +command_line_args()
        +start()
        +assert_process_still_running()
        +is_connectable()
        +send_remote_shutdown_command()
        +stop()
        +__del__()
        }
    }
}

package remote <<folder>> {
    package webdriver.py <<Frame>> {
        class RemoteWebDriver
        {
        +get_timeout()
        +reset_timeout()
        +get_certificate_bundle_path()
        +set_certificate_bundle_path()
        +get_remote_connection_headers()
        +_get_proxy_url()
        +_identify_http_proxy_auth()
        +_seperate_http_proxy_auth()
        +_get_connection_manager()
        +__init__()
        +execute()
        +_request()
        +close()
        }
        class BaseWebDriver{}

    }
    package remote_connection.py <<Frame>> {
        class RemoteConnection
    }
    }

Options --> ChromiumOptions: 继承
Service --> ChromiumService: 继承
WebDriver --> ChromiumDriver: 继承
ChromiumRemoteConnection --> RemoteConnection:继承

ChromiumOptions -->ArgOptions: 继承
ArgOptions --> BaseOptions: 继承
ChromiumService --> service的Service: 继承

ChromiumDriver --> RemoteWebDriver: 继承
RemoteWebDriver --> BaseWebDriver: 继承

@enduml

本文转载自: https://blog.csdn.net/Mantou023/article/details/134817655
版权归原作者 wuxianfeng023 所有, 如有侵权,请联系我们删除。

“selenium库浅析,基于4.3”的评论:

还没有评论