2017-01-22 13 views
1

こんにちは私はすでにChromeFirefoxドライバの両方を試してみました、私はJava libraryを使用していますSeleniumセレンStaleElementReferenceException

に新しいです。

私はループを実行しています。興味深いのは、ループが時々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要素を調べる前に、Thread.sleepで明示的に5秒待って例外を修正できます。

もう1つのオプションは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")); 
} 

その方法はほとんどありませんfindElementgetAttribute間の要素が変更された場合の例外のための唯一のチャンスはある(またはテーブル要素の変更 - searchResults)。 もちろん、これを実現するにはfindElementのラッパー関数やPage Object Patternを使用するのが良い方法がありますが、十分なはずです。

EDIT:あなたのソリューションは、ページが完全に読み込まれて要素がもう変化しなくなるまでスクリプトを待機させるため、おそらく機能します。

+1

@Altober、このソリューションを見て、それは完璧だと思われる。 –

+0

こんにちは、ありがとう。私はそれを試しましたが、何らかの理由で2回の繰り返しの後に、forループで実行がハングアップします。私は探検し続けていく予定です。 – Altober

+1

ありがとう@Grzegorzは私の日を作った;)。ぶら下がりについては、 'a'タグからたくさんの要素があり、これらのそれぞれについてDOMをポーリングするので、それが前提です...したがって、より具体的なロケータを使用してリストを絞り込むことができれば、それは役に立ちそうです。すなわち、By.cssSelector( "a.someClass") ' – Moshisho

関連する問題