轉自https://www.cnblogs.com/lizm166/p/9995612.html
一、問題描述
在做web應用的自動化測試時,定位元素是必不可少的,這個過程經常會碰到定位不到元素的情況:
報錯信息: no such element: Unable to locate element: {"method":"xpath","selector":"xpath"}
二、分析以及解決方案
1,原因一以及解決方案
(1)原因:
Frame/Iframe原因定位不到元素:這個是最常見的原因,首先要理解下frame的實質,frame中實際上是嵌入了另一個頁面,而webdriver每次只能在一個頁面識別,因此需要先定位到相應的frame,對那個頁面里的元素進行定位。
(2)解決方案:
如果iframe有name或id的話,直接使用switch_to_frame("name值")或switch_to_frame("id值")。如下:
driver=webdriver.Firefox() driver.get(r'http://www.126.com/') driver.switch_to_frame('x-URS-iframe') #需先跳轉到iframe框架 username=driver.find_element_by_name('email') username.clear()
#先定位到iframe elementi= driver.find_element_by_class_name('APP-editor-iframe') #再將定位對象傳給switch_to_frame()方法 driver.switch_to_frame(elementi)
2,原因二以及解決方案
(1)原因:
Xpath描述錯誤原因:由於Xpath層級太復雜,容易犯錯。但是該定位方式能夠有效定位絕大部分的元素,建議掌握。
(2)解決方案:
<1>.可以使用Firefox的firePath,復制xpath路徑。該方式容易因為層級改變而需要重新編寫過xpath路徑,不建議使用,初學者可以先復制路徑,然后嘗試去修改它。
<2>.提高下寫xpath的水平.
如何檢驗編寫的Xpath是否正確?

3,原因三以及解決方案
(1)原因
頁面還沒有加載出來,就對頁面上的元素進行的操作:這種情況一般說來,可以設置等待,等待頁面顯示之后再操作,這與人手工操作的原理一樣:
(2)解決方案
導入時間模塊。
time.sleep(3)
4,原因四以及解決方案
(1)原因
動態id定位不到元素:每次調用頁面出現的元素的ID會動態隨機分配。
(2)解決方案
如果發現是動態id,推薦使用xpath的相對路徑方法查找到該元素。
5,原因五以及解決方案
(1)原因
二次定位,如彈出框登錄:如百度登錄彈出框登錄百度賬號,需先定位到百度彈出框,然后再定位到用戶名密碼登錄。
(2)解決方案
''' Project:登錄百度賬號 ''' from selenium import webdriver import time driver = webdriver.Firefox() driver.get("http://www.baidu.com/") time.sleep(3) #點擊登錄:有些name為tj_login的元素為不可見的,點擊可見的那個登錄按鈕即可。 #否則會報:ElementNotVisibleException element0=driver.find_elements_by_name("tj_login") for ele0 in element0: if ele0.is_displayed(): ele0.click() #在登錄彈出框,需先定位到登錄彈出框 #否則會報:NoSuchElementException element1=driver.find_element_by_class_name("tang-content") element11=element1.find_element_by_id("TANGRAM__PSP_8__userName") element11.clear() element11.send_keys("登錄名") element2=element1.find_element_by_id("TANGRAM__PSP_8__password") element2.clear() element2.send_keys("密碼") element3=element1.find_element_by_id("TANGRAM__PSP_8__submit") element3.click() element3.submit() try: assert "登錄名" in driver.page_source except AssertionError as e: print "登錄失敗" else: print "登錄成功" time.sleep(3) finally: print "測試記錄:已測試" driver.close()
6,原因六以及解決方案
(1)原因
不可見元素定位:如上百度登錄代碼,通過名稱為tj_login查找的登錄元素,有些是不可見的。
(2)解決方案
加一個循環判斷,找到可見元素(is_displayed())點擊登錄即可。
7,原因七以及解決方案
(1)原因
firefox安全性強,不允許跨域調用出現報錯:因為firefox安全性強,不允許跨域調用。
(2)解決方案
Firefox 要取消XMLHttpRequest的跨域限制的話,
第一是從 about:config 里設置:signed.applets.codebase_principal_support = true; (地址欄輸入about:config 即可進行firefox設置)
try{ netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } catch (e) { alert("Permission UniversalBrowserRead denied."); }
8,原因八以及解決方案
(1)原因
窗口切換:窗口句柄還處在上一個窗口,導致無法定位新窗口的元素。
(2)解決方案
String currentWindow = driver.getWindowHandle();//獲取當前窗口句柄 Set<String> handles = driver.getWindowHandles();//獲取所有窗口句柄 for(String windowId : handles){ if(!windowId.equals(currentWindow)){ driver.switchTo().window(windowId); System.out.println(driver.getCurrentUrl()); break; } }