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.pswp.cn/bicheng/76623.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76623.shtml
英文地址,請注明出處:http://en.pswp.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…