Selenium之Actions事件

鼠标、键盘组合键

在使用selenium的时候,有的时候我们需要鼠标单击、双击、拖动;或者是按下键盘的某个键,松开某个按键,以及组合键的使用;今天我们就来看一看,怎么样实现上面的操作

先把准备工作做好,需要导入ActionChains, Keys这两个模块

perform()作用就是,执行前面动作链的所有操作

from selenium import webdriver
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import Byserve_path = r'D:\Code_Study\driver\chromedriver-win64\chromedriver.exe'
service = Service(serve_path)
browser = webdriver.Chrome(service=service)
url = r"https://selenium.dev/selenium/web/single_text_input.html"
browser.get(url=url)

键盘Keyboard

按下按键key_down
# 可以看到输入框中输入的是大写单词
ActionChains(driver=browser).key_down(Keys.SHIFT).send_keys("selenium").perform()
释放按键key_up
松开按键key_up,可以看到先输入大写的HELLO,之后输入小写的world
ActionChains(driver=browser).key_down(Keys.SHIFT).send_keys("hello").key_up(Keys.SHIFT).send_keys("world").perform()
键入
  • 活跃元素send_keys

    # 可以看到打开网页的一瞬间, 就输入了内容;当然,还是先定位到元素,在对元素进行send_keys()的方法好用
    ActionChains(driver=browser).send_keys("selenium").perform()
    
  • 指定元素send_keys_to_element

    # 首先是定位到元素,在对元素进行内容输入
    text_input = browser.find_element(By.ID, "textInput")
    ActionChains(driver=browser).send_keys_to_element(text_input,"selenium").perform()
复制粘贴
# send_keys(Keys.ARROW_LEFT) - 按一次左箭头键,将光标移动到"Selenium"的最后一个字母'm'的后面
# key_down(Keys.SHIFT) - 按下Shift键(不松开)
# send_keys(Keys.ARROW_UP) - 在按住Shift的同时按上箭头键(通常用于向上选择文本)
# key_up(Keys.SHIFT) - 松开Shift键
# key_down(cmd_ctrl) - 按下Command键(Mac)或Control键(Windows)
# send_keys("xvv") - 在按住Command/Control键的同时输入:
# 'x' - 通常是剪切操作(Command+X/Ctrl+X)
# 'v' - 粘贴操作(Command+V/Ctrl+V)
# 第二个'v' - 再次粘贴
# key_up(cmd_ctrl) - 松开Command/Control键
cmd_ctrl = Keys.COMMAND if sys.platform == "darwin" else Keys.CONTROL
ActionChains(driver=browser).send_keys("Selenium")\.send_keys(Keys.ARROW_LEFT).key_down(Keys.SHIFT)\.send_keys(Keys.ARROW_UP).key_up(Keys.SHIFT)\.key_down(cmd_ctrl).send_keys("xvv").key_up(cmd_ctrl).perform()

鼠标Mouse

url = r"https://selenium.dev/selenium/web/single_text_input.html"
browser.get(url=url)
点击鼠标左键click
# 可以看到点击了一个链接,进入了一个新页面
clickable =browser.find_element(By.ID,"click")
ActionChains(driver=browser).click(clickable).perform()
按住鼠标左键click_and_hold
# 可以看到点击一下,右侧展示【focused】;
clickable = browser.find_element(By.ID,"clickable")
ActionChains(driver=browser).click_and_hold(clickable).perform()
双击左键double_click
# 点击二下右侧展示【double-clicked】
clickable = browser.find_element(By.ID,"clickable")
ActionChains(driver=browser).double_click(clickable).perform()
assert browser.find_element(By.ID, "click-status").text == "double-clicked"
点击鼠标右键context_click
# 可以看到点击右键的一些信息和平时手动右键出现的内容一模一样
clickable = browser.find_element(By.ID, "clickable")
ActionChains(driver=browser) \.context_click(clickable) \.perform()

鼠标对应按键数字

"""
使用 数字 代替 MouseButton.FORWARD:
0 = 左键(MouseButton.LEFT)
1 = 中键(MouseButton.MIDDLE)
2 = 右键(MouseButton.RIGHT)
3 = 前进侧键(MouseButton.FORWARD)
4 = 后退侧键(MouseButton.BACK)
"""
点击鼠标前进键MouseButton.FORWARD
# 可以看到鼠标点击链接跳转后,再后退以下;然后会前进一步
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.devtools.v132.input_ import MouseButton# 点击click后,链接的title为We Arrive Here
browser.find_element(By.ID,"click").click()
time.sleep(3)
browser.back()
print(browser.title)
assert browser.title == "BasicMouseInterfaceTest"# ActionBuilder 是 Selenium 提供的一个底层动作构造器,用于构建复杂的输入设备(如鼠标、键盘、触摸屏等)操作。
这里初始化了一个 ActionBuilder 对象,绑定到当前的浏览器实例 browser。
# pointer_action表示鼠标指针操作
# pointer_down、pointer_up表示按下、释放;往往成对出现
# action = ActionBuilder(driver=browser)
# 这里我的鼠标对应的4,才是前进键;其他的可以各位私下尝试
# 因为使用方法会报错,这里用了数字可以使用
action.pointer_action.pointer_down(4)
action.pointer_action.pointer_up(4)
action.perform()
print(browser.title)
assert browser.title == "We Arrive Here"
点击鼠标回退键MouseButton.BACK
browser.find_element(By.ID, "click").click()
assert browser.title == "We Arrive Here"
print(browser.title)# ActionBuilder 是 Selenium 提供的一个底层动作构造器,用于构建复杂的输入设备(如鼠标、键盘、触摸屏等)操作。
这里初始化了一个 ActionBuilder 对象,绑定到当前的浏览器实例 browser。
# pointer_action表示鼠标指针操作
# pointer_down、pointer_up表示按下、释放;往往成对出现action = ActionBuilder(browser)# 这里我的鼠标对应的3,才是前进键;其他的可以各位私下尝试
# 因为使用方法会报错,这里用了数字可以使用
action.pointer_action.pointer_down(3)
action.pointer_action.pointer_up(3)
action.perform()
print(browser.title)
assert browser.title == "BasicMouseInterfaceTest"
移动光标到元素上move_to_element
# 可以看到鼠标移动过去,右侧展示文字
hoverable = browser.find_element(By.ID, "hover")
ActionChains(driver=browser).move_to_element(hoverable).perform()
通过偏移量移动光标
  • 先移动到指定的坐标原点

  • 通过px单位的偏移量进行光标相对原点的偏移移动

  • 光标位置必须在可视化窗口区域,否则报错

从元素中心点【原点】偏移move_to_element_with_offset

先将光标移动到元素中心点(原点),然后通过偏移量进行光标相对原点的偏移。

move_to_element_with_offset接受三个参数,可以查看源码
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 self
# 先定位到元素
mouse_tracker = browser.find_element(By.ID, "mouse-tracker")
# 先移动到元素,默认就是中心点
ActionChains(driver=browser).move_to_element(mouse_tracker).click().perform()
time.sleep(5)
# x轴增加了8个px,y轴不动
ActionChains(driver=browser).move_to_element_with_offset(mouse_tracker, 8, 0).perform()
# 获取Relative Location in Box:内容
coordinates = browser.find_element(By.ID, "relative-location").text.split(",")
assert abs(int(coordinates[0]) - 100 - 8) < 2
从左上角偏移move_to_location

先将光标移动到窗口左上角原点,然后通过偏移量进行偏移

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ECWebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
action = ActionBuilder(browser)
action.pointer_action.move_to_location(8, 0)
action.perform()
coordinates = browser.find_element(By.ID, "absolute-location").text.split(", ")
assert abs(int(coordinates[0]) - 8) < 2
从当前光标位置偏移move_by_offset

光标位于当前位置的,通过偏移量进行偏移;如果之前没有移动过光标,则位置是窗口左上角;

页面发生滚动后,光标位置不会发生变化

查看源码,发现第一个参数指定为正数往右移动;第二个参数指定正数往下移动

 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()
action = ActionBuilder(browser)
# 先右移动6px;下移动3px
action.pointer_action.move_to_location(6, 3)
action.perform()
ActionChains(browser).move_by_offset(13,15).perform()
拖放元素drag_and_drop

在原元素上提交执行按下鼠标左键,移动到目标元素位置后是释放鼠标左键。

查看源码,第一个是需要移动的元素,第二个是要移动到哪里的元素,释放鼠标

    def 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 self
draggable = browser.find_element(By.ID, "draggable")
droppable = browser.find_element(By.ID, "droppable")
ActionChains(browser).drag_and_drop(draggable, droppable).perform()
time.sleep(5)
assert browser.find_element(By.ID, "drop-status").text == "dropped"
通过偏移量拖放元素drag_and_drop_by_offset

查看源码,发现需要一个开始元素的element;和需要移动x、y的偏移量

    def 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 self

首先计算需要拖动的元素的location,之后计算出要释放鼠标的元素的location;之后后者的x轴,y轴分别减去前者的x、y坐标;就是需要移动的x、y坐标的偏移量

draggable = browser.find_element(By.ID, "draggable")
start = draggable.location
finish = browser.find_element(By.ID, "droppable").location
ActionChains(browser)\.drag_and_drop_by_offset(draggable,finish["x"] - start["x"],finish["y"] - start["y"]).perform()assert browser.find_element(By.ID, "drop-status").text == "dropped"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 CentOS 7 系统上以容器方式部署 GitLab,使用 ZeroNews 通过互联网访问 GitLab 私有仓库,进行代码版本发布与更新

第 1 步&#xff1a; 部署 GitLab 容器​ 在开始部署 GitLab 容器之前&#xff0c;您需要创建本地目录来存储 GitLab 数据、配置和日志&#xff1a; #创建本地目录 mkdir -p /opt/docker/gitlab/data mkdir -p /opt/docker/gitlab/config mkdir -p /opt/docker/gitlab/log#gi…

.py文件和.ipynb文件的区别:完整教程

一、概述 Python开发者常用的两种文件格式.py和.ipynb各有特点&#xff0c;本教程将通过对比分析、代码示例和场景说明&#xff0c;帮助开发者全面理解二者的区别与联系。 二、核心区别对比 1. 文件格式本质 特性.ipynb文件.py文件文件类型JSON结构化文档纯文本文件存储内容…

Go 字符串四种拼接方式的性能对比

简介 使用完整的基准测试代码文件&#xff0c;可以直接运行来比较四种字符串拼接方法的性能。 for 索引 的方式 for range 的方式 strings.Join 的方式 strings.Builder 的方式 写一个基准测试文件 echo_bench_test.go package mainimport ("os""stri…

从代码学习深度学习 - Bahdanau注意力 PyTorch版

文章目录 1. 前言为什么选择Bahdanau注意力本文目标与预备知识2. Bahdanau注意力机制概述注意力机制简述加性注意力与乘性注意力对比Bahdanau注意力的数学原理与流程图数学原理流程图可视化与直观理解3. 数据准备与预处理数据集简介数据加载与预处理1. 读取数据集2. 预处理文本…

19【动手学深度学习】卷积层

1. 从全连接到卷积 2. 图像卷积 3. 图形卷积代码 互相关操作 import torch from torch import nn from d2l import torch as d2ldef corr2d(X, K):"""计算2维互相关运算"""h, w K.shapeY torch.zeros((X.shape[0]-h1, X.shape[1]-w 1))for …

Linux xorg-server 解析(一)- 编译安装Debug版本的xorg-server

一:下载代码 1. 配置源,以Ubuntu24.04 为例( /etc/apt/sources.list.d/ubuntu.sources): 2. apt source xserver-xorg-core 二:编译代码 1. sudo apt build-dep ./ 2. DEB_BUILD_OPTIONS="nostrip" DEB_CFLAGS_SET="-g -O0" dpkg-buildpac…

大模型SFT用chat版还是base版 SFT后灾难性遗忘怎么办

大模型SFT用chat版还是base版 进行 SFT 时&#xff0c;基座模型选用 Chat 还是 Base 模型&#xff1f; 选 Base 还是 Chat 模型&#xff0c;首先先熟悉 Base 和 Chat 是两种不同的大模型&#xff0c;它们在训练数据、应用场景和模型特性上有所区别。 在训练数据方面&#xf…

【图像生成之21】融合了Transformer与Diffusion,Meta新作Transfusion实现图像与语言大一统

论文&#xff1a;Transfusion: Predict the Next Token and Diffuse Images with One Multi-Modal Model 地址&#xff1a;https://arxiv.org/abs/2408.11039 类型&#xff1a;理解与生成 Transfusion模型‌是一种将Transformer和Diffusion模型融合的多模态模型&#xff0c;旨…

动态多目标进化算法:基于知识转移和维护功能的动态多目标进化算法(KTM-DMOEA)求解CEC2018(DF1-DF14)

一、KTM-DMOEA介绍 在实际工程和现实生活中&#xff0c;许多优化问题具有动态性和多目标性&#xff0c;即目标函数会随着环境的变化而改变&#xff0c;并且存在多个相互冲突的目标。传统的多目标进化算法在处理这类动态问题时面临着一些挑战&#xff0c;如收敛速度慢、难以跟踪…

部署NFS版StorageClass(存储类)

部署NFS版StorageClass存储类 NFS版PV动态供给StorageClass(存储类)基于NFS实现动态供应下载NFS存储类资源清单部署NFS服务器为StorageClass(存储类)创建所需的RBAC部署nfs-client-provisioner的deployment创建StorageClass使用存储类创建PVC NFS版PV动态供给StorageClass(存储…

Vue使用el-table给每一行数据上面增加一行自定义合并行

// template <template><el-table:data"flattenedData":span-method"objectSpanMethod"borderclass"custom-header-table"style"width: 100%"ref"myTable":height"60vh"><!-- 订单详情列 -->&l…

vue项目使用html2canvas和jspdf将页面导出成PDF文件

一、需求&#xff1a; 页面上某一部分内容需要生成pdf并下载 二、技术方案&#xff1a; 使用html2canvas和jsPDF插件 三、js代码 // 页面导出为pdf格式 import html2Canvas from "html2canvas"; import jsPDF from "jspdf"; import { uploadImg } f…

大模型LLM表格报表分析:markitdown文件转markdown,大模型markdown统计分析

整体流程&#xff1a;用markitdown工具文件转markdown&#xff0c;然后大模型markdown统计分析 markitdown https://github.com/microsoft/markitdown 在线体验&#xff1a;https://huggingface.co/spaces/AlirezaF138/Markitdown 安装&#xff1a; pip install markitdown…

Linux 第二讲 --- 基础指令(二)

前言 这是基础指令的第二部分&#xff0c;但是该部分的讲解会大量使用到基础指令&#xff08;一&#xff09;的内容&#xff0c;为了大家的观感&#xff0c;如果对Linux的一些基本指令不了解的话&#xff0c;可以先看基础指令&#xff08;一&#xff09;&#xff0c;同样的本文…

python格式化字符串漏洞

什么是python格式化字符串漏洞 python中&#xff0c;存在几种格式化字符串的方式&#xff0c;然而当我们使用的方式不正确的时候&#xff0c;即格式化的字符串能够被我们控制时&#xff0c;就会导致一些严重的问题&#xff0c;比如获取敏感信息 python常见的格式化字符串 百…

LLaMA-Factory双卡4090微调DeepSeek-R1-Distill-Qwen-14B医学领域

unsloth单卡4090微调DeepSeek-R1-Distill-Qwen-14B医学领域后&#xff0c;跑通一下多卡微调。 1&#xff0c;准备2卡RTX 4090 2&#xff0c;准备数据集 医学领域 pip install -U huggingface_hub export HF_ENDPOINThttps://hf-mirror.com huggingface-cli download --resum…

React Hooks: useRef,useCallback,useMemo用法详解

1. useRef&#xff08;保存引用值&#xff09; useRef 通常用于保存“不会参与 UI 渲染&#xff0c;但生命周期要长”的对象引用&#xff0c;比如获取 DOM、保存定时器 ID、WebSocket等。 新建useRef.js组件&#xff0c;写入代码&#xff1a; import React, { useRef, useSt…

Spring AI 结构化输出详解

一、Spring AI 结构化输出的定义与核心概念 Spring AI 提供了一种强大的功能&#xff0c;允许开发者将大型语言模型&#xff08;LLM&#xff09;的输出从字符串转换为结构化格式&#xff0c;如 JSON、XML 或 Java 对象。这种结构化输出能力对于依赖可靠解析输出值的下游应用程…

THM Billing

1. 信息收集 (1) Nmap 扫描 bashnmap -T4 -sC -sV -p- 10.10.189.216 输出关键信息&#xff1a; PORT STATE SERVICE VERSION22/tcp open ssh OpenSSH 8.4p1 Debian 5deb11u380/tcp open http Apache 2.4.56 (Debian) # MagnusBilling 应用3306/tcp open …

布局决定终局:基于开源AI大模型、AI智能名片与S2B2C商城小程序的战略反推思维

摘要&#xff1a;在商业竞争日益激烈的当下&#xff0c;布局与终局预判成为企业成功的关键要素。本文探讨了布局与终局预判的智慧性&#xff0c;强调其虽无法做到百分之百准确&#xff0c;但能显著提升思考能力。终局思维作为重要战略工具&#xff0c;并非一步到位的战略部署&a…