一、元素定位
- 要想操作一個對象,首先應該識別這個對象。
- 定位方式有很多,但是要保證這種方式存在,且能夠唯一的定位到這個元素。
1、用 id 來定位 優先選擇 ※
- 首先在 Chrome 瀏覽器上把鼠標放到搜索框,鼠標右擊選擇開發者模式(快捷鍵:f12),查看對應 id 名
driver.find_element_by_id("kw").send_keys("肖戰") driver.find_element_by_id("su").click()
2、用 name 來定位
- 在開發者模式中找到對應的name,
driver.find_element_by_name("wd").send_keys("肖戰演員") driver.find_element_by_id("su").click()
3、用 class name 來定位
- class name不唯一,容易出錯。
driver.find_element_by_class_name("s_ipt").send_keys("xiaozhan") driver.find_element_by_class_name("bg s_btn").click()
4、用 link text (鏈接)定位
- 有時候不是一個輸入框也不是一個按鈕,而是一個文字鏈接,我們可以通過link。
driver.find_element_by_link_text("hao123").click()
5、用 partial link text (鏈接文字)定位
- 通過部分鏈接定位,可以只用鏈接的一部分文字進行匹配。
driver.find_element_by_partial_link_text("新").click()
6、用 tag name (標簽)定位
driver.find_element_by_tag_name("input").send_keys("陳情令") driver.find_element_by_tag_name("input").click()
失敗,ElementNotInteractableException: element not interactable 無法交互。input 標簽元素太多,無法定位。
7、用 XPath 定位 ※
- XPath 是一種在XML 文檔中定位元素的語言。因為HTML 可以看做XML 的一種實現,所以selenium 用戶可是使用這種強大語言在web 應用中定位元素。
- 用 id 來定位 優先選擇。如果沒有,使用 xpath 也可以唯一定位。
- 熟悉前端頁面也可以自己寫 :// 路徑, * 所有的尋找, @id 尋找 id。
# 在粘貼中,注意“ ” 內是' ' ,需要修改 driver.find_element_by_xpath("//*[@id='kw']").send_keys("陳情令") driver.find_element_by_xpath("//*[@id='su']").click()
8、用 css selector 定位
- 當有唯一 id 用 # ,有唯一 class 用 . 。
driver.find_element_by_css_selector("#kw").send_keys("cql") driver.find_element_by_css_selector("#su").click()
整體代碼
from selenium import webdriver import time driver = webdriver.Chrome() driver.get("https://www.baidu.com/") # 瀏覽器最大化 driver.maximize_window() # 用 id 來定位 優先選擇 如果沒有,使用 xpath 也可以唯一定位 # driver.find_element_by_id("kw").send_keys("肖戰") # driver.find_element_by_id("su").click() # 用 name 來定位 # driver.find_element_by_name("wd").send_keys("肖戰演員") # driver.find_element_by_id("su").click() # 用 class name 來定位 不唯一,出錯 # driver.find_element_by_class_name("s_ipt").send_keys("xiaozhan") # driver.find_element_by_class_name("bg s_btn").click() # link text # driver.find_element_by_link_text("hao123").click() # 鏈接的文本內容 partial link text # driver.find_element_by_partial_link_text("新").click() # tag name 標簽 ElementNotInteractableException: element not interactable 無法交互 input標簽元素太多,無法定位 # driver.find_element_by_tag_name("input").send_keys("陳情令") # driver.find_element_by_tag_name("input").click() # xPath //路徑 *所有的尋找 @id尋找id # driver.find_element_by_xpath("//*[@id='kw']").send_keys("陳情令") # driver.find_element_by_xpath("//*[@id='su']").click() # css id用#號 如果有唯一class是.號 driver.find_element_by_css_selector("#kw").send_keys("cql") driver.find_element_by_css_selector("#su").click() time.sleep(6) driver.quit()
二、操作測試對象
1、click 點擊對象
- click() 用於點擊一個按鈕。
2、send_keys 在對象上模擬按鍵輸入
- send_keys(“xx”) 用於在一個輸入框里輸入xx 內容。
3、clear 清除對象的內容(如果可以的話)
- clear() 用於清除輸入框的內容。
- 比如百度輸入框里默認有個“請輸入關鍵字”的信息。
- 比如我們的登陸框一般默認會有“賬號”“密碼”這樣的默認信息,clear 可以幫助我們清除這些信息。
from selenium import webdriver import time driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window() driver.find_element_by_css_selector("#kw").send_keys("我在他鄉挺好的") driver.find_element_by_css_selector("#su").click() time.sleep(6) # 清除信息 先定位 driver.find_element_by_id("kw").clear() time.sleep(5) # 在搜索其他信息 driver.find_element_by_id("kw").send_keys("肖戰") driver.find_element_by_id("su").click() time.sleep(6) driver.quit()
4、submit 提交表單
- 把“百度一下”的操作從click 換成submit 可以達到相同的效果(在該頁面唯一,與 click 作用一致)。
driver.find_element_by_id("kw").send_keys("肖戰") driver.find_element_by_id("su").submit()
5、text 用於獲取元素的文本信息 ※
- text 用於獲取元素的文本信息。
from selenium import webdriver import time driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window() # 獲取元素內容 text = driver.find_element_by_id("bottom_layer").text print(text) driver.quit()
三、添加等待
- 添加休眠非常簡單,我們需要引入time 包,就可以在腳本中自由的添加休眠時間。
from selenium import webdriver import time driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window() driver.find_element_by_id("kw").send_keys("肖戰") driver.find_element_by_id("su").click() # 找到肖戰,跳轉到肖戰的百度百科界面 driver.find_element_by_link_text("百度百科").click() # 沒有找到,在資源沒加載出來,就去尋找資源,導致沒有變化 time.sleep(6) # close 關閉瀏覽器 quit 不僅關閉瀏覽器,還可以清除緩存垃圾 driver.quit()
1、固定等待 time.sleep()
from selenium import webdriver import time driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window() driver.find_element_by_id("kw").send_keys("肖戰") driver.find_element_by_id("su").click() # 加一個等待 # 固定等待,讓頁面 等待 規定的時間 10s ,在 10s后在查找肖戰的百度百科, time.sleep(10) driver.find_element_by_link_text("百度百科").click() time.sleep(6) driver.quit()
2、智能等待 implicitly_wait()
from selenium import webdriver import time driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window() driver.find_element_by_id("kw").send_keys("肖戰") driver.find_element_by_id("su").click() # 加一個等待 # 智能等待 ,當頁面加載出來后就直接跳轉, 下面的意思是最多等10秒 但是在10s后沒有加載出來后就會報錯 driver.implicitly_wait(10) driver.find_element_by_link_text("百度百科").click() time.sleep(6) driver.quit()
3、顯示等待WebDriverWait()
- 等待頁面加載完成,找到某個條件發生后再繼續執行后續代碼,如果超過設置時間檢測不到則拋出異常
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None) ——driver:WebDriver 的驅動程序(Ie, Firefox, Chrome 或遠程) ——timeout:最長超時時間,默認以秒為單位 ——poll_frequency:休眠時間的間隔(步長)時間,默認為 0.5 秒 ——ignored_exceptions:超時后的異常信息,默認情況下拋 NoSuchElementException 異常
- 通常使用WebDriverWait時,我們還是使用到EC即expected_condition
#coding=utf-8 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait base_url = "http://www.baidu.com" driver = webdriver.Firefox() driver.implicitly_wait(5) '''隱式等待和顯示等待都存在時,超時時間取二者中較大的''' locator = (By.ID,'kw') driver.get(base_url) WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道")) '''判斷title,返回布爾值''' WebDriverWait(driver,10).until(EC.title_contains(u"百度一下")) '''判斷title,返回布爾值''' WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw'))) '''判斷某個元素是否被加到了dom樹里,並不代表該元素一定可見,如果定位到就返回WebElement''' WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'su'))) '''判斷某個元素是否被添加到了dom里並且可見,可見代表元素可顯示且寬和高都大於0''' WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw'))) '''判斷元素是否可見,如果可見就返回這個元素''' WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.mnav'))) '''判斷是否至少有1個元素存在於dom樹中,如果定位到就返回列表''' WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR,'.mnav'))) '''判斷是否至少有一個元素在頁面中可見,如果定位到就返回列表''' WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.XPATH,"//*[@id='u1']/a[8]"),u'設置')) '''判斷指定的元素中是否包含了預期的字符串,返回布爾值''' WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),u'百度一下')) '''判斷指定元素的屬性值中是否包含了預期的字符串,返回布爾值''' #WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator)) '''判斷該frame是否可以switch進去,如果可以的話,返回True並且switch進去,否則返回False''' #注意這里並沒有一個frame可以切換進去 WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR,'#swfEveryCookieWrap'))) '''判斷某個元素在是否存在於dom或不可見,如果可見返回False,不可見返回這個元素''' #注意#swfEveryCookieWrap在此頁面中是一個隱藏的元素 WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]"))).click() '''判斷某個元素中是否可見並且是enable的,代表可點擊''' driver.find_element_by_xpath("//*[@id='wrapper']/div[6]/a[1]").click() #WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='wrapper']/div[6]/a[1]"))).click() #WebDriverWait(driver,10).until(EC.staleness_of(driver.find_element(By.ID,'su'))) '''等待某個元素從dom樹中移除''' #這里沒有找到合適的例子 WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]"))) '''判斷某個元素是否被選中了,一般用在下拉列表''' WebDriverWait(driver,10).until(EC.element_selection_state_to_be(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]"),True)) '''判斷某個元素的選中狀態是否符合預期''' WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.XPATH,"//*[@id='nr']/option[1]"),True)) '''判斷某個元素的選中狀態是否符合預期''' driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click() instance = WebDriverWait(driver,10).until(EC.alert_is_present()) '''判斷頁面上是否存在alert,如果有就切換到alert並返回alert的內容''' print instance.text instance.accept() driver.close()
四、打印 信息
1、打印 title:title()※
from selenium import webdriver import time driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window() # 打印 title 信息 title = driver.title print(title) time.sleep(8) driver.quit()
2、打印 URL:current_url()※
from selenium import webdriver import time driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window() # 打印 title 信息 # title = driver.title # print(title) # 打印 url url = driver.current_url print(url) time.sleep(8) driver.quit()
六、瀏覽器的操作
1、瀏覽器最大化:maximize_window()
- 調用啟動的瀏覽器不是全屏的,這樣不會影響腳本的執行,但是有時候會影響我們“觀看”腳本的執行。
driver.maximize_window()
2、設置瀏覽器的長寬:set_window_size()
driver.set_window_size(400, 800)
3、操作瀏覽器的前進:forward()和后退:back()※
# 瀏覽器后退 driver.back() # 瀏覽器前進 driver.forward()
4、操作瀏覽器滾動條:execute_script ()※
#將頁面滾動條拖到底部 js="var q=document.documentElement.scrollTop=10000" driver.execute_script(js) #將滾動條移動到頁面的頂部 js="var q=document.documentElement.scrollTop=0" driver.execute_script(js)
七、鍵盤事件
1、enter 鍵:send_keys(Keys.ENTER)
- 首先需要導入keys 包:from selenium.webdriver.common.keys import Keys 。
- 一般登錄頁面,非測試人員 不可以使用自動化腳本登錄。破壞安全性,同時也會造成性能損耗。自動化登錄腳本會產生大量數據,造成垃圾數據,會對數據庫存儲產生壓力。
如何防止用戶使用自動化腳本控制郵箱登錄?
- 選擇禪道來登錄,開發者模式下,選中密碼 name = “password”,快鍵鍵 ctrl + f 可以搜索查看是否是唯一 name,來進行定位。
2、tab 鍵:send_keys(Keys.TAB)
from selenium import webdriver import time from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("http://127.0.0.1:88/pro/user-login-L3Byby8=.html") driver.maximize_window() # 先清除已有賬號的登錄信息 driver.find_element_by_id("account").clear() driver.find_element_by_name("password").clear() # 登錄操作 自己的用戶名 密碼 # driver.find_element_by_id("account").send_keys("admin") # driver.find_element_by_name("password").send_keys("123456cao") # driver.find_element_by_id("submit").click() # 或者 使用 Tab 鍵,先要將焦點定位到用戶名 driver.find_element_by_id("account").send_keys("admin") driver.find_element_by_id("account").send_keys(Keys.TAB) time.sleep(3) driver.find_element_by_name("password").send_keys("123456cao") # 用 enter 鍵直接登陸 driver.find_element_by_name("password").send_keys(Keys.ENTER) time.sleep(5) driver.quit()
3、ctrl + x、ctrl + v、ctrl + a ※
from selenium import webdriver import time from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window() driver.find_element_by_id("kw").send_keys("顧一野") driver.find_element_by_id("su").click() time.sleep(3) # 重新搜索一個內容,可以使用之前的clear 。 # 新方法:可以先選中(ctrl + a ),在使用 ctrl + x 剪切掉,再重新輸入 driver.find_element_by_id("kw").send_keys(Keys.CONTROL,"a") time.sleep(3) driver.find_element_by_id("kw").send_keys(Keys.CONTROL,"x") time.sleep(3) driver.find_element_by_id("kw").send_keys("顧一野 阿秀") driver.find_element_by_id("su").click() time.sleep(5) driver.quit()
七、鼠標事件
1、右擊:context_click()※
- ActionChains(driver):生成用戶的行為。所有的行動都存儲在 actionchains 對象。通過 perform() 存儲的行為。
2、雙擊:double_click()※
from selenium import webdriver import time from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome() driver.get("https://www.baidu.com/") driver.maximize_window() driver.find_element_by_id("kw").send_keys("王牌部隊") driver.find_element_by_id("su").click() time.sleep(3) b = driver.find_element_by_id("su") # 右擊 百度一下 ActionChains(driver).context_click(b).perform() time.sleep(3) # 雙擊 百度一下 ActionChains(driver).double_click(b).perform() time.sleep(3) driver.quit()
3、拖動:drag_and_drop() ※
4、移動:move_to_element() ※
八、定位一組元素
- webdriver 可以很方便的使用findElement 方法來定位某個特定的對象,不過有時候我們卻需要定位一組對象,這時候就需要使用 findElements 方法。
- 使用場景:checkbox 勾選…
from selenium import webdriver import time import os driver = webdriver.Chrome() # 首先要打開頁面 file:///D:/javacode/selenium2html/selenium2html/checkbox.html # 1、首先用到 系統類工具 os 找到復選框頁面文件地址, / 轉義為 \\ url = "file:///" + os.path.abspath("D:\\javacode\\selenium2html\\selenium2html/checkbox.html") driver.get(url) driver.maximize_window() # 勾選所有的 checkbox ,定位一組 tag buttons = driver.find_elements_by_tag_name("input") for button in buttons: if button.get_attribute('type') == 'checkbox': button.click() time.sleep(3) driver.quit()
checkbox.html
<html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <title>Checkbox</title> </head> <body> <h3>checkbox</h3> <div class="well"> <form class="form-horizontal"> <div class="control-group"> <label class="control-label" for="c1">checkbox1</label> <div class="controls"> <input type="checkbox" id="c1" /> </div> </div> <div class="control-group"> <label class="control-label" for="c2">checkbox2</label> <div class="controls"> <input type="checkbox" id="c2" /> </div> </div> <div class="control-group"> <label class="control-label" for="c3">checkbox3</label> <div class="controls"> <input type="checkbox" id="c3" /> </div> </div> <div class="control-group"> <label class="control-label" for="r">radio</label> <div class="controls"> <input type="radio" id="r1" /> </div> </div> <div class="control-group"> <label class="control-label" for="r">radio</label> <div class="controls"> <input type="radio" id="r2" /> </div> </div> </form> </div> </body> </html>
九、多層框架/窗口定位
1、多層框架的定位:
- 點擊 click
- from selenium import webdriver import time import os driver = webdriver.Chrome() url = "file:///" + os.path.abspath("D:\\javacode\\selenium2html\\selenium2html/frame.html") driver.get(url) time.sleep(3) driver.maximize_window() # 定位 第二個窗口 f1 中的 click # 從默認頁面到 f1 driver.switch_to.frame("f1") driver.find_element_by_link_text("click").click() time.sleep(5) driver.quit()
- 從默認頁面到達 f2 頁面:默認 —》f1—》f2,使用 switch_to.frame()。
- 從 f2 回退到 f1 頁面:f2—》默認—》f1,driver.switch_to.default_content() 回到默認頁面,在從默認頁面到 f1,driver.swtich_to.frame()。
十、層級定位
- 點擊二級菜單,並且使其高亮展示
from selenium import webdriver import time import os from selenium.webariver.common.action_chains import ActionChains driver = webdriver.Chrome() url = "file:///" + os.path.abspath("D:\\javacode\\selenium2html\\selenium2html/level_locate.html") driver.get(url) time.sleep(3) driver.maximize_window() # 定位 link1 ,點擊 driver.find_element_by_link_text("Link1").click() driver.implicitly_wait(10) # 定位 二級菜單中的 Another action action = driver.find_element_by_link_text("Another action") # 高亮展示 ActionChains(driver).move_to_element(action).perform() time.sleep(5) driver.quit()
十一、下拉框處理
- 下拉框里的內容需要進行兩次定位,先定位到下拉框,再定位到下拉框內里的選項。
from selenium import webdriver import time import os from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome() url = "file:///" + os.path.abspath("D:\\javacode\\selenium2html\\selenium2html/drop_down.html") driver.get(url) time.sleep(3) driver.maximize_window() time.sleep(3) options = driver.find_elements_by_tag_name("option") # for option in options: # if option.get_attribute('value') == '9.03': # option.click() options[3].click() time.sleep(3) driver.quit()
十二、alert彈窗處理
關閉 alert:alert.accept()
from selenium import webdriver import time import os from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome() url = "file:///" + os.path.abspath("D:\\javacode\\selenium2html\\selenium2html/alert.html") driver.get(url) time.sleep(3) driver.maximize_window() time.sleep(3) # 定位元素,點擊,使彈出框出現 driver.find_element_by_id("tooltip").click() time.sleep(3) # 定位彈出框 的操作句柄 alert = driver.switch_to.alert time.sleep(3) # 關閉 alert alert.accept() time.sleep(3) driver.quit()
十三、div處理
- 如果要定位元素的屬性,頁面有很多元素有相同的屬性,可以限定為具體的 div,在定位該元素。
from selenium import webdriver import time import os from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome() url = "file:///" + os.path.abspath("D:\\javacode\\selenium2html\\selenium2html/modal.html") driver.get(url) driver.maximize_window() time.sleep(3) # 點擊 click,出現彈框 driver.find_element_by_link_text("Click").click() time.sleep(3) # 點擊 div 中的 click me div = driver.find_element_by_class_name("modal-body") div.find_element_by_link_text("click me").click() time.sleep(3) # 定位 div 中的 button div2 = driver.find_element_by_class_name("modal-footer") buttons = driver.find_elements_by_tag_name("button") buttons[0].click() time.sleep(5) driver.quit()
modal.html
<html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <title>modal</title> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" /> <script type="text/javascript"> $(document).ready(function () { $('#click').click(function () { $(this).parent().find('p').text('Click on the link to success!'); }); }); </script> </head> <body> <h3>modal</h3> <div class="row-fluid"> <div class="span6"> <!-- Button to trigger modal --> <a href="#myModal" role="button" class="btn btn-primary" data-toggle="modal" id="show_modal">Click</a> <!-- Modal --> <div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h3 id="myModalLabel">Modal header</h3> </div> <div class="modal-body"> <p>Congratulations, you open the window!</p> <a href="#" id="click">click me</a> </div> <div class="modal-footer"> <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button> <button class="btn btn-primary">Save changes</button> </div> </div> </div> </div> </body> <script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script> </html>
十四、上傳文件操作
from selenium import webdriver import time import os from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome() url = "file:///" + os.path.abspath("D:\\javacode\\selenium2html\\selenium2html/upload.html") driver.get(url) driver.maximize_window() time.sleep(3) # 上傳一個圖片 driver.find_element_by_name("file").send_keys("C:\\Users\\DELL\\Pictures/bg.jpg") time.sleep(5) driver.quit()