Java Selenium StaleElementReferenceException
[에러 메시지] org.openqa.selenium.StaleElementReferenceException: stale element reference: stale element not found
오늘 회사에서 크롤링을 하다가 해당 오류에 직면했다. 이 오류의 원인은 여러가지가 있기에 찾기 힘들다.
- DOM이 변경되어 이전에 참조한 요소를 사용할 수 없는 경우
- 해당 요소가 사라졌거나 새로 고쳐진 경우
나의 경우엔 1번이었다.
해당 오류가 난 코드는 이렇다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void search(WebDriver driver) {
Queue<WebElement> q = new LinkedList<>();
q.addAll(driver.findElements(By.tagName("a")));
while(!q.isEmpty()) {
WebElement now = q.poll();
if (now.isEnabled() && !now.getAttribute("href").contains(url))
continue;
System.out.println(now.getAttribute("href"));
driver.get(now.getAttribute("href"));
q.addAll(driver.findElements(By.tagName("a")));
}
}
driver에서 a 태그가 있는 요소만을 큐에 넣어 링크를 출력하는 코드였다. 어떻게 해결해야할까 고민이 많았으나 이 글을 읽고 해결할 수 있었다.
When you navigate away from the first page all
WebElements
in the allLinks list get lost.
첫 번째 페이지에서 벗어나면 모든 WebElement
가 손실된다고 한다. 이 글을 읽고 아래와 같이 수정하였다. whlie문 안에서 url을 찾는 것이 아닌, 처음부터 url을 찾아 String 목록 형태로 저장하는 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void search(WebDriver driver) {
Queue<String> q = new LinkedList<>();
q.addAll(convertWebElementToString(driver));
while(!q.isEmpty()) {
String now = q.poll();
if (now.isEnabled() && !now.contains(url))
continue;
if (!urlSet.isEmpty() && urlSet.contains(now))
continue;
System.out.println(now);
driver.get(now);
q.addAll(convertWebElementToString(driver));
}
}
void convertWebElementToString(WebDriver driver) {
return driver.findElements(By.tagName("a")).stream()
.map(link -> link.getAttribute("href"))
.collect(Collectors.toList());
}
This post is licensed under CC BY 4.0 by the author.