selenium库浅析

selenium,浅析 · 浏览次数 : 39

小编点评

**排版指南** * **排版**在代码中使用时应该使用****```**```**标签**。 * **缩进**在代码中使用时应该使用****```**```**缩进**标签**。 * ******在代码中使用时应该使用****```**```****标签**。 * ******在代码中使用时应该使用****```**```****标签**。 * ******在代码中使用时应该使用****```**```**标签**。 * ******在代码中使用时应该使用****```**```**标签**。

正文

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库浅析相似的内容:

selenium库浅析

selenium库浅析 基于4.3 pip install selenium安装好后,在sitepackages下 2个主要的目录,common和webdriver 1- common 该目录一共就一个模块exceptions.py ① exceptions.py 其中定义了32个异常,竟然有个同学

《最新出炉》系列初窥篇-Python+Playwright自动化测试-4-playwright等待浅析

1.简介 在介绍selenium的时候,宏哥也介绍过等待,是因为在某些元素出现后,才可以进行操作。有时候我们自己忘记添加等待时间后,查了半天代码确定就是没有问题,奇怪的就是获取不到元素。然后搞了好久,或者经过别人的提示才恍然大悟没有添加等待时间。而playwright为了避免我们犯这么low的错误,

Selenium+2Captcha 自动化+验证码识别实战

> 本文深入探讨了使用Selenium库进行网页自动化操作,并结合2Captcha服务实现ReCAPTCHA验证码的破解。内容涵盖Selenium的基础知识、验证码的分类、2Captcha服务的使用,以及通过实例进行的详细讲解,最后对实践进行总结和优化思考,为读者提供了一条完整的验证码破解实践路线图

selenium结合tenacity的retry实现验证码失败重试

说在前面 验证码登录的demo后续可以单独讲解,VIP学员对这部分应该都是掌握的,此处不再赘述 本文假设了一个场景 你通过OCR识别的验证码是有一定的错误几率的 本文是通过识别后的验证码去加一个随机字符,如果取到的是''空字符则可能成功,否则必然不会成功 所涉及的python库 selenium d

SpringBoot+Selenium模拟用户操作浏览器

Selenium Selenium是一个用于Web应用程序自动化测试的开源工具套件。它主要用于以下目的: 浏览器自动化:Selenium能够模拟真实用户在不同浏览器(如Chrome、Firefox、IE/Edge等)中的交互行为,通过编程方式控制浏览器执行一系列操作,例如点击按钮、填写表单、导航页面

Selenium4自动化测试8--控件获取数据--上传、下载、https和切换分页

10-上传 上传不能模拟用户在页面上选择本地文件,只能先把要上传的文件先准备好在代码里上传 import time from selenium.webdriver.support.select import Select #pip install selenium from selenium imp

比Selenium更优秀的playwright介绍与未来展望

Playwright是新兴的自动化测试工具,拥有丰富的功能和API,隐藏在众多的爬虫和自动化工具背后,而多模LLM的出现让Playwright可以如虎添翼,自动化智能化的RPA工具预计将会井喷般出现。

Selenium4自动化测试3--元素定位By.NAME,By.LINK_TEXT 和通过链接部分文本定位,By.PARTIAL_LINK_TEXT,css_selector定位,By.CSS_SELECTOR

4-通过名称定位,By.NAME name属性为表单中客户端提交数据的标识,一个网页中name值可能不是唯一的。所以要根据实际情况进行判断 import time from selenium import webdriver from selenium.webdriver.common.by imp

selenium Webdriver版本和浏览器版本不匹配问题:ChromeDriver only supports Chrome version 119 Current browser version is 124.0.6367.202

问题描述 代码如下: from selenium import webdriver from selenium.webdriver.common.by import By def test01(): driver = webdriver.Chrome() driver.get("https://ww

Selenium4自动化测试2--元素定位By.ID,By.CLASS_NAME,By.TAG_NAME

三、元素定位方式 1-通过id定位,By.ID id属性在HTML中是唯一的,因此使用id定位可以确保找到页面上唯一的元素。 由于id是唯一的,浏览器在查找元素时可以快速定位到目标元素,提高了定位的效率。 import time #pip install selenium from selenium