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.
注
Stale
means the element no longer appears on the DOM of the page.WebDriverException
3个初始化参数,msg/screen/stacktrace,仅仅定义了__str__
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源码见附录
注
service的Service
这个类原名是Service
,但如果这么写,由于有重名就会关联错误- 下面展示了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)
这么解释
- 用传过来的
method
,call它,传入self._driver
- 得到一个
value
,如果有value就直接return - 如果没有得到就
time.sleep(轮询间隔)
- 加个判断如果当前时间超过了你的预设时间
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()
做完这个,正常情况你会打开一个浏览器
这是相对比较复杂的一个过程
其继承关系如下
注
- 其中
RemoteWebDriver
是别名,实际是WebDriver
,不过是remote
下的,跟第一个不同 BaseWebDriver
是个抽象基类RemoteWebDriver
中会执行self.start_session(capabilities, browser_profile)
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')
- 就是这句
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’]
- 其中
Command
类定义了JsonWireProtocol
,比如Command.W3C_MAXIMIZE_WINDOW='w3cMaximizeWindow'
- 而
execute
这个方法接收2个参数driver_command
和params
,核心是response = self.command_executor.execute(driver_command, params)
- 其中
command_executor
你可以理解为是chromedriver
这个驱动(REST API SERVER),虽然默认值是'http://127.0.0.1:4444'
Grid的地址。它的本质会去调度self._request(command_info[0], url, body=data)
这里跟requests
库的调用就即可相似了,虽然底层的差异还是蛮多的 - 举个例子,调试第二行
实例化
得到的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
版权归原作者 wuxianfeng023 所有, 如有侵权,请联系我们删除。