【python+selenium的web自動化】- 元素的常用操作詳解(二)

如果想從頭學起selenium,可以去看看這個系列的文章哦!

//www.cnblogs.com/miki-peng/category/1942527.html

本篇主要內容:1.滑鼠操作;2.鍵盤操作;3.下拉框操作;4.js處理

上篇主要內容:1.元素的基本操作;2.等待操作;3.iframe操作;4.alert彈出框 傳送門

滑鼠操作

​ selenium的ActionChains類提供了一系列模擬滑鼠操作的方法,主要操作流程:1、存儲滑鼠操作;2、調用perform()執行滑鼠操作,支援的操作部分列舉如下:

  • 🍇 double_click(ele):雙擊
  • 🍑 context_click(ele):右鍵
  • 🍊 drag_and_drop(source, target):從某個元素拖拽到某個元素然後鬆開
  • 🍇 drag_and_drop_by_offset(source, xoffset, yoffset):拖拽元素到某個坐標然後鬆開
  • 🍓 move_to_element(ele):滑鼠懸停在某個元素

​ 下面以百度首頁的搜索設置為例,滑鼠懸停在【設置】,然後點擊顯示出來的【搜索設置】:

import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

# 啟動Chromedriver,並與Chromedriver開啟會話
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("//www.baidu.com")

# 第一步:實例化ActionChains
ac = ActionChains(driver)
# 第二步:定位要操作的元素
ele = driver.find_element_by_xpath('//span[@id="s-usersetting-top"]')
# 第三步:執行對應的操作
ac.move_to_element(ele)		# 懸浮操作
# 第四步,釋放滑鼠動作
ac.perform()

# 點擊懸停出來的頁面上的元素
wait = WebDriverWait(driver, 10)
loc = (By.XPATH, '//a[@class="setpref"]')
wait.until(EC.visibility_of_element_located(loc))
driver.find_element(*loc).click()

time.sleep(2)
driver.quit()

​ 這裡科普一個知識點,就是鏈式調用:它可以在一個方法後面接著調用另外的方法,只要它的方法都是返回對象本身即可,如上述的actionchains 用法可以這樣寫: ActionChains(driver).move_to_element(ele).perform()

小知識:查看源碼,按住鍵盤ctrl鍵,然後滑鼠點擊一下函數就會跳轉到源碼。

​ 用一個簡單例子來演示一下ActionChains工作流程的原理:

def move_to():
    print("正在移動")

def click():
    print('點擊')

actions = []
actions.append(move_to)
actions.append(click)

for action in actions:	# perform
    # action = move_to
    action()

鍵盤操作

​ selenium提供了比較完整的鍵盤操作,在使用鍵盤按鍵方法前需要先導入keys類:from selenium.webdriver.common.keys import Keys,它定義了非常多的按鍵操作,具體的可以問度娘。

​ 常見的一些組合鍵和非組合鍵如下:

  • 🍊 send_keys(Keys.BACK_SPACE) 刪除鍵
  • 🍇 send_keys(Keys.SPACE) 空格鍵
  • 🍋 send_keys(Keys.TAB) 製表tab鍵
  • 🍉 send_keys(Keys.ESCAPE) 回退鍵
  • 🍑 send_keys(Keys.ENTER) 回車鍵
  • 🍓 send_keys(Keys.F5) 刷新鍵
  • 🍅 send_keys(Keys.CONTROL,'a') 全選
  • 🍏 send_keys(Keys.CONTROL,'c') 複製
  • 🍆 send_keys(Keys.CONTROL,'x') 剪切
  • 🍎 send_keys(Keys.CONTROL,'v') 粘貼
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

# 啟動Chromedriver,並與Chromedriver開啟會話
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("//www.baidu.com")
driver.find_element_by_id('kw').send_keys("selenium")  # 沒有點擊百度一下也沒有回車不會出現搜索結果
time.sleep(2)
driver.find_element_by_id('kw').send_keys(Keys.CONTROL,'a')	 # 全選然後輸入新內容python
driver.find_element_by_id('kw').send_keys('python', Keys.ENTER)	  # 用回車代替點擊搜索按鈕
time.sleep(2)
# driver.find_element_by_id('kw').send_keys('python')  # 也可以單獨先輸內容
# driver.find_element_by_id('kw').send_keys(Keys.ENTER) # 再回車
time.sleep(2)
driver.quit()

​ 之前在瀏覽器操作的那篇文章中,提到過除了點擊瀏覽器窗口上方的「+」號可以打開新標籤頁,現在有了鍵盤操作,那是不是也可以通過快捷鍵來打開一個新標籤頁呢?趕緊去試一下看看效果吧!

下拉框操作

​ 對select/option類型的下拉列表的操作,我們可以通過點擊select標籤進行選擇選項,另外selenium也提供了Select類來處理select/option去選擇下拉列表值:

  • 🍦 通過下標選擇:select_by_index(index) index從0開始
  • 🍦 通過value屬性:select_by_value(value值)
  • 🍦 通過文本內容:select_by_visible_text(文本內容)

​ 取消選中則是deselect_by...,下面以舉例的html為例,需要先把該程式碼保存成html文件,後續直接訪問這個本地html文件:

<html>
<head>
    <meta charset="UTF-8">
    <title>下拉框演示</title>
</head>
<body>
<select id="province">
    <option value="sj">深圳</option>
    <option value="gd">廣東</option>
    <option value="sh">上海</option>
    <option value="bj">北京</option>
</select>
<select id="city">
    <option value="sj">深圳</option>
    <option value="gz">廣州</option>
    <option value="sh">上海</option>
    <option value="bj">北京</option>
</select>
</body>
</html>

​ 演示程式碼如下:

import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.ui import Select

# 啟動Chromedriver,並與Chromedriver開啟會話
driver = webdriver.Chrome()
driver.maximize_window()
driver.get(r"D:\learn\test.html")

wait = WebDriverWait(driver, 10)

# 找到select元素
ele = driver.find_element_by_id('province')
# 實例化Select類
s = Select(ele)
time.sleep(1)
s.select_by_value('gd')   # 通過value屬性選值
time.sleep(2)
s.select_by_index(2)   # 通過下標index選值
time.sleep(2)
s.select_by_visible_text('北京')   # 通過文本內容選值

time.sleep(2)
driver.quit()

Js處理日曆控制項

​ 在web自動化的過程中,我們常常會遇到有日曆控制項選擇日期的場景,大致分為以下兩種:

​ 📆 1、可以直接輸入日期(可以通過定位元素然後send_keys輸入日期)

​ 📅 2、不能直接輸入日期,只能選擇(帶有:readonly(只讀)屬性)

​ 對於不能直接輸入日期的控制項,只能通過選擇實在太麻煩了。因為不能輸入,就會考慮去點擊其中的年份、月份、太難的數字。由於日曆控制項面板很小,單個元素也很小,有可能會產生操作失誤的問題,並且程式碼寫起來實在太繁瑣了。

​ 那既然selenium支援執行js語句,那我們是不是可以利用js來去掉readonly(即只讀)屬性,然後直接通過send_keys輸入時間呢,試一下吧!

​ 以12306網站買票的出發日期為例,如下圖它是有隻讀屬性的,直接程式碼輸入是無法輸入的:

import time
import datetime
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

# 啟動Chromedriver,並與Chromedriver開啟會話
driver = webdriver.Chrome()
# driver.maximize_window()
driver.get("//www.12306.cn/")

wait = WebDriverWait(driver, 30)
loc = (By.XPATH, '//input[@id="train_date"]')
wait.until(EC.visibility_of_element_located(loc))

js = 'document.getElementById("train_date").readOnly=false;'
driver.execute_script(js)
time.sleep(2)

# 清空日曆,重新輸入日期
driver.find_element(*loc).clear()
today = datetime.date.today()
tomorrow = today + datetime.timedelta(days=1)
driver.find_element_by_id('train_date').send_keys(str(tomorrow))

time.sleep(2)
driver.quit()

​ 舉一反三,在碰到selenium處理不了的情況時,我們就可以考慮使用js或者其他方法去實現噢~~之前也有講過js處理瀏覽器窗口滾動條的場景:傳送門