(轉(zhuǎn))Selenium無法定位元素的九種解決方案

http://www.itdecent.cn/p/83087c24ab19

一、frame/iframe表單嵌套

WebDriver只能在一個頁面上對元素識別與定位,對于frame/iframe表單內(nèi)嵌的頁面元素無法直接定位。

解決方法:driver.switch_to.frame(id/name/obj)。

switch_to.frame()默認可以直接取表單的id或name屬性。如果沒有可用的id和name屬性,可以先定位到frame/iframe,再將定位對象傳給switch_to.frame(對象)方法。

xf = driver.find_element_by_xpath('//*[@class="if"]')driver.switch_to.frame(xf)...

driver.switch_to.parent_frame()切到父frame。影響性能,可以提給開發(fā),讓其改進。

driver.switch_to.default_content()跳回最外層的頁面

二、頁面跳轉(zhuǎn)到新的標簽頁,或者彈出的警告框等

在頁面操作過程中有時候點擊某個鏈接會彈出新窗口,這時就需要切換焦點到新窗口上進行操作。

解決方法1:driver.switch_to.window(window_handle)切換到新窗口。

首先獲取當前窗口的句柄driver.current_window_handle,接著打開彈出新窗口,獲得當前打開的所有窗口的句柄driver.window_handles。通過for循環(huán)遍歷handle,如果不等于第一次打開窗口的句柄,那么一定是新窗口的句柄,因為執(zhí)行過程只打開了兩個窗口;改變條件,如果等于第一次打開窗口的句柄,那么可以切換回第一次打開的窗口。

解決方法2:對于JavaScript生成的alert、confirm以及prompt,無法使用前端工具對彈出窗口進行定位的,使用driver.switch_to.alert方法定位彈出框。alert的方法有:

.accept()? ? '等同于點擊“確認”或“OK”'.dismiss()? ? '等同于點擊“取消”或“Cancel”'.text? ? ? ? '獲取alert文本內(nèi)容,對有信息顯示的alert框'.send_keys(text)? ? '發(fā)送文本,對有提交需求的prompt框'.authenticate(username,password)? ? '驗證,針對需要身份驗證的alert'

三、頁面元素失去焦點導致腳本運行不穩(wěn)定

解決方法:driver.switch_to.active_element遇到腳本不穩(wěn)定,有時會失去焦點導致測試失敗的情況下,可以先切到焦點元素再進行操作。注意.active_element后面不帶括號()。

下面是一個參考案例

'最初的 “右擊鼠標 → 新建文件夾 → 輸入文件夾名稱” 的代碼'l = driver.find_element_by_id('pm_treeRoom_1_span')ActionChains(driver).context_click(l).perform()driver.find_element_by_class_name('fnew').click()time.sleep(2)driver.find_element_by_xpath('//*[@id="pm_treeRoom_1_ul"]/li[...]').send_keys('filename')time.sleep(2)

結(jié)果這種操作總會導致輸入框失去焦點,直接消失,更不能send_keys進去了,直接報錯。

'修改后的代碼如下'driver.find_element_by_class_name('fnew').click()time.sleep(2)driver.switch_to.active_element.send_keys('filename')time.sleep(2)

四、使用Xpath或CSS定位

find_element_by_xpath("http://標簽[屬性='值']")

使用Xpath/CSS方法,非常適合定位屬性值動態(tài)生成、不容易定位的元素。如果不想指定標簽,則可以使用“*”代替,使用xpath不局限于id、name和class這三個屬性,元素的任意屬性值都可以使用,只要它能唯一的標識一個元素。

解決方法1:如果一個元素沒有唯一屬性,那么我們可以一級一級向上查找,直到找到可以唯一定位元素的屬性,再向下查找其子元素。

find_element_by_xpath("http://form[@id='form']/span[2]/input")首先通過唯一標識屬性id=form定位最外層元素,接著找到最外層元素下的第2個span標簽的元素為父元素,最后向下查找定位到父元素下標簽為input的子元素。

解決方法2:如果一個屬性不能唯一地區(qū)分一個元素,那么使用多個屬性來唯一地定位一個元素。

find_element_by_xpath("http://input[@id='kw' and @class='su']/span/input")首先找到標簽為input,id=kw且class=su的元素,接著找到其下標簽為span的子元素,繼續(xù)向下查找找到標簽為input的子元素。

解決方法3:檢查Xpath描述是否有誤,導致無法定位到元素。

五、頁面還沒有加載出來,就對頁面上的元素進行的操作

因為加載元素延時造成的腳本失敗,我們可以通過設(shè)置等待時間來提升自動化腳本的穩(wěn)定性。

解決方法1:WebDriverWait()顯示等待。等待單個的元素加載,通常配合until()、until_not()方法使用。

WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)-driver-傳入WebDriver實例,必填-timeout-最長等待時間,必填-poll_frequency-調(diào)用`until`/`until_not`方法的時間間隔,默認為0.5秒,可省。-ignored_exceptions-忽略異常,默認僅包含NoSuchElementException,可省。

WebDriverWait(driver,10).until(method,message='')'等待目標出現(xiàn)'WebDriverWait(driver,5,1).until_not(method,message='')'等待目標消失'-method-必填。-message-默認為空,可省。如果超時,拋出TimeoutException,返回message信息。

即,WebDriverWait(driver, 超時時長, 調(diào)用頻率, 忽略異常).until(可執(zhí)行方法, 超時時返回的信息)

WebDriverWait(driver,5,1).until(expected_conditions.presence_of_element_located(By.ID,'kw'))

最長等待時間為5s,每隔1秒檢查一次id='kw'的元素是否被加載在DOM樹里(并不代表該元素一定可見)。最常用的methodexpected_conditions類提供的預期條件判斷。

is_disappeared=WebDriverWait(driver,30,1,(ElementNotVisibleException)).until_not(lambdax:x.find_element_by_id('someId').is_displayed())

最長等待時間為30s,每隔1秒檢查一次id='someId'的元素是否從DOM樹里消失,忽略默認異常信息NoSuchElementException和指定的異常信息ElementNotVisibleException。此處匿名函數(shù)lambda的用法具體參考Python語法。

解決方法2:driver.implicitly_wait(秒)隱式等待。全局等待,對所有元素設(shè)置超時時間,等待頁面的加載,因此只需要設(shè)置一次即可。這里的時間是最長等待時間(非固定等待時間)。

解決方法3:sleep(秒)線程等待。休眠固定的時間,使用時需要先引入time模塊的sleep方法from time import sleep。

六、元素被遮擋,不可用,不可見

解決方法1:driver.maximize_window()由于窗口大小改變引起的頁面元素布局發(fā)生變化,被測元素被遮擋,可以先將窗口最大化,再進行元素定位。

解決方法2:.is_enabled()由于業(yè)務原因元素在某些情況下不可用(元素屬性disabled,灰顯),首先檢查測試步驟是否符合業(yè)務邏輯,其次確認是否為業(yè)務流程上的Bug。

解決方法3:.is_displayed()對于屬性不一定可見的元素,在定位前首先判斷其屬性是否可見,是否被隱藏。

解決方法4:由于布局不合理導致的元素被遮蓋、或是元素本身缺失引起的無法定位問題屬于Bug,可以提給開發(fā)讓其改進。

七、使用WebDriver調(diào)用JavaScript代碼代替無法實現(xiàn)的功能

對于有些WebDriver沒有提供的方法或者無法實現(xiàn)的功能,WebDriver提供了driver.execute_script()方法來執(zhí)行JavaScript代碼。

解決方法:如果頁面內(nèi)容過長,窗口最大化也無法查看到所有元素,可以通過執(zhí)行JavaScript腳本實現(xiàn)滾動條的拖動等動作。

driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

以上語句實現(xiàn)了拉動頁面到底部的功能,其中window.scrollTo(左邊距,上邊距)是JavaScript中用于設(shè)置瀏覽器窗口滾動條的水平和垂直位置的代碼。

text = "input text"driver.execute_script("var obj=document.getElementById('text'); obj.value=' " + text + " ';")

假設(shè)一個輸入框可以通過id='text'將其定位,卻不能通過send_keys()輸入文本內(nèi)容,可以借助JavaScript代碼來實現(xiàn)。

video = driver.find_element_by_xpath("body/Section[1]/div/video")url = driver.execute_script("return arguments[0].currentSrc;", video)print(url)? ? ? ? ? '返回文件播放地址'print("start")? ? ? '播放視屏'driver.execute_script("return arguments[0].play()", video)sleep(15)? ? ? ? ? '播放15秒鐘'print(stop)? ? ? ? '暫停視屏'driver.execute_script("arguments[0].pause()", video)...

以上實現(xiàn)了HTML5視屏標簽的部分測試,更多內(nèi)容參考HTML DOM Video對象。

其中arguments是JavaScript的內(nèi)置對象。因為將video對象傳給了arguments[0],所以arguments[0]相當于JavaScript腳本的document.getElementsByTagName("video")。JavaScript不支持重載,使用arguments對象可以模擬函數(shù)重載效果。

八、WebDriver無法操作Windows控件

文件的普通上傳和下載(參考How to auto save files using custom Firefox profile ?),可以通過.send_keys('本地路徑')和find_element_by_partial_link_text('下載鏈接名').click()實現(xiàn)。

解決方法:對于插件上傳,需要操作Windows控件的,可以通過安裝AutoIt工具、編寫腳本、保存為“.au3”文件、轉(zhuǎn)換成“.exe”文件,再由自動化腳本os.system("D:\\upfile.exe")實現(xiàn)上傳/下載。

* 雖然這種方法可以解決文件上傳、下載的操作問題,但是并不推薦。因為通過python調(diào)用exe程序并不在python的可控范圍內(nèi),執(zhí)行多長時間,執(zhí)行過程是否出錯,都無從自動化過程得知。

九、資源是通過JavaScript加載的情況

http://www.itdecent.cn/p/de5e779048de

/

/

/

/

十、firefox安全性強,不允許跨域調(diào)用出現(xiàn)報錯

錯誤描述:uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMNSHTMLDocument.execCommand]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location:

解決辦法:Firefox 要取消XMLHttpRequest的跨域限制的話,第一是從 about:config 里設(shè)置 signed.applets.codebase_principal_support = true; (地址欄輸入about:config 即可進行firefox設(shè)置);第二就是在open的代碼函數(shù)前加入類似如下的代碼:

try{netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");}catch(e){alert("Permission UniversalBrowserRead denied.");}

17人點贊

Python

作者:小仙女本人呀

鏈接:http://www.itdecent.cn/p/83087c24ab19

來源:簡書

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容