selenium库浅析

基于4.3

pip install selenium安装好后,在sitepackages下

2个主要的目录,commonwebdriver

1- common

该目录一共就一个模块exceptions.py

① exceptions.py

其中定义了32个异常,竟然有个同学面试的时候被问过

异常 说明
WebDriverException 主异常,下面的都继承于它
InvalidSwitchToTargetException Thrown when frame or window target to be switched doesn't exist.
NoSuchFrameException Thrown when frame target to be switched doesn't exist.
NoSuchWindowException Thrown when window target to be switched doesn't exist.
NoSuchElementException Thrown when element could not be found.
NoSuchAttributeException Thrown when the attribute of element could not be found.
NoSuchShadowRootException Thrown when trying to access the shadow root of an element when it does not have a shadow root attached.
StaleElementReferenceException Thrown when a reference to an element is now "stale".
InvalidElementStateException Thrown when a command could not be completed because the element is in an invalid state.
UnexpectedAlertPresentException Thrown when an unexpected alert has appeared.
NoAlertPresentException Thrown when switching to no presented alert.
ElementNotVisibleException Thrown when an element is present on the DOM, but it is not visible, and so is not able to be interacted with.
ElementNotInteractableException Thrown when an element is present in the DOM but interactions with that element will hit another element due to paint order
ElementNotSelectableException Thrown when trying to select an unselectable element.
InvalidCookieDomainException Thrown when attempting to add a cookie under a different domain than the current URL.
UnableToSetCookieException Thrown when a driver fails to set a cookie.
RemoteDriverServerException 源码没有给__doc__
TimeoutException Thrown when a command does not complete in enough time.
MoveTargetOutOfBoundsException Thrown when the target provided to the ActionsChains move() method is invalid, i.e. out of document.
UnexpectedTagNameException Thrown when a support class did not get an expected web element.
InvalidSelectorException Thrown when the selector which is used to find an element does not return a WebElement
ImeNotAvailableException Thrown when IME support is not available.
ImeActivationFailedException Thrown when activating an IME engine has failed.
InvalidArgumentException The arguments passed to a command are either invalid or malformed.
JavascriptException An error occurred while executing JavaScript supplied by the user.
NoSuchCookieException No cookie matching the given path name was found amongst the associated cookies of the current browsing context's active document.
ScreenshotException A screen capture was made impossible.
ElementClickInterceptedException The Element Click command could not be completed because the element receiving the events is obscuring the element that was requested to be clicked.
InsecureCertificateException Navigation caused the user agent to hit a certificate warning, which is usually the result of an expired or invalid TLS certificate.
InvalidCoordinatesException The coordinates provided to an interaction's operation are invalid.
InvalidSessionIdException Occurs 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.
SessionNotCreatedException A new session could not be created.
UnknownMethodException The 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 动作链的底层
bidi W3C WebDriver的下一代协议, 旨在提供由所有浏览器实现稳定的API
devtools 开发者工具,适配不同的浏览器版本v85 v101等等,实现会有细微差异
html5 后续会移除
__init__.py
action_chains.py 鼠标动作链的所有方法(21个)
alert.py 警告框
by.py 8个定位方法
desired_capabilities.py 预期能力
keys.py 65个按键
log.py Bidi相关的日志处理
mutation-listener.js 被log.py使用
options.py 选项类的实现
print_page_options.py 页面打印选项?
proxy.py 代理?
service.py Service基类
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_offset to_element, xoffset, yoffset 移动到元素(依据偏移量)
pause seconds 暂停
perform★★★ 无参数 执行
release★ on_element=None 释放
reset_actions 无参数 重置动作
scroll x: int, y: int, delta_x: int, delta_y: int, duration: int = 0, origin: str = "viewport" 滚动(废弃)
scroll_by_amount delta_x: int, delta_y: int 通过给定的偏差滚动
scroll_from_origin scroll_origin: ScrollOrigin, delta_x: int, delta_y: int 通过给定的原始位置+偏差滚动
scroll_to_element element 滚动到元素
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属性的值
xpath xpath表达式
link text a标签的文本
partial link text a标签的部分文本
name 元素name属性的值
tag name 标签名
class name 元素class属性的值
css selector css 选择器表达式

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.py bidi连接
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.py Shadow DOM 下的根相关内容
switch_to.py 切换
utils.py 工具模块
webdriver.py webdriver核心技术
webelement.py webelement核心技术

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_property css属性值

④ support包

File 作用
__init__.py
abstract_event_listener.py
color.py 颜色处理
event_firing_webdriver.py
events.py
expected_conditions.py 预期条件
relative_locator.py 相对定位
select.py select控件
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_changes url是否改变,入参是url
url_contains url是否包含,入参是url,入参in当前的url
url_matches url是否匹配指定模式,传入一个正则表达式模式
url_to_be url应该是,入参和当前的url比较
visibility_of visibility_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

selenium库浅析的更多相关文章

  1. 为采集动态网页安装和测试Python Selenium库

    1. 引言上一篇<为编写网络爬虫程序安装Python3.5>中测试小例子对静态网页做了一个简单的采集程序,而动态网页因为需要动态加载js获取数据,所以使用urllib直接openurl已经 ...

  2. python利用selenium库识别点触验证码

    利用selenium库和超级鹰识别点触验证码(学习于静谧大大的书,想自己整理一下思路) 一.超级鹰注册:超级鹰入口 1.首先注册一个超级鹰账号,然后在超级鹰免费测试地方可以关注公众号,领取1000积分 ...

  3. python爬虫---selenium库的用法

    python爬虫---selenium库的用法 selenium是一个自动化测试工具,支持Firefox,Chrome等众多浏览器 在爬虫中的应用主要是用来解决JS渲染的问题. 1.使用前需要安装这个 ...

  4. python爬虫笔记----4.Selenium库(自动化库)

    4.Selenium库 (自动化测试工具,支持多种浏览器,爬虫主要解决js渲染的问题) pip install selenium 基本使用 from selenium import webdriver ...

  5. Python3 使用selenium库登陆知乎并保存cookie为本地文件

    Python3 使用selenium库登陆知乎并保存cookie为本地文件 学习使用selenium库模拟登陆知乎,并将cookie保存为本地文件,然后供以后(requests模块)使用,用selen ...

  6. Python爬虫-- selenium库

    selenium库 selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并行处理(S ...

  7. PYTHON 爬虫笔记七:Selenium库基础用法

    知识点一:Selenium库详解及其基本使用 什么是Selenium selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium ...

  8. python爬虫---从零开始(六)Selenium库

    什么是Selenium库: 自动化测试工具,支持多种浏览器.支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera ...

  9. Python:利用 selenium 库抓取动态网页示例

    前言 在抓取常规的静态网页时,我们直接请求对应的 url 就可以获取到完整的 HTML 页面,但是对于动态页面,网页显示的内容往往是通过 ajax 动态去生成的,所以如果是用 urllib.reque ...

  10. 浅谈python中selenium库调动webdriver驱动浏览器的实现原理

    最近学web自动化时用到selenium库,感觉很神奇,遂琢磨了一下,写了点心得. 当我们输入以下三行代码并执行时,会发现新打开了一个浏览器窗口并访问了百度首页,然而这是怎么做到的呢? from se ...

随机推荐

  1. 【Netty】一个RPC实例

    Netty实现简易RPC调用 总体流程: 客户端发起rpc调用请求,封装好调用的接口名,函数名,返回类型,函数参数类型,函数参数值等属性,将消息发送给服务器. 服务器的handler解析rpc请求,调 ...

  2. SLF4J门面日志框架源码探索

    1 SLF4J介绍 SLF4J即Simple Logging Facade for Java,它提供了Java中所有日志框架的简单外观或抽象.因此,它使用户能够使用单个依赖项处理任何日志框架,例如:L ...

  3. 使用Flask和Django构建Web应用程序:现代Web应用程序框架

    目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 3. 实现步骤与流程 3.1 准备工作:环境配置与依赖安装 3.2 核心模块实现 3.3 集成 ...

  4. 图书商城项目练习②后端服务Node/Express/Sqlite

    本系列文章是为学习Vue的项目练习笔记,尽量详细记录一下一个完整项目的开发过程.面向初学者,本人也是初学者,搬砖技术还不成熟.项目在技术上前端为主,包含一些后端代码,从基础的数据库(Sqlite).到 ...

  5. PB从入坑到放弃(一)第一个HelloWorld程序

    前言 网上关于PowerBuilder的资料确实是少之又少. 为了方便,后面我们都用pb 来代替PowerBuilder 说到这不得不来说说自己的pb入坑经历, 自己也不是计算机科班出生. 刚到公司面 ...

  6. 精讲Mybatis··#{}和${}

    题目 笔记Notes 面试题目:#{}和${}的区别是什么? 网上的答案是:#{}是预编译处理,${}是字符串替换.mybatis在处理#{}时, 会将sql中的#{}替换为?号,调用Prepared ...

  7. Delta Lake_ High-Performance ACID Table Storage over Cloud Object Stores

    论文发表于 2020年, 研究数据湖产品的很好的学习资料. 概要 开篇很明确的表明了为什么要做Delta lake这样一个产品. Databricks尝试将数据仓库直接架在云上对象存储之上, 这种尝试 ...

  8. 我是如何组织 Go 代码的(目录结构 依赖注入 wire)

    背景 对于大多数 Gopher 来说,编写 Go 程序会直接在目录建立 main.go,xxx.go,yyy.go-- 不是说不好,对于小型工程来说,简单反而简洁明了,我也提倡小工程没必要整一些花里胡 ...

  9. 最为常用的Laravel操作(3)-模板

    Blade 模板引擎 模板继承 定义布局: <!-- 存放在 resources/views/layouts/app.blade.php --> <html> <head ...

  10. 树莓派使用Golang+MQ135检测室内空气质量

      MQ135是一个比较便宜的空气质量传感器,可以用在家庭以及工业场所中.树莓派是一个小巧但很强大的卡片电脑,基于Linux,同时提供了很多硬件接口,方便开发出各种电子产品.Golang是一款简单高效 ...