Java+Selenium設(shè)置元素等待的方法詳解
簡介
本文主要介紹如何使用java代碼利用Selenium操作瀏覽器,某些網(wǎng)頁元素加載慢,如何操作元素就會把找不到元素的異常,此時需要設(shè)置元素等待,等待元素加載完,再操作。
設(shè)置元素等待
很多頁面都使用 ajax 技術(shù),頁面的元素不是同時被加載出來的,為了防止定位這些尚在加載的元素報錯,可以設(shè)置元素等來增加腳本的穩(wěn)定性。webdriver 中的等待分為 顯式等待 和 隱式等待。
顯式等待
顯式等待:設(shè)置一個超時時間,每個一段時間就去檢測一次該元素是否存在,如果存在則執(zhí)行后續(xù)內(nèi)容,如果超過最大時間(超時時間)則拋出超時異常(TimeoutException)。顯示等待需要使用 WebDriverWait,同時配合 until 或 not until 。下面詳細(xì)講解一下。
import org.openqa.selenium.By; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; /** * @author Lenovo */ public class SeleniumDemo { private final static String webDriver = "webdriver.chrome.driver"; private final static String webDriverPath ="E:\\chromedriver\\chromedriver.exe"; public static void main(String[] args) throws InterruptedException { System.setProperty(webDriver, webDriverPath); WebDriver driver= new ChromeDriver(); //博客主頁 driver.get("https://blog.csdn.net/weixin_40986713"); WebElement element=driver.findElement(By.className("submit")); long start=System.currentTimeMillis(); //等待5秒 WebDriverWait shortWait = new WebDriverWait(driver, 5); //5秒內(nèi)元素加載出來就執(zhí)行點擊 shortWait.until(ExpectedConditions.elementToBeClickable(element)).click(); //忽略找不到元素異常 shortWait.ignoring(NoSuchElementException.class); System.out.println("耗時 "+(System.currentTimeMillis()-start)+" ms"); } }
- until 指定預(yù)期條件的判斷方法,在等待期間,每隔一段時間調(diào)用該方法,判斷元素是否存在,直到元素出現(xiàn)。
- ignoring 指定忽略的異常,如果設(shè)定的執(zhí)行等待超時的時間段內(nèi),忽略指定的異常,讓程序繼續(xù)進行。
隱式等待
隱式等待也是指定一個超時時間,如果超出這個時間指定元素還沒有被加載出來,就會拋出 NoSuchElementException 異常。
除了拋出的異常不同外,還有一點,隱式等待是全局性的,即運行過程中,如果元素可以定位到,它不會影響代碼運行,但如果定位不到,則它會以輪詢的方式不斷地訪問元素直到元素被找到,若超過指定時間,則拋出異常。
使用 driver.manage().timeouts().implicitlyWait() 來實現(xiàn)隱式等待,使用難度相對于顯式等待要簡單很多。
示例:打開個人主頁,設(shè)置一個隱式等待時間 5s,通過 id 定位一個不存在的元素,最后打印 拋出的異常 與 運行時間。
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.util.concurrent.TimeUnit; /** * @author Lenovo */ public class SeleniumDemo { private final static String webDriver = "webdriver.chrome.driver"; private final static String webDriverPath ="E:\\chromedriver\\chromedriver.exe"; public static void main(String[] args) throws InterruptedException { System.setProperty(webDriver, webDriverPath); WebDriver driver= new ChromeDriver(); //博客主頁 driver.get("https://blog.csdn.net/weixin_40986713"); //設(shè)置全局隱式等待 driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); long start=System.currentTimeMillis(); try { driver.findElement(By.className("tarzan")); }catch (Exception e){ System.out.println(e); System.out.println("耗時 "+(System.currentTimeMillis()-start)+" ms"); } } }
代碼運行到 driver.findElement(By.className("tarzan"));這句之后觸發(fā)隱式等待,在輪詢檢查 5s 后仍然沒有定位到元素,拋出異常。
強制等待
用java代碼強制當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行)
使用 time.sleep() 強制等待,設(shè)置固定的休眠時間,對于代碼的運行效率會有影響。
以上面的例子作為參照,將 隱式等待 改為 強制等待。
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; /** * @author Lenovo */ public class SeleniumDemo { private final static String webDriver = "webdriver.chrome.driver"; private final static String webDriverPath ="E:\\chromedriver\\chromedriver.exe"; public static void main(String[] args) throws InterruptedException { System.setProperty(webDriver, webDriverPath); WebDriver driver= new ChromeDriver(); //博客主頁 driver.get("https://blog.csdn.net/weixin_40986713"); long start=System.currentTimeMillis(); //等待5s Thread.sleep(5000); try { driver.findElement(By.className("tarzan")); }catch (Exception e){ System.out.println(e); System.out.println("耗時 "+(System.currentTimeMillis()-start)+" ms"); } } }
值得一提的是,對于定位不到元素的時候,從耗時方面隱式等待和強制等待沒什么區(qū)別。但如果元素經(jīng)過 2s 后被加載出來,這時隱式等待就會繼續(xù)執(zhí)行下面的代碼,但 sleep還要繼續(xù)等待 3s。
總結(jié)
推薦使用的隱式等待,也就是implicitlyWait。
理由:
使用implicitlyWait或者明確等待(explicitly wait),方法參數(shù)是等待的最大時長。
也就是只要一找到元素,就會立刻執(zhí)行下一行代碼,不會強制等待參數(shù)里設(shè)置的時間。
而第三種(線程休眠)則不同,會強制等待設(shè)置的時間。設(shè)想一下,如果你的工程有好幾百個case,
需要等待的元素都采用第三種,會大大加長所有case執(zhí)行的時間,而你又急著要report,豈不是很慘。
使用implicitlyWait,webdriver會自動應(yīng)用到case中的所有element中。在啟動瀏覽器(driver.get)之后設(shè)置上,這樣就不用針對某個元素去設(shè)置了,簡直太方便了,不過有些特殊的元素,確實等待時間較長的,可以再采用explicit wait。
如果implicitlyWait和explicitly wait都在用在代碼里,那么最大等待時間不是兩個時間的疊加,而是取最大值。
到此這篇關(guān)于Java+Selenium設(shè)置元素等待的方法詳解的文章就介紹到這了,更多相關(guān)Java Selenium設(shè)置元素等待內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Spring Cloud Zuul實現(xiàn)動態(tài)路由示例代碼
Spring Cloud Zuul路由是微服務(wù)架構(gòu)的不可或缺的一部分,提供動態(tài)路由,監(jiān)控,彈性,安全等的邊緣服務(wù)。下面這篇文章主要給大家介紹了關(guān)于利用Spring Cloud Zuul實現(xiàn)動態(tài)路由的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-09-09springmvc4+hibernate4分頁查詢功能實現(xiàn)
本篇文章主要介紹了springmvc4+hibernate4分頁查詢功能實現(xiàn),Springmvc+hibernate成為現(xiàn)在很多人用的框架整合,有興趣的可以了解一下。2017-01-01當(dāng)mybatis返回值遇見內(nèi)部類的問題
這篇文章主要介紹了當(dāng)mybatis返回值遇見內(nèi)部類的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12Java Dubbo協(xié)議下的服務(wù)端線程使用詳解
Dubbo是阿里開源項目,國內(nèi)很多互聯(lián)網(wǎng)公司都在用,已經(jīng)經(jīng)過很多線上考驗。Dubbo內(nèi)部使用了Netty、Zookeeper,保證了高性能高可用性,使用Dubbo可以將核心業(yè)務(wù)抽取出來,作為獨立的服務(wù),逐漸形成穩(wěn)定的服務(wù)中心2023-03-03Java格式化輸出詳細(xì)講解(printf、print、println、format等)
Java的格式化輸出等同于String.Format,與C有很大的相似,下面這篇文章主要給大家介紹了關(guān)于Java格式化輸出(printf、print、println、format等)的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03SpringMVC KindEditor在線編輯器之文件上傳代碼實例
這篇文章主要介紹了SpringMVC KindEditor在線編輯器之文件上傳代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09spring boot整合scurity做簡單的登錄校驗的實現(xiàn)
這篇文章主要介紹了spring boot整合scurity做簡單的登錄校驗的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04