鼠標、鍵盤組合鍵
在使用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"