2017-01-22 63 views
1

您好我是新來Selenium硒StaleElementReferenceException

我現在用的是Java library,已經試用過ChromeFirefox驅動程序。

我正在運行一個循環。有趣的是,循環有時會工作3次,2次,並不總是在同一次迭代中失敗。我認爲它必須處理某種競爭條件(如等待頁面加載)。如果我運行在調試模式下,它似乎完美工作。

我已經嘗試了其他答案,如wait explicitlyimplicitly,但仍然沒有幫助。也許如果你看到代碼,你可以幫我一把。

這進入循環。

WebDriverWait wait = new WebDriverWait(driver,20); 
WebElement searchResults = driver.findElement(new By.ById("searchresults")); 
searchResults = searchResults.findElement(new By.ByClassName("table")); 
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.tagName("a"))); 
List<WebElement> list=searchResults.findElements(By.tagName("a")); 
for(WebElement w: list) { 
    result.add(w.getAttribute("href")); //EXCEPTION HAPPENS ALWAYS HERE 
} 

SOLUTION

的解決方案是一個總的黑客。我仍然不明白,但是它完成了這項工作。如果有人明白爲什麼請讓我知道。

我只是移動所有的等待,它表現更好。我還採取了@Cyril的建議來重新運行迭代,如果在某些數據檢查中拋出異常,以確保我獲得了我想要的所有結果。

WebDriverWait wait = new WebDriverWait(driver,20); 
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(new By.ById("searchresults"))); 
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(new By.ByClassName("table"))); 
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.tagName("a"))); 

回答

2

StaleElementReferenceException意味着您正在訪問的DOM元素已從DOM中更改或刪除。所以等到元素可見或不存在時(他們仍然可以在此之後更新)。

在查找任何DOM元素之前,您可以通過明確地等待5秒鐘通過Thread.sleep修復異常。

另一種選擇是look up the element again if the exception is thrown。但它只適用於單個元素。

+0

非常感謝您的回答我接受了您最後的建議。我以某種方式破解了一些其他的變化(見上文)。我不是100%高興,但這是工作。 – Altober

2

爲了避免StaleElementReferenceException,您可以在find元素中獲取屬性。這裏有一個片段(nth-child第一指數爲1):

List<WebElement> list=searchResults.findElements(By.tagName("a")); 
for(int i = 1; i < list.length; i++) { 
    result.add(searchResults.findElement(By.cssSelector("a:nth-child(" + i + ")")).getAttribute("href")); 
} 

這樣的異常的唯一機會是,如果(表元素的變化或 - searchResults)的findElementgetAttribute這是不可能的元素變化。 當然,還有更好的方法來實現這個效果,比如findElement或使用頁面對象模式的包裝函數,但對於你的情況它應該足夠了。

編輯:您的解決方案可能工作,因爲它使腳本等待,直到頁面完全加載,然後元素不再改變。

+1

@Altober,看看這個解決方案,看起來很完美。 –

+0

嗨,非常感謝。我嘗試過,但由於某種原因,經過幾次迭代後,執行掛在for循環中。我會繼續探索並帶來一些更新。 – Altober

+1

感謝@Grzegorz創造了我的一天;)。至於懸掛,我認爲這是因爲你有'a'標籤中的很多元素,並且它爲每個元素輪詢DOM ...所以,如果你可以通過使用更具體的定位器縮小列表範圍,我認爲它會有所幫助。即'By.cssSelector(「a.someClass」)' – Moshisho

相關問題