当前位置: 首页 > news >正文

Selenium库原代码WebDriver及WebElement方法属性总结

简单示例:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECdriver = webdriver.Chrome()try:driver.get("https://www.hao123.com/")# print('*****driver_type',type(driver)) # driver_type <class 'selenium.webdriver.chrome.webdriver.WebDriver'>input_elements = driver.find_elements(By.TAG_NAME, "input")for input_element in input_elements:print(input_element.get_attribute("outerHTML"))search_input = driver.find_element(By.CSS_SELECTOR, 'input[data-hook="searchInput"]')# print('*****search_input_type',type(search_input)) # search_input_type <class 'selenium.webdriver.remote.webelement.WebElement'>search_input.send_keys("Selenium库")search_button = driver.find_element(By.CSS_SELECTOR, 'input[data-hook="searchSubmit"]')search_button.click()handles = driver.window_handlesprint(type(handles))if len(handles) > 1:driver.switch_to.window(handles[1])# Wait for the search results to load completelyWebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div[id="content_left"]')))
finally:driver.quit()# In this updated version, we added the following imports:
# from selenium.webdriver.support.ui import WebDriverWait
# from selenium.webdriver.support import expected_conditions as EC
# We then added a WebDriverWait statement to wait for the presence of a specific element in the search results page:
# WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div[class="search-list-item"]')))
# This statement waits for up to 10 seconds for an element with the CSS selector 'div[class="search-list-item"]' to appear on the page. 
# Once the element appears, the script continues to execute.# Note that you may need to adjust the CSS selector or the wait time to suit your specific needs.
# (By.CSS_SELECTOR, 'div[id="content_left"]'), 

------------
Selenium 的 WebDriver 实现的源代码提供了以下基本操作和功能:

初始化浏览器会话:通过实例化 WebDriver 对象,可以初始化一个特定的浏览器会话,如Chrome、Firefox等。
执行 JavaScript:可以通过 WebDriver.execute_script() 方法执行 JavaScript 代码,实现对页面的动态操作或数据获取。
窗口管理:WebDriver 可以管理浏览器窗口,包括最大化窗口、最小化窗口、设置窗口大小等功能。
元素定位:使用 WebDriver 提供的方法,如定位元素的 find_elementfind_elements 等,可以定位页面上的元素,进行操作或获取元素信息。
截图:WebDriver 可以对当前页面进行截图,并保存为图片文件,方便后续分析或记录。
下载文件:通过 WebDriver 控制浏览器下载文件,并保存到指定的目录中。
以上是 Selenium WebDriver 实现的源代码提供的一些基本操作和功能,这些功能可以帮助用户进行自动化测试、网页操作或数据采集等任务。
selenium.webdriver.chrome.webdriver.WebDriver是 Selenium WebDriver 中用于操作 Chrome 浏览器的主要类之一,它继承自 selenium.webdriver.remote.webdriver.WebDriver。这个类提供了丰富的方法和属性,用于实现对 Chrome 浏览器的控制和页面操作。

常用方法:

  1. get(url) - 打开指定的网址
  2. find_element(by=, value=) - 根据指定条件查找单个元素
  3. find_elements(by=, value=) - 根据指定条件查找多个元素
  4. execute_script(script, *args) - 在当前页面执行 JavaScript 代码
  5. close() - 关闭当前窗口
  6. quit() - 退出浏览器驱动并关闭所有窗口
  7. maximize_window() - 最大化浏览器窗口
  8. set_window_size(width, height) - 设置浏览器窗口大小
  9. save_screenshot(filename) - 保存当前页面的截图到指定文件
  10. switch_to.frame(frame_reference) - 切换到指定的 iframe
  11. switch_to.default_content() - 切回到默认的内容上下文
  12. switch_to.window(window_name) - 切换到指定窗口
  13. back() - 在浏览器中执行回退操作
  14. forward() - 在浏览器中执行前进操作
  15. refresh() - 刷新当前页面

常用属性:

current_url: 当前页面的 URL。
title: 当前页面的标题。
page_source: 当前页面的源代码。
window_handles: 当前浏览器窗口的句柄列表。
current_window_handle: 当前窗口的句柄。
capabilities: 浏览器的配置信息和能力。
name: 浏览器实例的名称。
session_id: 浏览器会话的 ID。
desired_capabilities: 期望的浏览器配置信息。

通过这些常用方法和属性,您可以更好地利用 selenium.webdriver.chrome.webdriver.WebDriver 类来控制 Chrome 浏览器进行自动化测试、网页操作等各种任务。


"""The WebDriver implementation."""
import base64
import contextlib
import copy
import os
import pkgutil
import types
import typing
import warnings
import zipfile
from abc import ABCMeta
from base64 import b64decode
from base64 import urlsafe_b64encode
from contextlib import asynccontextmanager
from contextlib import contextmanager
from importlib import import_module
from typing import Dict
from typing import List
from typing import Optional
from typing import Unionfrom selenium.common.exceptions import InvalidArgumentException
from selenium.common.exceptions import JavascriptException
from selenium.common.exceptions import NoSuchCookieException
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.options import BaseOptions
from selenium.webdriver.common.print_page_options import PrintOptions
from selenium.webdriver.common.timeouts import Timeouts
from selenium.webdriver.common.virtual_authenticator import Credential
from selenium.webdriver.common.virtual_authenticator import VirtualAuthenticatorOptions
from selenium.webdriver.common.virtual_authenticator import (required_virtual_authenticator,
)
from selenium.webdriver.support.relative_locator import RelativeByfrom .bidi_connection import BidiConnection
from .command import Command
from .errorhandler import ErrorHandler
from .file_detector import FileDetector
from .file_detector import LocalFileDetector
from .mobile import Mobile
from .remote_connection import RemoteConnection
from .script_key import ScriptKey
from .shadowroot import ShadowRoot
from .switch_to import SwitchTo
from .webelement import WebElementcdp = Nonedef import_cdp():global cdpif not cdp:cdp = import_module("selenium.webdriver.common.bidi.cdp")def _create_caps(caps):"""Makes a W3C alwaysMatch capabilities object.Filters out capability names that are not in the W3C spec. Spec-compliantdrivers will reject requests containing unknown capability names.Moves the Firefox profile, if present, from the old location to the new Firefoxoptions object.:Args:- caps - A dictionary of capabilities requested by the caller."""caps = copy.deepcopy(caps)always_match = {}for k, v in caps.items():always_match[k] = vreturn {"capabilities": {"firstMatch": [{}], "alwaysMatch": always_match}}def get_remote_connection(capabilities, command_executor, keep_alive, ignore_local_proxy=False):from selenium.webdriver.chrome.remote_connection import ChromeRemoteConnectionfrom selenium.webdriver.edge.remote_connection import EdgeRemoteConnectionfrom selenium.webdriver.firefox.remote_connection import FirefoxRemoteConnectionfrom selenium.webdriver.safari.remote_connection import SafariRemoteConnectioncandidates = [ChromeRemoteConnection, EdgeRemoteConnection, SafariRemoteConnection, FirefoxRemoteConnection]handler = next((c for c in candidates if c.browser_name == capabilities.get("browserName")), RemoteConnection)return handler(command_executor, keep_alive=keep_alive, ignore_proxy=ignore_local_proxy)def create_matches(options: List[BaseOptions]) -> Dict:capabilities = {"capabilities": {}}opts = []for opt in options:opts.append(opt.to_capabilities())opts_size = len(opts)samesies = {}# Can not use bitwise operations on the dicts or lists due to# https://bugs.python.org/issue38210for i in range(opts_size):min_index = iif i + 1 < opts_size:first_keys = opts[min_index].keys()for kys in first_keys:if kys in opts[i + 1].keys():if opts[min_index][kys] == opts[i + 1][kys]:samesies.update({kys: opts[min_index][kys]})always = {}for k, v in samesies.items():always[k] = vfor i in opts:for k in always:del i[k]capabilities["capabilities"]["alwaysMatch"] = alwayscapabilities["capabilities"]["firstMatch"] = optsreturn capabilitiesclass BaseWebDriver(metaclass=ABCMeta):"""Abstract Base Class for all Webdriver subtypes.ABC's allow custom implementations of Webdriver to be registered sothat isinstance type checks will succeed."""class WebDriver(BaseWebDriver):"""Controls a browser by sending commands to a remote server. This serveris expected to be running the WebDriver wire protocol as defined athttps://www.selenium.dev/documentation/legacy/json_wire_protocol/.:Attributes:- session_id - String ID of the browser session started and controlled by this WebDriver.- capabilities - Dictionary of effective capabilities of this browser session as returnedby the remote server. See https://www.selenium.dev/documentation/legacy/desired_capabilities/- command_executor - remote_connection.RemoteConnection object used to execute commands.- error_handler - errorhandler.ErrorHandler object used to handle errors."""_web_element_cls = WebElement_shadowroot_cls = ShadowRootdef __init__(self,command_executor="http://127.0.0.1:4444",keep_alive=True,file_detector=None,options: Union[BaseOptions, List[BaseOptions]] = None,) -> None:"""Create a new driver that will issue commands using the wireprotocol.:Args:- command_executor - Either a string representing URL of the remote server or a customremote_connection.RemoteConnection object. Defaults to 'http://127.0.0.1:4444/wd/hub'.- keep_alive - Whether to configure remote_connection.RemoteConnection to useHTTP keep-alive. Defaults to True.- file_detector - Pass custom file detector object during instantiation. If None,then default LocalFileDetector() will be used.- options - instance of a driver options.Options class"""if isinstance(options, list):capabilities = create_matches(options)_ignore_local_proxy = Falseelse:capabilities = options.to_capabilities()_ignore_local_proxy = options._ignore_local_proxyself.command_executor = command_executorif isinstance(self.command_executor, (str, bytes)):self.command_executor = get_remote_connection(capabilities,command_executor=command_executor,keep_alive=keep_alive,ignore_local_proxy=_ignore_local_proxy,)self._is_remote = Trueself.session_id = Noneself.caps = {}self.pinned_scripts = {}self.error_handler = ErrorHandler()self._switch_to = SwitchTo(self)self._mobile = Mobile(self)self.file_detector = file_detector or LocalFileDetector()self._authenticator_id = Noneself.start_client()self.start_session(capabilities)def __repr__(self):return f'<{type(self).__module__}.{type(self).__name__} (session="{self.session_id}")>'def __enter__(self):return selfdef __exit__(self,exc_type: typing.Optional[typing.Type[BaseException]],exc: typing.Optional[BaseException],traceback: typing.Optional[types.TracebackType],):self.quit()@contextmanagerdef file_detector_context(self, file_detector_class, *args, **kwargs):"""Overrides the current file detector (if necessary) in limitedcontext. Ensures the original file detector is set afterwards.Example::with webdriver.file_detector_context(UselessFileDetector):someinput.send_keys('/etc/hosts'):Args:- file_detector_class - Class of the desired file detector. If the class is differentfrom the current file_detector, then the class is instantiated with args and kwargsand used as a file detector during the duration of the context manager.- args - Optional arguments that get passed to the file detector class duringinstantiation.- kwargs - Keyword arguments, passed the same way as args."""last_detector = Noneif not isinstance(self.file_detector, file_detector_class):last_detector = self.file_detectorself.file_detector = file_detector_class(*args, **kwargs)try:yieldfinally:if last_detector:self.file_detector = last_detector@propertydef mobile(self) -> Mobile:return self._mobile@propertydef name(self) -> str:"""Returns the name of the underlying browser for this instance.:Usage:::name = driver.name"""if "browserName" in self.caps:return self.caps["browserName"]raise KeyError("browserName not specified in session capabilities")def start_client(self):"""Called before starting a new session.This method may be overridden to define custom startup behavior."""passdef stop_client(self):"""Called after executing a quit command.This method may be overridden to define custom shutdownbehavior."""passdef start_session(self, capabilities: dict) -> None:"""Creates a new session with the desired capabilities.:Args:- capabilities - a capabilities dict to start the session with."""caps = _create_caps(capabilities)response = self.execute(Command.NEW_SESSION, caps)["value"]self.session_id = response.get("sessionId")self.caps = response.get("capabilities")def _wrap_value(self, value):if isinstance(value, dict):converted = {}for key, val in value.items():converted[key] = self._wrap_value(val)return convertedif isinstance(value, self._web_element_cls):return {"element-6066-11e4-a52e-4f735466cecf": value.id}if isinstance(value, self._shadowroot_cls):return {"shadow-6066-11e4-a52e-4f735466cecf": value.id}if isinstance(value, list):return list(self._wrap_value(item) for item in value)return valuedef create_web_element(self, element_id: str) -> WebElement:"""Creates a web element with the specified `element_id`."""return self._web_element_cls(self, element_id)def _unwrap_value(self, value):if isinstance(value, dict):if "element-6066-11e4-a52e-4f735466cecf" in value:return self.create_web_element(value["element-6066-11e4-a52e-4f735466cecf"])if "shadow-6066-11e4-a52e-4f735466cecf" in value:return self._shadowroot_cls(self, value["shadow-6066-11e4-a52e-4f735466cecf"])for key, val in value.items():value[key] = self._unwrap_value(val)return valueif isinstance(value, list):return list(self._unwrap_value(item) for item in value)return valuedef execute(self, driver_command: str, params: dict = None) -> dict:"""Sends a command to be executed by a command.CommandExecutor.:Args:- driver_command: The name of the command to execute as a string.- params: A dictionary of named parameters to send with the command.:Returns:The command's JSON response loaded into a dictionary object."""params = self._wrap_value(params)if self.session_id:if not params:params = {"sessionId": self.session_id}elif "sessionId" not in params:params["sessionId"] = self.session_idresponse = self.command_executor.execute(driver_command, params)if response:self.error_handler.check_response(response)response["value"] = self._unwrap_value(response.get("value", None))return response# If the server doesn't send a response, assume the command was# a successreturn {"success": 0, "value": None, "sessionId": self.session_id}def get(self, url: str) -> None:"""Loads a web page in the current browser session."""self.execute(Command.GET, {"url": url})@propertydef title(self) -> str:"""Returns the title of the current page.:Usage:::title = driver.title"""return self.execute(Command.GET_TITLE).get("value", "")def pin_script(self, script: str, script_key=None) -> ScriptKey:"""Store common javascript scripts to be executed later by a uniquehashable ID."""script_key_instance = ScriptKey(script_key)self.pinned_scripts[script_key_instance.id] = scriptreturn script_key_instancedef unpin(self, script_key: ScriptKey) -> None:"""Remove a pinned script from storage."""try:self.pinned_scripts.pop(script_key.id)except KeyError:raise KeyError(f"No script with key: {script_key} existed in {self.pinned_scripts}") from Nonedef get_pinned_scripts(self) -> List[str]:return list(self.pinned_scripts)def execute_script(self, script, *args):"""Synchronously Executes JavaScript in the current window/frame.:Args:- script: The JavaScript to execute.- \\*args: Any applicable arguments for your JavaScript.:Usage:::driver.execute_script('return document.title;')"""if isinstance(script, ScriptKey):try:script = self.pinned_scripts[script.id]except KeyError:raise JavascriptException("Pinned script could not be found")converted_args = list(args)command = Command.W3C_EXECUTE_SCRIPTreturn self.execute(command, {"script": script, "args": converted_args})["value"]def execute_async_script(self, script: str, *args):"""Asynchronously Executes JavaScript in the current window/frame.:Args:- script: The JavaScript to execute.- \\*args: Any applicable arguments for your JavaScript.:Usage:::script = "var callback = arguments[arguments.length - 1]; " \\"window.setTimeout(function(){ callback('timeout') }, 3000);"driver.execute_async_script(script)"""converted_args = list(args)command = Command.W3C_EXECUTE_SCRIPT_ASYNCreturn self.execute(command, {"script": script, "args": converted_args})["value"]@propertydef current_url(self) -> str:"""Gets the URL of the current page.:Usage:::driver.current_url"""return self.execute(Command.GET_CURRENT_URL)["value"]@propertydef page_source(self) -> str:"""Gets the source of the current page.:Usage:::driver.page_source"""return self.execute(Command.GET_PAGE_SOURCE)["value"]def close(self) -> None:"""Closes the current window.:Usage:::driver.close()"""self.execute(Command.CLOSE)def quit(self) -> None:"""Quits the driver and closes every associated window.:Usage:::driver.quit()"""try:self.execute(Command.QUIT)finally:self.stop_client()self.command_executor.close()@propertydef current_window_handle(self) -> str:"""Returns the handle of the current window.:Usage:::driver.current_window_handle"""return self.execute(Command.W3C_GET_CURRENT_WINDOW_HANDLE)["value"]@propertydef window_handles(self) -> List[str]:"""Returns the handles of all windows within the current session.:Usage:::driver.window_handles"""return self.execute(Command.W3C_GET_WINDOW_HANDLES)["value"]def maximize_window(self) -> None:"""Maximizes the current window that webdriver is using."""command = Command.W3C_MAXIMIZE_WINDOWself.execute(command, None)def fullscreen_window(self) -> None:"""Invokes the window manager-specific 'full screen' operation."""self.execute(Command.FULLSCREEN_WINDOW)def minimize_window(self) -> None:"""Invokes the window manager-specific 'minimize' operation."""self.execute(Command.MINIMIZE_WINDOW)def print_page(self, print_options: Optional[PrintOptions] = None) -> str:"""Takes PDF of the current page.The driver makes a best effort to return a PDF based on theprovided parameters."""options = {}if print_options:options = print_options.to_dict()return self.execute(Command.PRINT_PAGE, options)["value"]@propertydef switch_to(self) -> SwitchTo:""":Returns:- SwitchTo: an object containing all options to switch focus into:Usage:::element = driver.switch_to.active_elementalert = driver.switch_to.alertdriver.switch_to.default_content()driver.switch_to.frame('frame_name')driver.switch_to.frame(1)driver.switch_to.frame(driver.find_elements(By.TAG_NAME, "iframe")[0])driver.switch_to.parent_frame()driver.switch_to.window('main')"""return self._switch_to# Navigationdef back(self) -> None:"""Goes one step backward in the browser history.:Usage:::driver.back()"""self.execute(Command.GO_BACK)def forward(self) -> None:"""Goes one step forward in the browser history.:Usage:::driver.forward()"""self.execute(Command.GO_FORWARD)def refresh(self) -> None:"""Refreshes the current page.:Usage:::driver.refresh()"""self.execute(Command.REFRESH)# Optionsdef get_cookies(self) -> List[dict]:"""Returns a set of dictionaries, corresponding to cookies visible inthe current session.:Usage:::driver.get_cookies()"""return self.execute(Command.GET_ALL_COOKIES)["value"]def get_cookie(self, name) -> typing.Optional[typing.Dict]:"""Get a single cookie by name. Returns the cookie if found, None ifnot.:Usage:::driver.get_cookie('my_cookie')"""with contextlib.suppress(NoSuchCookieException):return self.execute(Command.GET_COOKIE, {"name": name})["value"]return Nonedef delete_cookie(self, name) -> None:"""Deletes a single cookie with the given name.:Usage:::driver.delete_cookie('my_cookie')"""self.execute(Command.DELETE_COOKIE, {"name": name})def delete_all_cookies(self) -> None:"""Delete all cookies in the scope of the session.:Usage:::driver.delete_all_cookies()"""self.execute(Command.DELETE_ALL_COOKIES)def add_cookie(self, cookie_dict) -> None:"""Adds a cookie to your current session.:Args:- cookie_dict: A dictionary object, with required keys - "name" and "value";optional keys - "path", "domain", "secure", "httpOnly", "expiry", "sameSite":Usage:::driver.add_cookie({'name' : 'foo', 'value' : 'bar'})driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/'})driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/', 'secure' : True})driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'sameSite' : 'Strict'})"""if "sameSite" in cookie_dict:assert cookie_dict["sameSite"] in ["Strict", "Lax", "None"]self.execute(Command.ADD_COOKIE, {"cookie": cookie_dict})else:self.execute(Command.ADD_COOKIE, {"cookie": cookie_dict})# Timeoutsdef implicitly_wait(self, time_to_wait: float) -> None:"""Sets a sticky timeout to implicitly wait for an element to be found,or a command to complete. This method only needs to be called one timeper session. To set the timeout for calls to execute_async_script, seeset_script_timeout.:Args:- time_to_wait: Amount of time to wait (in seconds):Usage:::driver.implicitly_wait(30)"""self.execute(Command.SET_TIMEOUTS, {"implicit": int(float(time_to_wait) * 1000)})def set_script_timeout(self, time_to_wait: float) -> None:"""Set the amount of time that the script should wait during anexecute_async_script call before throwing an error.:Args:- time_to_wait: The amount of time to wait (in seconds):Usage:::driver.set_script_timeout(30)"""self.execute(Command.SET_TIMEOUTS, {"script": int(float(time_to_wait) * 1000)})def set_page_load_timeout(self, time_to_wait: float) -> None:"""Set the amount of time to wait for a page load to complete beforethrowing an error.:Args:- time_to_wait: The amount of time to wait:Usage:::driver.set_page_load_timeout(30)"""try:self.execute(Command.SET_TIMEOUTS, {"pageLoad": int(float(time_to_wait) * 1000)})except WebDriverException:self.execute(Command.SET_TIMEOUTS, {"ms": float(time_to_wait) * 1000, "type": "page load"})@propertydef timeouts(self) -> Timeouts:"""Get all the timeouts that have been set on the current session.:Usage:::driver.timeouts:rtype: Timeout"""timeouts = self.execute(Command.GET_TIMEOUTS)["value"]timeouts["implicit_wait"] = timeouts.pop("implicit") / 1000timeouts["page_load"] = timeouts.pop("pageLoad") / 1000timeouts["script"] = timeouts.pop("script") / 1000return Timeouts(**timeouts)@timeouts.setterdef timeouts(self, timeouts) -> None:"""Set all timeouts for the session. This will override any previouslyset timeouts.:Usage:::my_timeouts = Timeouts()my_timeouts.implicit_wait = 10driver.timeouts = my_timeouts"""_ = self.execute(Command.SET_TIMEOUTS, timeouts._to_json())["value"]def find_element(self, by=By.ID, value: Optional[str] = None) -> WebElement:"""Find an element given a By strategy and locator.:Usage:::element = driver.find_element(By.ID, 'foo'):rtype: WebElement"""if isinstance(by, RelativeBy):elements = self.find_elements(by=by, value=value)if not elements:raise NoSuchElementException(f"Cannot locate relative element with: {by.root}")return elements[0]if by == By.ID:by = By.CSS_SELECTORvalue = f'[id="{value}"]'elif by == By.CLASS_NAME:by = By.CSS_SELECTORvalue = f".{value}"elif by == By.NAME:by = By.CSS_SELECTORvalue = f'[name="{value}"]'return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]def find_elements(self, by=By.ID, value: Optional[str] = None) -> List[WebElement]:"""Find elements given a By strategy and locator.:Usage:::elements = driver.find_elements(By.CLASS_NAME, 'foo'):rtype: list of WebElement"""if isinstance(by, RelativeBy):_pkg = ".".join(__name__.split(".")[:-1])raw_function = pkgutil.get_data(_pkg, "findElements.js").decode("utf8")find_element_js = f"/* findElements */return ({raw_function}).apply(null, arguments);"return self.execute_script(find_element_js, by.to_dict())if by == By.ID:by = By.CSS_SELECTORvalue = f'[id="{value}"]'elif by == By.CLASS_NAME:by = By.CSS_SELECTORvalue = f".{value}"elif by == By.NAME:by = By.CSS_SELECTORvalue = f'[name="{value}"]'# Return empty list if driver returns null# See https://github.com/SeleniumHQ/selenium/issues/4555return self.execute(Command.FIND_ELEMENTS, {"using": by, "value": value})["value"] or []@propertydef capabilities(self) -> dict:"""Returns the drivers current capabilities being used."""return self.capsdef get_screenshot_as_file(self, filename) -> bool:"""Saves a screenshot of the current window to a PNG image file.Returns False if there is any IOError, else returns True. Use fullpaths in your filename.:Args:- filename: The full path you wish to save your screenshot to. Thisshould end with a `.png` extension.:Usage:::driver.get_screenshot_as_file('/Screenshots/foo.png')"""if not str(filename).lower().endswith(".png"):warnings.warn("name used for saved screenshot does not match file type. It should end with a `.png` extension",UserWarning,stacklevel=2,)png = self.get_screenshot_as_png()try:with open(filename, "wb") as f:f.write(png)except OSError:return Falsefinally:del pngreturn Truedef save_screenshot(self, filename) -> bool:"""Saves a screenshot of the current window to a PNG image file.Returns False if there is any IOError, else returns True. Use fullpaths in your filename.:Args:- filename: The full path you wish to save your screenshot to. Thisshould end with a `.png` extension.:Usage:::driver.save_screenshot('/Screenshots/foo.png')"""return self.get_screenshot_as_file(filename)def get_screenshot_as_png(self) -> bytes:"""Gets the screenshot of the current window as a binary data.:Usage:::driver.get_screenshot_as_png()"""return b64decode(self.get_screenshot_as_base64().encode("ascii"))def get_screenshot_as_base64(self) -> str:"""Gets the screenshot of the current window as a base64 encoded stringwhich is useful in embedded images in HTML.:Usage:::driver.get_screenshot_as_base64()"""return self.execute(Command.SCREENSHOT)["value"]def set_window_size(self, width, height, windowHandle: str = "current") -> None:"""Sets the width and height of the current window. (window.resizeTo):Args:- width: the width in pixels to set the window to- height: the height in pixels to set the window to:Usage:::driver.set_window_size(800,600)"""self._check_if_window_handle_is_current(windowHandle)self.set_window_rect(width=int(width), height=int(height))def get_window_size(self, windowHandle: str = "current") -> dict:"""Gets the width and height of the current window.:Usage:::driver.get_window_size()"""self._check_if_window_handle_is_current(windowHandle)size = self.get_window_rect()if size.get("value", None):size = size["value"]return {k: size[k] for k in ("width", "height")}def set_window_position(self, x, y, windowHandle: str = "current") -> dict:"""Sets the x,y position of the current window. (window.moveTo):Args:- x: the x-coordinate in pixels to set the window position- y: the y-coordinate in pixels to set the window position:Usage:::driver.set_window_position(0,0)"""self._check_if_window_handle_is_current(windowHandle)return self.set_window_rect(x=int(x), y=int(y))def get_window_position(self, windowHandle="current") -> dict:"""Gets the x,y position of the current window.:Usage:::driver.get_window_position()"""self._check_if_window_handle_is_current(windowHandle)position = self.get_window_rect()return {k: position[k] for k in ("x", "y")}def _check_if_window_handle_is_current(self, windowHandle: str) -> None:"""Warns if the window handle is not equal to `current`."""if windowHandle != "current":warnings.warn("Only 'current' window is supported for W3C compatible browsers.", stacklevel=2)def get_window_rect(self) -> dict:"""Gets the x, y coordinates of the window as well as height and widthof the current window.:Usage:::driver.get_window_rect()"""return self.execute(Command.GET_WINDOW_RECT)["value"]def set_window_rect(self, x=None, y=None, width=None, height=None) -> dict:"""Sets the x, y coordinates of the window as well as height and widthof the current window. This method is only supported for W3C compatiblebrowsers; other browsers should use `set_window_position` and`set_window_size`.:Usage:::driver.set_window_rect(x=10, y=10)driver.set_window_rect(width=100, height=200)driver.set_window_rect(x=10, y=10, width=100, height=200)"""if (x is None and y is None) and (not height and not width):raise InvalidArgumentException("x and y or height and width need values")return self.execute(Command.SET_WINDOW_RECT, {"x": x, "y": y, "width": width, "height": height})["value"]@propertydef file_detector(self) -> FileDetector:return self._file_detector@file_detector.setterdef file_detector(self, detector) -> None:"""Set the file detector to be used when sending keyboard input. Bydefault, this is set to a file detector that does nothing.see FileDetectorsee LocalFileDetectorsee UselessFileDetector:Args:- detector: The detector to use. Must not be None."""if not detector:raise WebDriverException("You may not set a file detector that is null")if not isinstance(detector, FileDetector):raise WebDriverException("Detector has to be instance of FileDetector")self._file_detector = detector@propertydef orientation(self):"""Gets the current orientation of the device.:Usage:::orientation = driver.orientation"""return self.execute(Command.GET_SCREEN_ORIENTATION)["value"]@orientation.setterdef orientation(self, value) -> None:"""Sets the current orientation of the device.:Args:- value: orientation to set it to.:Usage:::driver.orientation = 'landscape'"""allowed_values = ["LANDSCAPE", "PORTRAIT"]if value.upper() in allowed_values:self.execute(Command.SET_SCREEN_ORIENTATION, {"orientation": value})else:raise WebDriverException("You can only set the orientation to 'LANDSCAPE' and 'PORTRAIT'")@propertydef log_types(self):"""Gets a list of the available log types. This only works with w3ccompliant browsers.:Usage:::driver.log_types"""return self.execute(Command.GET_AVAILABLE_LOG_TYPES)["value"]def get_log(self, log_type):"""Gets the log for a given log type.:Args:- log_type: type of log that which will be returned:Usage:::driver.get_log('browser')driver.get_log('driver')driver.get_log('client')driver.get_log('server')"""return self.execute(Command.GET_LOG, {"type": log_type})["value"]@asynccontextmanagerasync def bidi_connection(self):global cdpimport_cdp()if self.caps.get("se:cdp"):ws_url = self.caps.get("se:cdp")version = self.caps.get("se:cdpVersion").split(".")[0]else:version, ws_url = self._get_cdp_details()if not ws_url:raise WebDriverException("Unable to find url to connect to from capabilities")devtools = cdp.import_devtools(version)async with cdp.open_cdp(ws_url) as conn:targets = await conn.execute(devtools.target.get_targets())target_id = targets[0].target_idasync with conn.open_session(target_id) as session:yield BidiConnection(session, cdp, devtools)def _get_cdp_details(self):import jsonimport urllib3http = urllib3.PoolManager()_firefox = Falseif self.caps.get("browserName") == "chrome":debugger_address = self.caps.get("goog:chromeOptions").get("debuggerAddress")elif self.caps.get("browserName") == "msedge":debugger_address = self.caps.get("ms:edgeOptions").get("debuggerAddress")else:_firefox = Truedebugger_address = self.caps.get("moz:debuggerAddress")res = http.request("GET", f"http://{debugger_address}/json/version")data = json.loads(res.data)browser_version = data.get("Browser")websocket_url = data.get("webSocketDebuggerUrl")import reif _firefox:# Mozilla Automation Team asked to only support 85# until WebDriver Bidi is available.version = 85else:version = re.search(r".*/(\d+)\.", browser_version).group(1)return version, websocket_url# Virtual Authenticator Methodsdef add_virtual_authenticator(self, options: VirtualAuthenticatorOptions) -> None:"""Adds a virtual authenticator with the given options."""self._authenticator_id = self.execute(Command.ADD_VIRTUAL_AUTHENTICATOR, options.to_dict())["value"]@propertydef virtual_authenticator_id(self) -> str:"""Returns the id of the virtual authenticator."""return self._authenticator_id@required_virtual_authenticatordef remove_virtual_authenticator(self) -> None:"""Removes a previously added virtual authenticator.The authenticator is no longer valid after removal, so nomethods may be called."""self.execute(Command.REMOVE_VIRTUAL_AUTHENTICATOR, {"authenticatorId": self._authenticator_id})self._authenticator_id = None@required_virtual_authenticatordef add_credential(self, credential: Credential) -> None:"""Injects a credential into the authenticator."""self.execute(Command.ADD_CREDENTIAL, {**credential.to_dict(), "authenticatorId": self._authenticator_id})@required_virtual_authenticatordef get_credentials(self) -> List[Credential]:"""Returns the list of credentials owned by the authenticator."""credential_data = self.execute(Command.GET_CREDENTIALS, {"authenticatorId": self._authenticator_id})return [Credential.from_dict(credential) for credential in credential_data["value"]]@required_virtual_authenticatordef remove_credential(self, credential_id: Union[str, bytearray]) -> None:"""Removes a credential from the authenticator."""# Check if the credential is bytearray converted to b64 stringif isinstance(credential_id, bytearray):credential_id = urlsafe_b64encode(credential_id).decode()self.execute(Command.REMOVE_CREDENTIAL, {"credentialId": credential_id, "authenticatorId": self._authenticator_id})@required_virtual_authenticatordef remove_all_credentials(self) -> None:"""Removes all credentials from the authenticator."""self.execute(Command.REMOVE_ALL_CREDENTIALS, {"authenticatorId": self._authenticator_id})@required_virtual_authenticatordef set_user_verified(self, verified: bool) -> None:"""Sets whether the authenticator will simulate success or fail on userverification.verified: True if the authenticator will pass user verification, False otherwise."""self.execute(Command.SET_USER_VERIFIED, {"authenticatorId": self._authenticator_id, "isUserVerified": verified})def get_downloadable_files(self) -> dict:"""Retrieves the downloadable files as a map of file names and theircorresponding URLs."""if "se:downloadsEnabled" not in self.capabilities:raise WebDriverException("You must enable downloads in order to work with downloadable files.")return self.execute(Command.GET_DOWNLOADABLE_FILES)["value"]["names"]def download_file(self, file_name: str, target_directory: str) -> None:"""Downloads a file with the specified file name to the targetdirectory.file_name: The name of the file to download.target_directory: The path to the directory to save the downloaded file."""if "se:downloadsEnabled" not in self.capabilities:raise WebDriverException("You must enable downloads in order to work with downloadable files.")if not os.path.exists(target_directory):os.makedirs(target_directory)contents = self.execute(Command.DOWNLOAD_FILE, {"name": file_name})["value"]["contents"]target_file = os.path.join(target_directory, file_name)with open(target_file, "wb") as file:file.write(base64.b64decode(contents))with zipfile.ZipFile(target_file, "r") as zip_ref:zip_ref.extractall(target_directory)def delete_downloadable_files(self) -> None:"""Deletes all downloadable files."""if "se:downloadsEnabled" not in self.capabilities:raise WebDriverException("You must enable downloads in order to work with downloadable files.")self.execute(Command.DELETE_DOWNLOADABLE_FILES)

------------------- 

 这段代码看起来是关于对 Web 元素进行操作的,使用了 Selenium WebDriver 库。它定义了一个 WebElement 类用于表示网页中的 DOM 元素,并提供了一系列方法来操作元素,比如点击、输入文本、获取属性、截图等。除此之外,还包括了一些私有方法和元素定位的方法。这段代码主要是基于 Python 的 Selenium 库,用于模拟浏览器操作网页元素。
selenium.webdriver.remote.webelement.WebElement是 Selenium WebDriver 中用于表示网页上的元素(如按钮、输入框、链接等)的主要类之一。通过该类,可以对网页上的元素进行查找、操作和获取属性等操作。

常用方法:
click(self) -> None: 点击元素。
submit(self): 提交表单。
clear(self) -> None: 清除文本(如果是文本输入元素)。
send_keys(self, *value) -> None: 模拟向元素输入文本。
find_element(self, by=By.ID, value=None) -> WebElement: 根据查找策略和定位器查找元素。
find_elements(self, by=By.ID, value=None) -> List[WebElement]: 根据查找策略和定位器查找多个元素。
get_attribute(name): 获取元素的指定属性值。
is_displayed(): 判断元素是否可见。
is_enabled(): 判断元素是否可操作。
is_selected(): 判断元素是否被选中(针对复选框、单选框等元素)。

常用属性:
text - 获取元素的文本内容
tag_name - 获取元素的标签名
size - 获取元素的尺寸
location - 获取元素在页面中的位置
rect - 获取元素的位置和大小信息的字典表示


通过这些方法和属性,我们可以对网页元素执行点击、输入文本、获取属性、截图等操作,并获取元素的相关信息。这些方法和属性可以帮助我们实现自动化测试、网页数据采集等功能。


from __future__ import annotationsimport os
import pkgutil
import warnings
import zipfile
from abc import ABCMeta
from base64 import b64decode
from base64 import encodebytes
from hashlib import md5 as md5_hash
from io import BytesIO
from typing import Listfrom selenium.common.exceptions import JavascriptException
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.utils import keys_to_typingfrom .command import Command
from .shadowroot import ShadowRoot# TODO: When moving to supporting python 3.9 as the minimum version we can
# use built in importlib_resources.files.
getAttribute_js = None
isDisplayed_js = Nonedef _load_js():global getAttribute_jsglobal isDisplayed_js_pkg = ".".join(__name__.split(".")[:-1])getAttribute_js = pkgutil.get_data(_pkg, "getAttribute.js").decode("utf8")isDisplayed_js = pkgutil.get_data(_pkg, "isDisplayed.js").decode("utf8")class BaseWebElement(metaclass=ABCMeta):"""Abstract Base Class for WebElement.ABC's will allow custom types to be registered as a WebElement topass type checks."""passclass WebElement(BaseWebElement):"""Represents a DOM element.Generally, all interesting operations that interact with a document will beperformed through this interface.All method calls will do a freshness check to ensure that the elementreference is still valid.  This essentially determines whether theelement is still attached to the DOM.  If this test fails, then an``StaleElementReferenceException`` is thrown, and all future calls to thisinstance will fail."""def __init__(self, parent, id_) -> None:self._parent = parentself._id = id_def __repr__(self):return f'<{type(self).__module__}.{type(self).__name__} (session="{self._parent.session_id}", element="{self._id}")>'@propertydef tag_name(self) -> str:"""This element's ``tagName`` property."""return self._execute(Command.GET_ELEMENT_TAG_NAME)["value"]@propertydef text(self) -> str:"""The text of the element."""return self._execute(Command.GET_ELEMENT_TEXT)["value"]def click(self) -> None:"""Clicks the element."""self._execute(Command.CLICK_ELEMENT)def submit(self):"""Submits a form."""script = ("/* submitForm */var form = arguments[0];\n"'while (form.nodeName != "FORM" && form.parentNode) {\n'"  form = form.parentNode;\n""}\n""if (!form) { throw Error('Unable to find containing form element'); }\n""if (!form.ownerDocument) { throw Error('Unable to find owning document'); }\n""var e = form.ownerDocument.createEvent('Event');\n""e.initEvent('submit', true, true);\n""if (form.dispatchEvent(e)) { HTMLFormElement.prototype.submit.call(form) }\n")try:self._parent.execute_script(script, self)except JavascriptException as exc:raise WebDriverException("To submit an element, it must be nested inside a form element") from excdef clear(self) -> None:"""Clears the text if it's a text entry element."""self._execute(Command.CLEAR_ELEMENT)def get_property(self, name) -> str | bool | WebElement | dict:"""Gets the given property of the element.:Args:- name - Name of the property to retrieve.:Usage:::text_length = target_element.get_property("text_length")"""try:return self._execute(Command.GET_ELEMENT_PROPERTY, {"name": name})["value"]except WebDriverException:# if we hit an end point that doesn't understand getElementProperty lets fake itreturn self.parent.execute_script("return arguments[0][arguments[1]]", self, name)def get_dom_attribute(self, name) -> str:"""Gets the given attribute of the element. Unlike:func:`~selenium.webdriver.remote.BaseWebElement.get_attribute`, thismethod only returns attributes declared in the element's HTML markup.:Args:- name - Name of the attribute to retrieve.:Usage:::text_length = target_element.get_dom_attribute("class")"""return self._execute(Command.GET_ELEMENT_ATTRIBUTE, {"name": name})["value"]def get_attribute(self, name) -> str | None:"""Gets the given attribute or property of the element.This method will first try to return the value of a property with thegiven name. If a property with that name doesn't exist, it returns thevalue of the attribute with the same name. If there's no attribute withthat name, ``None`` is returned.Values which are considered truthy, that is equals "true" or "false",are returned as booleans.  All other non-``None`` values are returnedas strings.  For attributes or properties which do not exist, ``None``is returned.To obtain the exact value of the attribute or property,use :func:`~selenium.webdriver.remote.BaseWebElement.get_dom_attribute` or:func:`~selenium.webdriver.remote.BaseWebElement.get_property` methods respectively.:Args:- name - Name of the attribute/property to retrieve.Example::# Check if the "active" CSS class is applied to an element.is_active = "active" in target_element.get_attribute("class")"""if getAttribute_js is None:_load_js()attribute_value = self.parent.execute_script(f"/* getAttribute */return ({getAttribute_js}).apply(null, arguments);", self, name)return attribute_valuedef is_selected(self) -> bool:"""Returns whether the element is selected.Can be used to check if a checkbox or radio button is selected."""return self._execute(Command.IS_ELEMENT_SELECTED)["value"]def is_enabled(self) -> bool:"""Returns whether the element is enabled."""return self._execute(Command.IS_ELEMENT_ENABLED)["value"]def send_keys(self, *value) -> None:"""Simulates typing into the element.:Args:- value - A string for typing, or setting form fields.  For settingfile inputs, this could be a local file path.Use this to send simple key events or to fill out form fields::form_textfield = driver.find_element(By.NAME, 'username')form_textfield.send_keys("admin")This can also be used to set file inputs.::file_input = driver.find_element(By.NAME, 'profilePic')file_input.send_keys("path/to/profilepic.gif")# Generally it's better to wrap the file path in one of the methods# in os.path to return the actual path to support cross OS testing.# file_input.send_keys(os.path.abspath("path/to/profilepic.gif"))"""# transfer file to another machine only if remote driver is used# the same behaviour as for java bindingif self.parent._is_remote:local_files = list(map(lambda keys_to_send: self.parent.file_detector.is_local_file(str(keys_to_send)),"".join(map(str, value)).split("\n"),))if None not in local_files:remote_files = []for file in local_files:remote_files.append(self._upload(file))value = "\n".join(remote_files)self._execute(Command.SEND_KEYS_TO_ELEMENT, {"text": "".join(keys_to_typing(value)), "value": keys_to_typing(value)})@propertydef shadow_root(self) -> ShadowRoot:"""Returns a shadow root of the element if there is one or an error.Only works from Chromium 96, Firefox 96, and Safari 16.4 onwards.:Returns:- ShadowRoot object or- NoSuchShadowRoot - if no shadow root was attached to element"""return self._execute(Command.GET_SHADOW_ROOT)["value"]# RenderedWebElement Itemsdef is_displayed(self) -> bool:"""Whether the element is visible to a user."""# Only go into this conditional for browsers that don't use the atom themselvesif isDisplayed_js is None:_load_js()return self.parent.execute_script(f"/* isDisplayed */return ({isDisplayed_js}).apply(null, arguments);", self)@propertydef location_once_scrolled_into_view(self) -> dict:"""THIS PROPERTY MAY CHANGE WITHOUT WARNING. Use this to discover whereon the screen an element is so that we can click it. This method shouldcause the element to be scrolled into view.Returns the top lefthand corner location on the screen, or zerocoordinates if the element is not visible."""old_loc = self._execute(Command.W3C_EXECUTE_SCRIPT,{"script": "arguments[0].scrollIntoView(true); return arguments[0].getBoundingClientRect()","args": [self],},)["value"]return {"x": round(old_loc["x"]), "y": round(old_loc["y"])}@propertydef size(self) -> dict:"""The size of the element."""size = self._execute(Command.GET_ELEMENT_RECT)["value"]new_size = {"height": size["height"], "width": size["width"]}return new_sizedef value_of_css_property(self, property_name) -> str:"""The value of a CSS property."""return self._execute(Command.GET_ELEMENT_VALUE_OF_CSS_PROPERTY, {"propertyName": property_name})["value"]@propertydef location(self) -> dict:"""The location of the element in the renderable canvas."""old_loc = self._execute(Command.GET_ELEMENT_RECT)["value"]new_loc = {"x": round(old_loc["x"]), "y": round(old_loc["y"])}return new_loc@propertydef rect(self) -> dict:"""A dictionary with the size and location of the element."""return self._execute(Command.GET_ELEMENT_RECT)["value"]@propertydef aria_role(self) -> str:"""Returns the ARIA role of the current web element."""return self._execute(Command.GET_ELEMENT_ARIA_ROLE)["value"]@propertydef accessible_name(self) -> str:"""Returns the ARIA Level of the current webelement."""return self._execute(Command.GET_ELEMENT_ARIA_LABEL)["value"]@propertydef screenshot_as_base64(self) -> str:"""Gets the screenshot of the current element as a base64 encodedstring.:Usage:::img_b64 = element.screenshot_as_base64"""return self._execute(Command.ELEMENT_SCREENSHOT)["value"]@propertydef screenshot_as_png(self) -> bytes:"""Gets the screenshot of the current element as a binary data.:Usage:::element_png = element.screenshot_as_png"""return b64decode(self.screenshot_as_base64.encode("ascii"))def screenshot(self, filename) -> bool:"""Saves a screenshot of the current element to a PNG image file.Returns False if there is any IOError, else returns True. Use fullpaths in your filename.:Args:- filename: The full path you wish to save your screenshot to. Thisshould end with a `.png` extension.:Usage:::element.screenshot('/Screenshots/foo.png')"""if not filename.lower().endswith(".png"):warnings.warn("name used for saved screenshot does not match file type. It should end with a `.png` extension",UserWarning,)png = self.screenshot_as_pngtry:with open(filename, "wb") as f:f.write(png)except OSError:return Falsefinally:del pngreturn True@propertydef parent(self):"""Internal reference to the WebDriver instance this element was foundfrom."""return self._parent@propertydef id(self) -> str:"""Internal ID used by selenium.This is mainly for internal use. Simple use cases such as checking if 2webelements refer to the same element, can be done using ``==``::if element1 == element2:print("These 2 are equal")"""return self._iddef __eq__(self, element):return hasattr(element, "id") and self._id == element.iddef __ne__(self, element):return not self.__eq__(element)# Private Methodsdef _execute(self, command, params=None):"""Executes a command against the underlying HTML element.Args:command: The name of the command to _execute as a string.params: A dictionary of named parameters to send with the command.Returns:The command's JSON response loaded into a dictionary object."""if not params:params = {}params["id"] = self._idreturn self._parent.execute(command, params)def find_element(self, by=By.ID, value=None) -> WebElement:"""Find an element given a By strategy and locator.:Usage:::element = element.find_element(By.ID, 'foo'):rtype: WebElement"""if by == By.ID:by = By.CSS_SELECTORvalue = f'[id="{value}"]'elif by == By.CLASS_NAME:by = By.CSS_SELECTORvalue = f".{value}"elif by == By.NAME:by = By.CSS_SELECTORvalue = f'[name="{value}"]'return self._execute(Command.FIND_CHILD_ELEMENT, {"using": by, "value": value})["value"]def find_elements(self, by=By.ID, value=None) -> List[WebElement]:"""Find elements given a By strategy and locator.:Usage:::element = element.find_elements(By.CLASS_NAME, 'foo'):rtype: list of WebElement"""if by == By.ID:by = By.CSS_SELECTORvalue = f'[id="{value}"]'elif by == By.CLASS_NAME:by = By.CSS_SELECTORvalue = f".{value}"elif by == By.NAME:by = By.CSS_SELECTORvalue = f'[name="{value}"]'return self._execute(Command.FIND_CHILD_ELEMENTS, {"using": by, "value": value})["value"]def __hash__(self) -> int:return int(md5_hash(self._id.encode("utf-8")).hexdigest(), 16)def _upload(self, filename):fp = BytesIO()zipped = zipfile.ZipFile(fp, "w", zipfile.ZIP_DEFLATED)zipped.write(filename, os.path.split(filename)[1])zipped.close()content = encodebytes(fp.getvalue())if not isinstance(content, str):content = content.decode("utf-8")try:return self._execute(Command.UPLOAD_FILE, {"file": content})["value"]except WebDriverException as e:if "Unrecognized command: POST" in str(e):return filenameif "Command not found: POST " in str(e):return filenameif '{"status":405,"value":["GET","HEAD","DELETE"]}' in str(e):return filenameraise

----------------------- 

这段代码主要是使用 Python 中的 Selenium WebDriver 库来实现网页交互操作,通过封装常见的用户操作,如点击、鼠标移动、键盘输入等。其中 ActionChains 类可以实现更复杂的用户操作,如移动到元素、点击元素、双击、拖放等。用户可以通过调用不同的方法来模拟在页面上进行各种操作,并通过 perform() 方法执行这些操作。这段代码为进行页面交互操作提供了一个基础框架,可根据具体需求进行扩展和定制。
ActionChains 类涉及到的主要方法和属性如下:
move_to_element(element):将鼠标移动到指定元素上。
click():模拟鼠标左键点击操作。
context_click():模拟鼠标右键点击操作。
double_click():模拟鼠标双击操作。
drag_and_drop(source, target):模拟拖放操作,从源元素拖动到目标元素。
key_down(key):按下指定的键。
key_up(key):释放指定的键。
send_keys(keys):向页面元素发送按键输入。
perform():执行所有排队的操作。
属性:
actions:用于存储需要执行的操作序列。
这些方法和属性可以帮助用户实现各种复杂的页面交互操作,包括鼠标操作、键盘输入等。通过组合调用这些方法,可以模拟用户在页面上的各种操作行为。


"""The ActionChains implementation."""
from __future__ import annotationsfrom typing import TYPE_CHECKING
from typing import Unionfrom selenium.webdriver.remote.webelement import WebElementfrom .actions.action_builder import ActionBuilder
from .actions.key_input import KeyInput
from .actions.pointer_input import PointerInput
from .actions.wheel_input import ScrollOrigin
from .actions.wheel_input import WheelInput
from .utils import keys_to_typingif TYPE_CHECKING:from selenium.webdriver.remote.webdriver import WebDriverAnyDevice = Union[PointerInput, KeyInput, WheelInput]class ActionChains:"""ActionChains are a way to automate low level interactions such as mousemovements, mouse button actions, key press, and context menu interactions.This is useful for doing more complex actions like hover over and drag anddrop.Generate user actions.When you call methods for actions on the ActionChains object,the actions are stored in a queue in the ActionChains object.When you call perform(), the events are fired in the order theyare queued up.ActionChains can be used in a chain pattern::menu = driver.find_element(By.CSS_SELECTOR, ".nav")hidden_submenu = driver.find_element(By.CSS_SELECTOR, ".nav #submenu1")ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()Or actions can be queued up one by one, then performed.::menu = driver.find_element(By.CSS_SELECTOR, ".nav")hidden_submenu = driver.find_element(By.CSS_SELECTOR, ".nav #submenu1")actions = ActionChains(driver)actions.move_to_element(menu)actions.click(hidden_submenu)actions.perform()Either way, the actions are performed in the order they are called, one afteranother."""def __init__(self, driver: WebDriver, duration: int = 250, devices: list[AnyDevice] | None = None) -> None:"""Creates a new ActionChains.:Args:- driver: The WebDriver instance which performs user actions.- duration: override the default 250 msecs of DEFAULT_MOVE_DURATION in PointerInput"""self._driver = drivermouse = Nonekeyboard = Nonewheel = Noneif devices is not None and isinstance(devices, list):for device in devices:if isinstance(device, PointerInput):mouse = deviceif isinstance(device, KeyInput):keyboard = deviceif isinstance(device, WheelInput):wheel = deviceself.w3c_actions = ActionBuilder(driver, mouse=mouse, keyboard=keyboard, wheel=wheel, duration=duration)def perform(self) -> None:"""Performs all stored actions."""self.w3c_actions.perform()def reset_actions(self) -> None:"""Clears actions that are already stored locally and on the remoteend."""self.w3c_actions.clear_actions()for device in self.w3c_actions.devices:device.clear_actions()def click(self, on_element: WebElement | None = None) -> ActionChains:"""Clicks an element.:Args:- on_element: The element to click.If None, clicks on current mouse position."""if on_element:self.move_to_element(on_element)self.w3c_actions.pointer_action.click()self.w3c_actions.key_action.pause()self.w3c_actions.key_action.pause()return selfdef click_and_hold(self, on_element: WebElement | None = None) -> ActionChains:"""Holds down the left mouse button on an element.:Args:- on_element: The element to mouse down.If None, clicks on current mouse position."""if on_element:self.move_to_element(on_element)self.w3c_actions.pointer_action.click_and_hold()self.w3c_actions.key_action.pause()return selfdef context_click(self, on_element: WebElement | None = None) -> ActionChains:"""Performs a context-click (right click) on an element.:Args:- on_element: The element to context-click.If None, clicks on current mouse position."""if on_element:self.move_to_element(on_element)self.w3c_actions.pointer_action.context_click()self.w3c_actions.key_action.pause()self.w3c_actions.key_action.pause()return selfdef double_click(self, on_element: WebElement | None = None) -> ActionChains:"""Double-clicks an element.:Args:- on_element: The element to double-click.If None, clicks on current mouse position."""if on_element:self.move_to_element(on_element)self.w3c_actions.pointer_action.double_click()for _ in range(4):self.w3c_actions.key_action.pause()return selfdef drag_and_drop(self, source: WebElement, target: WebElement) -> ActionChains:"""Holds down the left mouse button on the source element, then movesto the target element and releases the mouse button.:Args:- source: The element to mouse down.- target: The element to mouse up."""self.click_and_hold(source)self.release(target)return selfdef drag_and_drop_by_offset(self, source: WebElement, xoffset: int, yoffset: int) -> ActionChains:"""Holds down the left mouse button on the source element, then movesto the target offset and releases the mouse button.:Args:- source: The element to mouse down.- xoffset: X offset to move to.- yoffset: Y offset to move to."""self.click_and_hold(source)self.move_by_offset(xoffset, yoffset)self.release()return selfdef key_down(self, value: str, element: WebElement | None = None) -> ActionChains:"""Sends a key press only, without releasing it. Should only be usedwith modifier keys (Control, Alt and Shift).:Args:- value: The modifier key to send. Values are defined in `Keys` class.- element: The element to send keys.If None, sends a key to current focused element.Example, pressing ctrl+c::ActionChains(driver).key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()"""if element:self.click(element)self.w3c_actions.key_action.key_down(value)self.w3c_actions.pointer_action.pause()return selfdef key_up(self, value: str, element: WebElement | None = None) -> ActionChains:"""Releases a modifier key.:Args:- value: The modifier key to send. Values are defined in Keys class.- element: The element to send keys.If None, sends a key to current focused element.Example, pressing ctrl+c::ActionChains(driver).key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()"""if element:self.click(element)self.w3c_actions.key_action.key_up(value)self.w3c_actions.pointer_action.pause()return selfdef move_by_offset(self, xoffset: int, yoffset: int) -> ActionChains:"""Moving the mouse to an offset from current mouse position.:Args:- xoffset: X offset to move to, as a positive or negative integer.- yoffset: Y offset to move to, as a positive or negative integer."""self.w3c_actions.pointer_action.move_by(xoffset, yoffset)self.w3c_actions.key_action.pause()return selfdef move_to_element(self, to_element: WebElement) -> ActionChains:"""Moving the mouse to the middle of an element.:Args:- to_element: The WebElement to move to."""self.w3c_actions.pointer_action.move_to(to_element)self.w3c_actions.key_action.pause()return selfdef move_to_element_with_offset(self, to_element: WebElement, xoffset: int, yoffset: int) -> ActionChains:"""Move the mouse by an offset of the specified element. Offsets arerelative to the in-view center point of the element.:Args:- to_element: The WebElement to move to.- xoffset: X offset to move to, as a positive or negative integer.- yoffset: Y offset to move to, as a positive or negative integer."""self.w3c_actions.pointer_action.move_to(to_element, int(xoffset), int(yoffset))self.w3c_actions.key_action.pause()return selfdef pause(self, seconds: float | int) -> ActionChains:"""Pause all inputs for the specified duration in seconds."""self.w3c_actions.pointer_action.pause(seconds)self.w3c_actions.key_action.pause(seconds)return selfdef release(self, on_element: WebElement | None = None) -> ActionChains:"""Releasing a held mouse button on an element.:Args:- on_element: The element to mouse up.If None, releases on current mouse position."""if on_element:self.move_to_element(on_element)self.w3c_actions.pointer_action.release()self.w3c_actions.key_action.pause()return selfdef send_keys(self, *keys_to_send: str) -> ActionChains:"""Sends keys to current focused element.:Args:- keys_to_send: The keys to send.  Modifier keys constants can be found in the'Keys' class."""typing = keys_to_typing(keys_to_send)for key in typing:self.key_down(key)self.key_up(key)return selfdef send_keys_to_element(self, element: WebElement, *keys_to_send: str) -> ActionChains:"""Sends keys to an element.:Args:- element: The element to send keys.- keys_to_send: The keys to send.  Modifier keys constants can be found in the'Keys' class."""self.click(element)self.send_keys(*keys_to_send)return selfdef scroll_to_element(self, element: WebElement) -> ActionChains:"""If the element is outside the viewport, scrolls the bottom of theelement to the bottom of the viewport.:Args:- element: Which element to scroll into the viewport."""self.w3c_actions.wheel_action.scroll(origin=element)return selfdef scroll_by_amount(self, delta_x: int, delta_y: int) -> ActionChains:"""Scrolls by provided amounts with the origin in the top left cornerof the viewport.:Args:- delta_x: Distance along X axis to scroll using the wheel. A negative value scrolls left.- delta_y: Distance along Y axis to scroll using the wheel. A negative value scrolls up."""self.w3c_actions.wheel_action.scroll(delta_x=delta_x, delta_y=delta_y)return selfdef scroll_from_origin(self, scroll_origin: ScrollOrigin, delta_x: int, delta_y: int) -> ActionChains:"""Scrolls by provided amount based on a provided origin. The scrollorigin is either the center of an element or the upper left of theviewport plus any offsets. If the origin is an element, and the elementis not in the viewport, the bottom of the element will first bescrolled to the bottom of the viewport.:Args:- origin: Where scroll originates (viewport or element center) plus provided offsets.- delta_x: Distance along X axis to scroll using the wheel. A negative value scrolls left.- delta_y: Distance along Y axis to scroll using the wheel. A negative value scrolls up.:Raises: If the origin with offset is outside the viewport.- MoveTargetOutOfBoundsException - If the origin with offset is outside the viewport."""if not isinstance(scroll_origin, ScrollOrigin):raise TypeError(f"Expected object of type ScrollOrigin, got: {type(scroll_origin)}")self.w3c_actions.wheel_action.scroll(origin=scroll_origin.origin,x=scroll_origin.x_offset,y=scroll_origin.y_offset,delta_x=delta_x,delta_y=delta_y,)return self# Context manager so ActionChains can be used in a 'with .. as' statements.def __enter__(self) -> ActionChains:return self  # Return created instance of self.def __exit__(self, _type, _value, _traceback) -> None:pass  # Do nothing, does not require additional cleanup.

-----------------------

这是一段 Python 代码,它定义了一些用于 WebDriver 测试的“预期条件”(Expected Conditions)。预期条件是一种在测试中使用的断言,用于检查页面或元素的状态是否符合预期。
这段代码中定义了许多常用的预期条件函数,如检查页面标题、检查元素是否可见、检查元素是否存在、检查元素是否包含文本等。你可以根据需要选择并使用这些预期条件函数来辅助你的测试。
这段代码还使用了 Selenium 提供的异常类,如 NoAlertPresentException、NoSuchElementException 等,用于处理在测试过程中可能出现的异常情况。
总之,这段代码提供了一些方便的方法来进行基于 WebDriver 的测试,并对页面和元素的状态进行验证。你可以根据自己的需求和场景使用这些预期条件函数。
这段代码涉及了一些 Selenium WebDriver 测试中常用的预期条件方法和属性,主要包括以下内容:
Expected Conditions 方法:
title_is(title):检查页面标题是否等于给定的标题。
title_contains(title):检查页面标题是否包含给定的字符串。
presence_of_element_located(locator):检查是否存在满足定位器条件的元素。
visibility_of_element_located(locator):检查满足定位器条件的元素是否可见。
visibility_of(element):检查元素是否可见。
text_to_be_present_in_element(element, text_):检查元素是否包含指定文本。
element_to_be_clickable(locator):检查元素是否可点击。
Selenium 异常类:
NoSuchElementException:当找不到元素时抛出此异常。
TimeoutException:超时异常,用于处理等待超时的情况。
NoAlertPresentException:当尝试操作不存在的警报时抛出。
这些方法和属性能够帮助测试人员编写更健壮和可靠的测试脚本,用于验证页面和元素的状态是否符合预期。通过结合预期条件和异常处理,可以提高测试的稳定性和准确性。

import re
from collections.abc import Iterable
from typing import Any
from typing import Callable
from typing import List
from typing import Literal
from typing import Tuple
from typing import TypeVar
from typing import Unionfrom selenium.common.exceptions import NoAlertPresentException
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoSuchFrameException
from selenium.common.exceptions import StaleElementReferenceException
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.remote.webdriver import WebElement"""* Canned "Expected Conditions" which are generally useful within webdriver* tests.
"""D = TypeVar("D")
T = TypeVar("T")WebDriverOrWebElement = Union[WebDriver, WebElement]def title_is(title: str) -> Callable[[WebDriver], bool]:"""An expectation for checking the title of a page.title is the expected title, which must be an exact match returnsTrue if the title matches, false otherwise."""def _predicate(driver: WebDriver):return driver.title == titlereturn _predicatedef title_contains(title: str) -> Callable[[WebDriver], bool]:"""An expectation for checking that the title contains a case-sensitivesubstring.title is the fragment of title expected returns True when the titlematches, False otherwise"""def _predicate(driver: WebDriver):return title in driver.titlereturn _predicatedef presence_of_element_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], WebElement]:"""An expectation for checking that an element is present on the DOM of apage. This does not necessarily mean that the element is visible.locator - used to find the elementreturns the WebElement once it is located"""def _predicate(driver: WebDriverOrWebElement):return driver.find_element(*locator)return _predicatedef url_contains(url: str) -> Callable[[WebDriver], bool]:"""An expectation for checking that the current url contains a case-sensitive substring.url is the fragment of url expected, returns True when the urlmatches, False otherwise"""def _predicate(driver: WebDriver):return url in driver.current_urlreturn _predicatedef url_matches(pattern: str) -> Callable[[WebDriver], bool]:"""An expectation for checking the current url.pattern is the expected pattern.  This finds the first occurrence ofpattern in the current url and as such does not require an exactfull match."""def _predicate(driver: WebDriver):return re.search(pattern, driver.current_url) is not Nonereturn _predicatedef url_to_be(url: str) -> Callable[[WebDriver], bool]:"""An expectation for checking the current url.url is the expected url, which must be an exact match returns Trueif the url matches, false otherwise."""def _predicate(driver: WebDriver):return url == driver.current_urlreturn _predicatedef url_changes(url: str) -> Callable[[WebDriver], bool]:"""An expectation for checking the current url.url is the expected url, which must not be an exact match returnsTrue if the url is different, false otherwise."""def _predicate(driver: WebDriver):return url != driver.current_urlreturn _predicatedef visibility_of_element_located(locator: Tuple[str, str]
) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]:"""An expectation for checking that an element is present on the DOM of apage and visible. Visibility means that the element is not only displayedbut also has a height and width that is greater than 0.locator - used to find the elementreturns the WebElement once it is located and visible"""def _predicate(driver: WebDriverOrWebElement):try:return _element_if_visible(driver.find_element(*locator))except StaleElementReferenceException:return Falsereturn _predicatedef visibility_of(element: WebElement) -> Callable[[Any], Union[Literal[False], WebElement]]:"""An expectation for checking that an element, known to be present on theDOM of a page, is visible.Visibility means that the element is not only displayed but also hasa height and width that is greater than 0. element is the WebElementreturns the (same) WebElement once it is visible"""def _predicate(_):return _element_if_visible(element)return _predicatedef _element_if_visible(element: WebElement, visibility: bool = True) -> Union[Literal[False], WebElement]:return element if element.is_displayed() == visibility else Falsedef presence_of_all_elements_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], List[WebElement]]:"""An expectation for checking that there is at least one element presenton a web page.locator is used to find the element returns the list of WebElementsonce they are located"""def _predicate(driver: WebDriverOrWebElement):return driver.find_elements(*locator)return _predicatedef visibility_of_any_elements_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], List[WebElement]]:"""An expectation for checking that there is at least one element visibleon a web page.locator is used to find the element returns the list of WebElementsonce they are located"""def _predicate(driver: WebDriverOrWebElement):return [element for element in driver.find_elements(*locator) if _element_if_visible(element)]return _predicatedef visibility_of_all_elements_located(locator: Tuple[str, str]
) -> Callable[[WebDriverOrWebElement], Union[List[WebElement], Literal[False]]]:"""An expectation for checking that all elements are present on the DOM ofa page and visible. Visibility means that the elements are not onlydisplayed but also has a height and width that is greater than 0.locator - used to find the elementsreturns the list of WebElements once they are located and visible"""def _predicate(driver: WebDriverOrWebElement):try:elements = driver.find_elements(*locator)for element in elements:if _element_if_visible(element, visibility=False):return Falsereturn elementsexcept StaleElementReferenceException:return Falsereturn _predicatedef text_to_be_present_in_element(locator: Tuple[str, str], text_: str) -> Callable[[WebDriverOrWebElement], bool]:"""An expectation for checking if the given text is present in thespecified element.locator, text"""def _predicate(driver: WebDriverOrWebElement):try:element_text = driver.find_element(*locator).textreturn text_ in element_textexcept StaleElementReferenceException:return Falsereturn _predicatedef text_to_be_present_in_element_value(locator: Tuple[str, str], text_: str
) -> Callable[[WebDriverOrWebElement], bool]:"""An expectation for checking if the given text is present in theelement's value.locator, text"""def _predicate(driver: WebDriverOrWebElement):try:element_text = driver.find_element(*locator).get_attribute("value")return text_ in element_textexcept StaleElementReferenceException:return Falsereturn _predicatedef text_to_be_present_in_element_attribute(locator: Tuple[str, str], attribute_: str, text_: str
) -> Callable[[WebDriverOrWebElement], bool]:"""An expectation for checking if the given text is present in theelement's attribute.locator, attribute, text"""def _predicate(driver: WebDriverOrWebElement):try:element_text = driver.find_element(*locator).get_attribute(attribute_)if element_text is None:return Falsereturn text_ in element_textexcept StaleElementReferenceException:return Falsereturn _predicatedef frame_to_be_available_and_switch_to_it(locator: Union[Tuple[str, str], str]) -> Callable[[WebDriver], bool]:"""An expectation for checking whether the given frame is available toswitch to.If the frame is available it switches the given driver to thespecified frame."""def _predicate(driver: WebDriver):try:if isinstance(locator, Iterable) and not isinstance(locator, str):driver.switch_to.frame(driver.find_element(*locator))else:driver.switch_to.frame(locator)return Trueexcept NoSuchFrameException:return Falsereturn _predicatedef invisibility_of_element_located(locator: Union[WebElement, Tuple[str, str]]
) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]:"""An Expectation for checking that an element is either invisible or notpresent on the DOM.locator used to find the element"""def _predicate(driver: WebDriverOrWebElement):try:target = locatorif not isinstance(target, WebElement):target = driver.find_element(*target)return _element_if_visible(target, visibility=False)except (NoSuchElementException, StaleElementReferenceException):# In the case of NoSuchElement, returns true because the element is# not present in DOM. The try block checks if the element is present# but is invisible.# In the case of StaleElementReference, returns true because stale# element reference implies that element is no longer visible.return Truereturn _predicatedef invisibility_of_element(element: Union[WebElement, Tuple[str, str]]
) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]:"""An Expectation for checking that an element is either invisible or notpresent on the DOM.element is either a locator (text) or an WebElement"""return invisibility_of_element_located(element)def element_to_be_clickable(mark: Union[WebElement, Tuple[str, str]]
) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]:"""An Expectation for checking an element is visible and enabled such thatyou can click it.element is either a locator (text) or an WebElement"""# renamed argument to 'mark', to indicate that both locator# and WebElement args are validdef _predicate(driver: WebDriverOrWebElement):target = markif not isinstance(target, WebElement):  # if given locator instead of WebElementtarget = driver.find_element(*target)  # grab element at locatorelement = visibility_of(target)(driver)if element and element.is_enabled():return elementreturn Falsereturn _predicatedef staleness_of(element: WebElement) -> Callable[[Any], bool]:"""Wait until an element is no longer attached to the DOM.element is the element to wait for. returns False if the element isstill attached to the DOM, true otherwise."""def _predicate(_):try:# Calling any method forces a staleness checkelement.is_enabled()return Falseexcept StaleElementReferenceException:return Truereturn _predicatedef element_to_be_selected(element: WebElement) -> Callable[[Any], bool]:"""An expectation for checking the selection is selected.element is WebElement object"""def _predicate(_):return element.is_selected()return _predicatedef element_located_to_be_selected(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], bool]:"""An expectation for the element to be located is selected.locator is a tuple of (by, path)"""def _predicate(driver: WebDriverOrWebElement):return driver.find_element(*locator).is_selected()return _predicatedef element_selection_state_to_be(element: WebElement, is_selected: bool) -> Callable[[Any], bool]:"""An expectation for checking if the given element is selected.element is WebElement object is_selected is a Boolean."""def _predicate(_):return element.is_selected() == is_selectedreturn _predicatedef element_located_selection_state_to_be(locator: Tuple[str, str], is_selected: bool
) -> Callable[[WebDriverOrWebElement], bool]:"""An expectation to locate an element and check if the selection statespecified is in that state.locator is a tuple of (by, path) is_selected is a boolean"""def _predicate(driver: WebDriverOrWebElement):try:element = driver.find_element(*locator)return element.is_selected() == is_selectedexcept StaleElementReferenceException:return Falsereturn _predicatedef number_of_windows_to_be(num_windows: int) -> Callable[[WebDriver], bool]:"""An expectation for the number of windows to be a certain value."""def _predicate(driver: WebDriver):return len(driver.window_handles) == num_windowsreturn _predicatedef new_window_is_opened(current_handles: List[str]) -> Callable[[WebDriver], bool]:"""An expectation that a new window will be opened and have the number ofwindows handles increase."""def _predicate(driver: WebDriver):return len(driver.window_handles) > len(current_handles)return _predicatedef alert_is_present() -> Callable[[WebDriver], Union[Alert, Literal[False]]]:"""An expectation for checking if an alert is currently present andswitching to it."""def _predicate(driver: WebDriver):try:return driver.switch_to.alertexcept NoAlertPresentException:return Falsereturn _predicatedef element_attribute_to_include(locator: Tuple[str, str], attribute_: str) -> Callable[[WebDriverOrWebElement], bool]:"""An expectation for checking if the given attribute is included in thespecified element.locator, attribute"""def _predicate(driver: WebDriverOrWebElement):try:element_attribute = driver.find_element(*locator).get_attribute(attribute_)return element_attribute is not Noneexcept StaleElementReferenceException:return Falsereturn _predicatedef any_of(*expected_conditions: Callable[[D], T]) -> Callable[[D], Union[Literal[False], T]]:"""An expectation that any of multiple expected conditions is true.Equivalent to a logical 'OR'. Returns results of the first matchingcondition, or False if none do."""def any_of_condition(driver: D):for expected_condition in expected_conditions:try:result = expected_condition(driver)if result:return resultexcept WebDriverException:passreturn Falsereturn any_of_conditiondef all_of(*expected_conditions: Callable[[D], Union[T, Literal[False]]]
) -> Callable[[D], Union[List[T], Literal[False]]]:"""An expectation that all of multiple expected conditions is true.Equivalent to a logical 'AND'.Returns: When any ExpectedCondition is not met: False.When all ExpectedConditions are met: A List with each ExpectedCondition's return value."""def all_of_condition(driver: D):results: List[T] = []for expected_condition in expected_conditions:try:result = expected_condition(driver)if not result:return Falseresults.append(result)except WebDriverException:return Falsereturn resultsreturn all_of_conditiondef none_of(*expected_conditions: Callable[[D], Any]) -> Callable[[D], bool]:"""An expectation that none of 1 or multiple expected conditions is true.Equivalent to a logical 'NOT-OR'. Returns a Boolean"""def none_of_condition(driver: D):for expected_condition in expected_conditions:try:result = expected_condition(driver)if result:return Falseexcept WebDriverException:passreturn Truereturn none_of_condition

相关文章:

Selenium库原代码WebDriver及WebElement方法属性总结

简单示例&#xff1a; from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as ECdriver webdriver.Chrome()try:driver.ge…...

C# 部署ICE框架以及用例(VS2019)

使用Windows 10环境&#xff0c;VS2019进行ICE用例开发 用例结构&#xff1a;客户端和服务端 关键技术&#xff1a;集成ICE环境&#xff0c;可以创建ice文件并自动生成对应的cs文件 1.环境安装 ICE Build插件安装。安装以后&#xff0c;就可以在项目中插入ice文件 2.代码实…...

PostgreSQL 数据加密怎么弄,应该用哪种方案

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;&#xff08;…...

1.通过AD组策略如何做封禁高危端口的策略?AD域控如何给加域的电脑做指定端口号封禁呢?

目录 (1)高危端口简介 1. 高危端口TCP和UDP类型 2.为什么要做AD组策略封禁加域计算机的一些高危的端口?好处是什么? (2)实战步骤过程 实验环境 第一步:新建计算机策略-编辑 第二步:将策略应用到OU...

05.BOM对象

一、js组成 JavaScript的组成 ECMAScript: 规定了js基础语法核心知识。比如&#xff1a;变量、分支语句、循环语句、对象等等 Web APIs : DOM 文档对象模型&#xff0c; 定义了一套操作HTML文档的APIBOM 浏览器对象模型&#xff0c;定义了一套操作浏览器窗口的API 二、windo…...

【Golang星辰图】Go语言游戏开发:选择合适的库加速你的开发过程

打造出色的游戏体验&#xff1a;使用Go库进行游戏和图形开发 前言 Go语言通过其简洁、高效和并发性的特性&#xff0c;逐渐在开发领域中崭露头角。对于游戏和图形开发&#xff0c;Go也有一些优秀的库和引擎可供选择。本文将介绍几个流行的Go库&#xff0c;包括ebiten、raylib…...

51单片机-AT24C02(I2C总线)

目录 一&#xff0c;介绍及元件工作原理 7.时序结构&#xff08;重要&#xff09; 8.i2C总线数据帧&#xff08;重要&#xff09; 二&#xff0c;应用 一&#xff0c;介绍及元件工作原理 1.元件介绍 2.存储器 3.地址总线和数据总线 地址总线只能一次选中一行 4.引脚及应用…...

面试经典-MySQL篇

一、MySQL组成 MySQL数据库的连接池&#xff1a;由一个线程来监听一个连接上请求以及读取请求数据&#xff0c;解析出来一条我们发送过去的SQL语句SQL接口&#xff1a;负责处理接收到的SQL语句查询解析器&#xff1a;让MySQL能看懂SQL语句查询优化器&#xff1a;选择最优的查询…...

C#控制台贪吃蛇

Console.Write("");// 第一次生成食物位置 // 随机生成一个食物的位置 // 食物生成完成后判断食物生成的位置与现在的蛇的身体或者障碍物有冲突 // 食物的位置与蛇的身体或者障碍物冲突了&#xff0c;那么一直重新生成食物&#xff0c;直到生成不冲突…...

[小程序开发] 构造页面

一、Component方法 Component方法用于创建自定义组件&#xff0c;小程序页面也可以使用Component方法进行创建&#xff0c;从而实现复杂的页面逻辑开发。 使用Component方法构造页面&#xff0c;可以实现更加复杂的页面逻辑开发。 二、注意事项 1、要求.json文件中必须包含usi…...

安装Android Studio遇到Unable to access Android SDK add-on list的错误

第一次安装android studio的时候&#xff0c;提示&#xff1a;unable to access Android sdk add-on list 解决办法 这个错误一般是android studoi代理没有设置导致的&#xff0c;需要在setting里面设置&#xff1a; 点击Android Studio - Preferences&#xff0c;在 Appeara…...

EXCEL+PYTHON学习3

1&#xff09; 遍历一个SHEET&#xff0c;无非就是两个循环&#xff0c;rows属性是取得所有行。 fn data3_16.xlsx wb openpyxl.load_workbook(fn) ws wb.active for row in ws.rows:for cell in row:print(cell.value, end )print() 2&#xff09; 返回工作表的最小行数…...

Rabbit MQ详解

写在前面,由于Rabbit MQ涉及的内容较多&#xff0c;赶在春招我个人先按照我认为重要的内容进行一定总结&#xff0c;也算是个学习笔记吧。主要参考官方文档、其他优秀文章、大模型问答。自己边学习边总结。后面有时间我会慢慢把所有内容补全&#xff0c;分享出来也是希望可以给…...

uniapp 写安卓app,运行到手机端 调试

手机 设置》关于手机》点击版本号 4-5次&#xff0c;弹出手机锁屏页面&#xff0c;输入手机锁屏密码 2.手机 设置中 》搜索 开发人员选项 》 调试》打开USB调试 同页面 找到 选择USB配置》选择 MIDIhbuilder 编辑器 点击 》运行》运行到手机或模拟器》运行到Android App基座 》…...

uniapp 实现双击点赞出现特效

更新一下 老板改了需求要加上特效 1. 创建点赞按钮 首先&#xff0c;在你的页面中创建一个点赞按钮 全局点赞的话就写在最外面的标签就行了。你可以使用 <button> 组件或者自定义一个视图组件。 <template> <view class"container"> <but…...

分布式搜索引擎elasticsearch(2)

1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;[Domain Specific Language](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html)&#xff09;来定义查…...

如何实现一个栈或队列?

如何实现一个栈或队列&#xff1f; 栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;是两种常见的数据结构&#xff0c;它们在编程中经常被使用。下面我将分别解释如何使用Python来实现这两种数据结构。 1. 栈的实现 栈是一种后进先出&#xff08;LIF…...

STM32输入捕获频率和占空比proteus仿真失败

这次用了两天的时间来验证这个功能&#xff0c;虽然实验没有成功&#xff0c;但是也要记录一下&#xff0c;后面能解决了&#xff0c;回来再写上解决的办法&#xff1a; 这个程序最后的实验结果是读取到的CCR1和CCR2的值都是0&#xff0c;所以没有办法算出来频率和占空比。 还…...

Kafka-SSL笔记整理

创建密钥仓库以及CA 创建密匙仓库,用户存储证书文件keytool -keystore server.keystore.jks -alias hello_kafka -validity 100000 -genkey创建CAopenssl req -new -x509 -keyout ca-key -out ca-cert -days 100000将生成的CA添加到客户端信任库keytool -keystore client.trus…...

Mysql挂掉怎么办

思路 从库处理&#xff0c;relaylog&#xff0c;讲从库升级主库。 待主机恢复后&#xff0c;主机替换为从库。 具体操作 简介&#xff1a; 主库宕机 Master DOWN机-企业场景一主多从宕机从库切换主继续和从同步过程详解 登陆从库&#xff0c;show processlist; 查看两个线…...

《工厂模式(极简c++)》

本文章属于专栏《设计模式&#xff08;极简c版&#xff09;》 继续上一篇《设计原则》。本章简要说明工厂模式。本文分为模式说明、本质思想、实践建议、代码示例四个部分。 模式说明&#xff1a; 简单工厂模式 方案&#xff1a;对象不直接new&#xff0c;而是通过另一个类&am…...

前端学习笔记|JavaScript基础

JS基础 数据类型 基于动力节点视频。 Number、String、Boolean、object 强制转换 Number 强转,boolean强转(undefined、null、NaN都是转成false)&#xff0c;String强转 myAge Number("123445"); Boolean(0); String(123);parseInt、parseFloat 遇到非数字&…...

springcloud五大组件:Eureka:注册中心、Zuul:服务网关、Ribbon:负载均衡、Feign:服务调用、Hystix:熔断器

你提到的这些组件都是Spring Cloud生态系统中非常关键和常用的组件。但是&#xff0c;关于这些组件的命名&#xff0c;有一点需要更正&#xff1a; Eureka 应该是 Eureka 或者 Eureka Server&#xff1a;Eureka是Netflix开源的一个服务发现组件&#xff0c;它本身是一个基于RE…...

Python的Selenium库中的模块、类和异常的汇总

这些是 Selenium Python 库中的模块、类和异常&#xff0c;用于实现自动化 Web 浏览器测试和网页操作。以下是它们的简单解释&#xff1a;Python Module Index — Selenium 4.18.1 documentation 1. selenium.common.exceptions&#xff1a;包含了 Selenium 中可能出现的异常。…...

智慧交通:构建智慧城市的重要一环

随着信息技术的飞速发展&#xff0c;智慧城市已成为现代城市发展的重要方向。作为智慧城市的重要组成部分&#xff0c;智慧交通以其高效、便捷、环保的特性&#xff0c;成为推动城市现代化进程的关键力量。本文将从智慧交通的概念、发展现状、面临挑战以及未来趋势等方面&#…...

BFS 求解 最小高度树 【妙用】

310. 最小高度树 链接 &#xff1a;题目链接 思路 常规解法是树形dp&#xff0c;两个dfs解决&#xff0c;这里不再赘述新颖解法bfs&#xff0c;而且实现更加简单&#xff0c;大体思路就是每次都从叶子节点一步步往中心爬&#xff0c;最后一批留在队列中的节点就为本题意的答案…...

【机器学习300问】36、什么是集成学习?

一、什么是集成学习&#xff1f; &#xff08;1&#xff09;它的出现是为了解决什么问题&#xff1f; 提高准确性&#xff1a;单个模型可能对某些数据敏感或者有概念偏见&#xff0c;而集成多个模型可以提高预测的准确性。让模型变稳定&#xff1a;一些模型&#xff0c;如决策…...

Stargo 管理部署 Starrocks 集群

配置主机间 ssh 互信 ssh-copy-id hadoop02 ssh-copy-id hadoop03配置系统参数 ############################ Swap检查 ############################ echo 0 | sudo tee /proc/sys/vm/swappiness########################### 内核参数检查 ########################## echo…...

CI/CD实战-git工具使用 1

版本控制系统 本地版本控制系统 集中化的版本控制系统 分布式版本控制系统 git官网文档&#xff1a;https://git-scm.com/book/zh/v2 Git 有三种状态&#xff1a;已提交&#xff08;committed&#xff09;、已修改&#xff08;modified&#xff09; 和 已暂存&#xff08;sta…...

Linux中udp服务端,客户端的开发

UDP通信相关函数&#xff1a; ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); 函数说明&#xff1a;接收信息 参数说明&#xff1a;sockfd:套接字buf:要接收的缓冲区len:缓冲区…...