本次總結針對selenium4.1
瀏覽器驅動配置:selenium環境配置 - 執劍之心 - 博客園 (cnblogs.com)
web頁面元素淺談:自動化:web網頁理解 - 執劍之心 - 博客園 (cnblogs.com)
需要整理: Selenium 中ExpectedConditions 用法說明(最全整理)_悠悠做神仙的博客-CSDN博客_expected_conditions
谷歌瀏覽器驅動下載:https://googlechromelabs.github.io/chrome-for-testing/#stable
一、概念和原理
- 軟件測試
- 爬蟲領域
- RPA領域

webdriver是什么?
- webdriver 協議 約定內容
- js代碼
- 還有很多指令通過js實現
- getAttribute.js 獲取元素屬性
- isDisplayed.js 判斷元素是否可見
- findElement.js 相對定位 se4新特性
- 支持錄制和回放(Selenium IDE)
- 通過WebDriver,直接控制瀏覽器,而不是通過攔截HTTP請求,實現真正模仿了用戶的操作;同時使用WebDriver能夠靈活的獲取頁面元素(WebDriver),並且提供執行JS的接口
- 能夠分布式運行在不同機器和異構環境中(不同瀏覽器)
對瀏覽器的操作: WebDriver對象 webdriver對象的方法和屬性
對元素的操作: WebElement對象 WebElement對象的方法和屬性
二、安裝和配置
安裝涉及事項:
- 編程語言
- selenium 庫
- 瀏覽器驅動 driver
- 瀏覽器
1、安裝selenium
pip install selenium
pip install --index-url http://mirrors.aliyun.com/pypi/simple/ selenium --trusted-host mirrors.aliyun.com # 換個地址下載
2、安裝瀏覽器驅動
set Path
echo $PATH
4、選擇方法打開瀏覽器
from selenium import webdriver driver = webdriver.Chrome()
自動安裝
pip install webdriver-helper=1.0.1 # 最新版本要收費,強行使用會報importerror
#安裝完web助手后,運行一次下面方法就可自動設置
三、瀏覽器交互
3.1、啟動和關閉瀏覽器
- service: 瀏覽器驅動對象,driver的存放路徑 (自動配置,可以省略service參數)
- options:瀏覽器參數對象,
- ChromeDriver: https://chromedriver.chromium.org/capabilities
- Chrome: https://peter.sh/experiments/chromium-command-line-switches/
啟動和自動退出瀏覽器
with webdriver.Chrome(service=service, options=options) as driver: driver.get("https://baidu.com")
手動退出瀏覽器
driver.quit()
3.2、webdriver對象的方法
窗口設置
方法
|
描述
|
set_window_size(width, height)
|
設置窗口大小
|
get_window_size()
|
獲取窗口大小 |
set_window_position(x,y)
|
設置窗口坐標 |
get_window_position()
|
獲取窗口坐標 |
set_window_rect()
|
設置窗口大小+坐標 |
get_window_rect()
|
獲取窗口大小+坐標 |
maximize_window()
|
最大化窗口 |
minimize_window()
|
最小化窗口 |
fullscreen_window()
|
全屏(后續無法退出) |
get_screenshot_as_png()
|
截圖的二進制內容
|
get_screenshot_as_base64()
|
截圖的base64內容
|
get_screenshot_as_file()
|
截圖保存到文件
|
頁面導航
get(url)
|
跳轉到指定頁面
|
back()
|
返回上個頁面
|
forward()
|
前進到下一個頁面
|
refresh()
|
刷新當前頁面 |
3.3、webdriver的屬性操作
屬性 | 描述 |
name
|
瀏覽器名字
|
capabilities
|
瀏覽器版本
|
current_url
|
當前網址
|
title
|
頁面title
|
page_source
|
HTML源碼
|
current_window_handle
|
當前窗口ID
|
window_handles
|
所有窗口ID
|
switch_to
|
窗口切換
|
timeouts
|
3.5、瀏覽器的高級操作
方法使用 | 描述 |
switch_to.alert | 切換到彈窗 |
switch_to.active_element | 切換到聚焦的元素 |
switch_to.frame('frame_name') | 切換到iframe |
switch_to.new_window('window_type') | 創建新窗口 |
switch_to.window('window_name') | 切換到窗口 |
cookie操作
方法 | 描述 |
add_cookie(cookie:dict)
|
增加指定cookie |
get_cookie(name) | 獲取指定cookie |
delete_cookie(name) | 刪除指定cookie |
delete_all_cookies() | 刪除所有cookies |
get_cookies() | 獲取所有cookies |
JavaScript操作
方法(主要就是第四個使用) | 描述 |
pin_script(script, script_key=None)
|
暫存JS片段 |
unpin(script_key) | 取消暫存 |
get_pinned_scripts() | 查看所有暫存 |
execute_script(script, *args) | 執行JS代碼,或暫存的JS |
四、元素定位
4.1、定位策略
- selenium角度來講:有8種定位策略,id、name、tag_name、class_name、link_text、partial_link_text、css、xpath
- 瀏覽器角度來講:只有兩種定位策略,css和xpath
- find_element()查找匹配的第一個,find_elements()查找匹配的多個,返回列表
driver.find_element(By.ID, "search-input") driver.find_element(By.NAME, "wd") driver.find_element(By.TAG_NAME, "input") find_element(By.CLASS_NAME, "submit am-btn") driver.find_element(By.LINK_TEXT, "首頁") driver.find_element(By.PARTIAL_LINK_TEXT, "首") driver.find_element(By.CSS, "input[id=search-input]") driver.find_element(By.XPATH, '//*@[id="search-input"]')
注:類似find_element_by_id()的方法正在被棄用,謹慎使用
- CSS
- XPATH
- LINK TEXT : 只能定位A標簽,局限性很大
- PARTIAL_LINK_TEXT: 只能定位A標簽,局限性很大
XPath: XPath 最初是用來在 XML 文檔中定位 DOM 節點的語言,由於 HTML 可以算作 XML 的一種實現。
CSS :Cascading Style Sheets是一種用於渲染 HTML 或者 XML 文檔的語言,CSS 利用其選擇器可以將樣式屬性綁定到文檔中的指定元素。
多個 CSS 選擇器還可以用逗號拼接為一個組合選擇器,滿足任意其中一個選擇器的元素都會被該組合選擇器選中,逗號的前后允許出現空白。
工作機制:
- XPath使用路徑標記在XML文檔層次結構中進行導航,就是遍歷文檔路徑。
- Selector則是一種匹配模式,速度上優化於XPath。
css和xpath選擇器都可以在開發者工具-控制端使用,如下:
css:$('#id')
xpath:$x('//*')
4.2、css選擇器
css選擇器參考文檔:CSS 選擇器參考手冊 (w3school.com.cn)
測試需掌握的幾種選擇方式:
#id #ID選擇器 .class #Class選擇器 input #元素選擇器 input[value="default_value"] #屬性選擇器 #通配選擇器,待舉例
input.cls 選擇class屬性為cls的input元素 #goods-category > div > div > div > ul >li #層次選擇器
控制台:$(’#lang‘) 選擇id 為lang的元素
4.3、xpath選擇器
xpath參考文檔:XPath 教程 (w3school.com.cn)
//input(@class="lang") 選擇class屬性為lang的input元素 //book[1] 選擇第一個book元素
對css和xpath總結:
- css匹配速度快
- xpath支持邏輯表達式,支持函數,實機項目中一般統一封裝為xpath
五、三種等待
相關的操作有如下幾種:
- 強制等待 sleep
- 隱式等待 implicitly_wait
- 顯式等待 WebDriverWait
- 流暢等待 FluentWait
1、強制等待sleep
#這是python本身自帶的等待方式 import time time.sleep()
缺點:當要求等待時間十分精確時,sleep很難自動做到,比如說某個提示信息出現停留1秒后消失
2、隱式等待implicitiy_wait
#一旦啟用,將全局生效 #每隔0.5秒檢查元素是否存在,存在就結束等待,不存在就等待到10秒后超時 driver.implicitiy_wait(10)
缺點:
1、與顯示等待WebDriverWait不可同時使用,會沖突
2、只會等待元素存在,不會等待元素就緒,例:按鈕A出現后置灰,不可點擊,等待3秒后才能點擊,
這樣的任務implicitiy_wait就做不到等待就緒
注:按鈕置灰時,selenium的click方法可以點擊成功,不會報錯,但結果是點擊無效
3、顯示等待WebDriverWait,0.5秒檢測一次
#實例化一個等待對象 web_wait=WebDriverWait(driver, 10) #條件等待,until直到條件ture,until_not直到條件false msg=web_wait.until( lambda x: x.find_element( By.XPATH, "//p[@class='prompt-msg']").text ) #1、until()中函數必須返回boolean值,其他類型的值也會當做布爾值判斷 #2、等待過程中只允許出現NoSuchElementException異常的出現,其他異# 常和timeout會終止等待 #3、until中等待條件只能是等待元素,不能交互元素,比如click點擊
項目實戰中一般等待就是用的顯示等待WebDriverWait
缺點:對一些更加精細化的操作難以完成,
例:元素閃現太快,某個提示只出現0.1秒就消失,而顯示等待檢測頻率為0.5s
4、流暢等待FluentWait
- 重試頻率 (可以設置等待多久判斷一次)
- 忽略的異常列表
#等待彈窗 alert = WebDriverWait( driver, 10, 0.1,#檢測判斷頻率為0.1s ignored_exceptions=[ NoAlertPresentException ], # 在等待過程中,如果出現NoAlertPresentException, 就繼續等待 ).until(lambda x: driver.switch_to.alert)
- element_to_be_clickable :判斷元素可見,並且可點擊
- alert_is_present: 判斷出現了alert 彈窗
六、元素交互
- 獲取網頁元素的信息:方法WebElement對象的屬性
- 對網頁元素進行交互: 調用WebElement對象的方法
<input value="input標簽實現的輸入框"> <textarea>textarea標簽實現的輸入框</textarea>/text
- ele.clear() # 清除內容
- ele.send_keys("new content") # 輸入內容
- ele.is_displayed()) # 是否顯示
- ele.is_enabled()) # 是否可用
2、按鈕
HTML代碼常見實現方式,以下有三種
<a href="javascript:;" onclick="btn_on_click(this)">a標簽實現的按鈕</a> <hr /> <input type="button" onclick="btn_on_click(this)" value="input標簽實現的按鈕" hidden=true /> <hr /> <button onclick="btn_on_click(this)" disabled=true >button標簽實現的按鈕 </button> <script> function btn_on_click(event){ console.log(event); alert("胸地,你點到我了!"); } </script>
- ele.click() # 鼠標 左鍵 單擊
- ele.is_displayed()) # 是否顯示
- ele.is_enabled()) # 是否可用
- ele.click() # selenium 提供 點擊按鈕
- driver.execute_script("return arguments[0].click()", ele) # js 進行點擊
selenium點擊過程
- 定位元素
- 找到元素 x,y坐標
- 把鼠標移動 x,y坐標中心 (可用手動調整坐標,模擬真人操作)
- 按下鼠標
3、單選框和復選框
都是input實現
<!--多選框 --> <input type="checkbox" name="check_1" value="1"/> <br> <input type="checkbox" name="check_1" value="2"/> <hr/ > <!--單選框 --> <input type="radio" name="check_2"/> <input type="radio" name="check_2" />
- ele.click() # 鼠標 左鍵 單擊
- ele.is_displayed()) # 是否顯示
- ele.is_enabled()) # 是否可用
- ele.is_selected() # 本元素是否被選中
- options 所有的可選項
- first_selected_option 已選的項目
- select_by_index 根據位置進行選擇
- select_by_visible_text 根據text選擇
- select_by_value 根據value選擇
with get_webdriver() as driver: from selenium.webdriver.support.select import Select
driver.get("http://118.24.147.95:8086/select_list.html") ele = driver.find_element(By.XPATH, "/html/body/select[1]")
select = Select(ele) # 實例化 Select print("所有的可選項目:", select.options) # 列表中多個元素 select.select_by_value("Shanghai") # 根據value進行選擇 print("已選擇的項目:", select.first_selected_option) # 單個元素
ele: WebElement = select.first_selected_option print("已選擇的項目的 text", ele.text) print("已選擇的項目的 value", ele.get_attribute("value")) # 進行斷言或者驗證
- all_selected_options 所有選中的項目 (可能是多個,所有是列表)
- deselect_all 取消選擇
- deselect_by_index 根據下標取消
- deselect_by_value 根據value取消
- deselect_by_visible_text 根據顯示文案取消
with get_webdriver() as driver: from selenium.webdriver.support.select import Select driver.get("http://118.24.147.95:8086/select_list.html") ele = driver.find_element(By.XPATH, "/html/body/select[2]") select = Select(ele) # 實例化 Select print("所有的可選項目:", select.options) # 列表中多個元素 select.select_by_index(0) # 順序 從0開始 select.select_by_visible_text("口味蝦") select.select_by_value("3") # 一共選擇3個 select.deselect_all() # 取消全部 print("已選擇的項目:", select.all_selected_options) # 所有選中的項目 ele: WebElement = select.first_selected_option print("已選擇的項目的 text", ele.text) print("已選擇的項目的 value", ele.get_attribute("value")) # 進行斷言或者驗證 driver.get_screenshot_as_file("a.png")
5、對話框(彈窗)
- alert
- confirm
- prompt
- driver.switch_to.alert
- Alert(driver)
- accept 點擊確定
- dismiss 點擊取消
- send_keys 輸入內容
6、文件上傳
點擊上傳:
with get_webdriver() as driver:
driver.get("http://118.24.147.95:8086/upload.html") file_path = str(Path("a.png").absolute()) # 文件的絕對路徑 i = driver.find_element(By.XPATH, '//*[@id="choice_file_windows"]') i.send_keys(file_path) # 輸入文件的路徑
driver.get_screenshot_as_file("b.png")

7、文件下載
8、鼠標和鍵盤事件
from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Firefox() # 直接操作 test = driver.find_element_by_id("id") # 定位到某元素 test.clear() # 清除輸入框的默認內容 test.size() # 獲取輸入框高度 test.send_keys("username") # 在輸入框輸入值 test.click() # 定位元素如果是按鈕,那現在是單擊 test.submit() # 定位元素如果是登錄按鈕之類表單確認,那現在就是提交操作 test.text() # 獲取文本內容 test.get_attribute('name') # 獲取元素name屬性的值 test.is_displayed() # 元素出現就輸出true test.is_enabled() # 判斷元素是否可以進行點擊、輸入之類的操作 test.is_selected() # 判斷元素是否被選中 # 鼠標事件 right = driver.find_element_by_xpath("xx") ActionChains(driver).context_click(right).perform() # 對定位到的元素執行鼠標右鍵操作 ActionChains(driver).double_click(right).perform() # 對定位到的元素執行鼠標雙擊操作 ActionChains(driver).move_to_element(right).perform() # 對定位到的元素執行鼠標移動到上面的操作 ActionChains(driver).click_and_hold(right).perform() # 對定位到的元素執行鼠標左鍵按下的操作 element = driver.find_element_by_name("xxx") # 定位元素的原位置 target = driver.find_element_by_name("xxx") # 定位元素要移動到的目標位置 ActionChains(driver).drag_and_drop(element, target).perform() # 執行元素的移動操作 # 鍵盤事件 driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE) # 回退刪格鍵 driver.find_element_by_id("kw").send_keys(Keys.SPACE) # 輸入空格鍵+“教程” driver.find_element_by_id("kw").send_keys(u"教程") driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x') # ctrl+x 剪切輸入框內容
應對滑動條
ac = ActionChains(driver) button = driver.find_element(By.XPATH, _ele_slider_button) ac.click_and_hold(button).perform() ac.move_to_element_with_offset(button, xoffset=240,yoffset=0).perform() ac.release().perform()
9、層級事件
1 # 層級定位 2 driver.switch_to.frame('frame11') # 先定位到某frame 3 driver.switch_to.parent_frame('frame1') # 定位到上級frame 4 driver.switch_to.default_content('frame0') # 定位最開始的frame
10、多窗口事件
driver = webdriver.Firefox() # 多窗口事件 nowhandle=driver.current_window_handle # 獲取當前窗口 driver.find_element_by_name("tj_reg").click() # 打開並去往注冊新窗口 allhandles=driver.window_handles # 獲取所有窗口 driver.switch_to.window(nowhandle) # 回到原來的窗口 driver.close() # 關閉當前窗口但不退出瀏覽器