selenium库浅析,基于4.3

selenium库浅析

基于4.3

pip install selenium安装好后,在sitepackages下

2个主要的目录,commonwebdriver

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 order
ElementNotSelectableExceptionThrown 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 WebElement
ImeNotAvailableExceptionThrown 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个包,commonsupportremote

这是selenium的核心功能所在

① chrome包

puml源码见附录

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

② common包

File-Dir作用
actions动作链的底层
bidiW3C WebDriver的下一代协议, 旨在提供由所有浏览器实现稳定的API
devtools开发者工具,适配不同的浏览器版本v85 v101等等,实现会有细微差异
html5后续会移除
__init__.py
action_chains.py鼠标动作链的所有方法(21个)
alert.py警告框
by.py8个定位方法
desired_capabilities.py预期能力
keys.py65个按键
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定位元素的js
getAttribute.js获取属性的js
isDisplayed.js是否显示的js
mobile.py移动设备相关
remote_connection.py远程连接
script_key.py一个uuid的处理
shadowroot.pyShadow DOM 下的根相关内容
switch_to.py切换
utils.py工具模块
webdriver.pywebdriver核心技术
webelement.pywebelement核心技术

webdriver

属性方法说明
add_cookie添加cookie
add_credential
add_virtual_authenticator添加虚拟身份验证器
application_cache
back浏览器后腿
bidi_connection
capabilities
caps
close关闭tab页
command_executor
create_options
create_web_element
current_url当前的URL地址
current_window_handle当前的窗口句柄
delete_all_cookies删除所有cookies
delete_cookie删除某个cookie
delete_network_conditions
desired_capabilities
error_handler
execute
execute_async_script
execute_cdp_cmd
execute_script执行js
file_detector
file_detector_context
find_element单个元素定位
find_elements多个元素定位
forward前进
fullscreen_window全屏
get打开网址
get_cookie获取某个cookie值
get_cookies获取所有cookie
get_credentials
get_issue_message
get_log
get_network_conditions
get_pinned_scripts
get_screenshot_as_base64
get_screenshot_as_file
get_screenshot_as_png
get_sinks
get_window_position获取窗口位置(xy值)
get_window_rect获取窗口矩形数据(包括position和size)
get_window_size获取窗口大小(width和height)
implicitly_wait隐式等待
launch_app
log_types
maximize_window最大化
minimize_window最小化
mobile
name浏览器名
orientation
page_source页面源码
pin_script
pinned_scripts
port
print_page
quit退出浏览器进程
refresh刷新
remove_all_credentials
remove_credential
remove_virtual_authenticator
save_screenshot保存页面截图
service
session_id
set_network_conditions
set_page_load_timeout
set_permissions
set_script_timeout
set_sink_to_use
set_user_verified
set_window_position设置窗口位置
set_window_rect设置窗口矩形
set_window_size设置窗口大小
start_client
start_desktop_mirroring
start_session
start_tab_mirroring
stop_casting
stop_client
switch_to切换
timeouts
title标题
unpin
vendor_prefix
virtual_authenticator_id
window_handles窗口句柄组成的列表

WebElement

属性方法说明
accessible_name
aria_role
clear清空内容
click点击元素
find_element元素上定位单个子元素
find_elements元素上定位多个子元素
get_attribute获取html属性
get_dom_attribute
get_property
id
is_displayed是否显示
is_enabled是否使能
is_selected是否选中
location位置
location_once_scrolled_into_view滚动到可见
parent
rect矩形
screenshot
screenshot_as_base64元素截图base64编码
screenshot_as_png元素截图保存为png
send_keys发送按键信息(输入内容)
shadow_root
size元素大小
submit提交内容
tag_name标签名
text标签文本
value_of_css_propertycss属性值

④ support包

File作用
__init__.py
abstract_event_listener.py
color.py颜色处理
event_firing_webdriver.py
events.py
expected_conditions.py预期条件
relative_locator.py相对定位
select.pyselect控件
ui.py暂未实现
wait.py等待处理

expected_conditions

方法说明
alert_is_present判断alert是否存在,若存在则切换到alert,若不存在则返回False
all_of传入多个条件,都成立才返回True
any_of传入多个条件,任意一个成立就返回True
element_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,不同则返回False
element_to_be_clickable判断某元素是否可访问并且可启用,比如能够点击,若可以则返回元素本身,否则返回False
element_to_be_selected判断某元素是否被选中
frame_to_be_available_and_switch_to_it判断某个frame是否可以切换过去,若可以则切换到该frame,否则返回False
invisibility_of_element判断元素是否隐藏[吴],继承自invisibility_of_element_located,入参可以是一个locator也可以是webelement
invisibility_of_element_locate判断元素是否隐藏,入参是locator
new_window_is_opened新窗口是否打开,入参是当前的句柄列表
none_of传入多个条件,都不成立才返回True
number_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值的元素,也会返回False
text_to_be_present_in_element_value文本在指定元素的value属性值中,入参是locator和文本
text_to_be_present_in_element_attribute文本出现在元素的属性中,传入元素定位器、属性和文本
title_contains用于判断网页title是否包含特定文本(英文区分大小写),若包含则返回True,不包含返回False。
title_is用于判断网页title是否是特定文本(英文区分大小写),若完全相同则返回True,否则返回False
url_changesurl是否改变,入参是url
url_containsurl是否包含,入参是url,入参in当前的url
url_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_namelocate_with

一个类RelativeBy

主要是5个方法abovebelowto_left_ofto_right_ofnear

select

定义了一个Select

3个属性options、all_selected_options、first_selected_option

七个方法select_by_value select_by_index select_by_visible_text deselect_alldeselect_by_value deselect_by_index deselect_by_visible_text

wait

显式等待的核心逻辑

一个类WebDriverWait

2个方法untiluntil_not

其中until是核心

原始定义如下

    def until(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
        while True:
            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:

                break
        raise TimeoutException(message, screen, stacktrace)

核心是

        end_time = time.monotonic() + self._timeout
        from time import ctime
        while True:
            try:
                value = method(self._driver)
                if value:
                    return value
            time.sleep(self._poll)
            if time.monotonic() > end_time:
                break
        raise 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源码如下,作用就是用提供的预期能力值启动会话

   def start_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.
       """
       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}
       response = self.execute(Command.NEW_SESSION, parameters)
       if 'sessionId' not in 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 endpoint
       if not 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
  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wuxianfeng023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值