2017-01-22 5 views
1

Hallo, ich bin neu in SeleniumSelen StaleElementReferenceException

ich die Java library verwende, habe bereits versucht, sowohl die Chrome und die Firefox Treiber.

Ich führe eine Schleife. Das Interessante daran ist, dass die Schleife manchmal 3, 2 Mal funktioniert und nicht immer in der gleichen Iteration fehlschlägt. Ich nehme an, dass es mit einer Art Race-Bedingung zu tun hat (wie die Seite warten, um zu laden). Wenn ich im Debug-Modus laufe, scheint es perfekt zu funktionieren.

Ich habe bereits Vorschläge aus anderen Antworten wie wait explicitly und implicitly versucht, aber immer noch nicht geholfen. Vielleicht, wenn Sie den Code sehen, können Sie mir eine Hand geben.

Dies geht in eine Schleife.

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

Die Lösung ist ein Gesamt Hack. Ich verstehe immer noch nicht, aber es macht den Job. Wenn jemand versteht warum, lass es mich wissen.

Ich verschiebe nur alle Wartezeiten und es funktioniert besser. Ich nahm auch den Vorschlag von @Cyril, um die Wiederholung neu zu laufen, wenn die Ausnahme entlang einiger Datenüberprüfungen geworfen wurde, um sicherzustellen, dass ich alles bekam, was ich wollte.

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"))); 

Antwort

2

StaleElementReferenceException bedeutet, dass die DOM-Elemente, die Sie bekamen zugreifen geändert oder aus dem DOM entfernt. Also zu warten, bis die Elemente sichtbar oder präsent sind, hilft nicht (sie können auch danach aktualisiert werden).

Sie können die Ausnahme wahrscheinlich beheben, indem Sie explizit über Thread.sleep für 5 Sekunden warten, bevor Sie DOM-Elemente nachschlagen. Eine andere Option ist look up the element again if the exception is thrown. Aber es funktioniert nur gut für einzelne Elemente.

+0

Vielen Dank für Ihre Antwort Ich nahm Ihren letzten Vorschlag. Ich hacke es irgendwie mit einigen anderen Änderungen (siehe oben). Ich bin nicht 100% glücklich, aber es ist der Job. – Altober

2

Um die StaleElementReferenceException zu vermeiden, können Sie das Attribut während des Find-Elements erhalten. Hier ist ein Ausschnitt (nth-child erster Index ist 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")); 
} 

diese Weise die einzige Chance für die Ausnahme ist, wenn die Elementänderungen zwischen den findElement und den getAttribute was unwahrscheinlich ist (oder das Tabellenelement Änderungen - searchResults). Natürlich gibt es bessere Möglichkeiten, um dies zu erreichen, wie eine Wrapper-Funktion um findElement oder Verwendung von Page Object Pattern, aber für Ihren Fall sollte es ausreichen.

BEARBEITEN: Ihre Lösung funktioniert wahrscheinlich, weil es das Skript warten lässt, bis die Seite vollständig geladen ist, und dann die Elemente nicht mehr ändern.

+1

@Atember, schauen Sie sich diese Lösung an, es scheint perfekt. –

+0

Hallo, vielen Dank. Ich habe das ausprobiert, aber nach ein paar Wiederholungen hängt die Ausführung in der for-Schleife. Ich werde weiter suchen und ein Update bringen. – Altober

+1

Dank @Grzegorz machte meinen Tag;). Was das Hängen betrifft, nehme ich an, dass es daran liegt, dass Sie viele Elemente aus dem "a" -Tag haben, und es fragt das DOM nach jedem dieser ...Also, wenn Sie die Liste mit einem spezifischeren Locator eingrenzen können, nehme ich an, dass es hilft. d. h. 'By.cssSelector (" a.someClass ")' – Moshisho

Verwandte Themen