다음에 포스팅할 항목을 테스트하기 위해 서울시 전자도서관에 Selenium을 사용하여 로그인하려고 하는데 다음과 같은 에러가 발생하였다.
원인은 서울시 전자도서관에 처음 접속하게 되면 추천 도서 목록을 가져오는 데 걸리는 시간이 길어 해당 목록을 가져올 때까지 로딩바를 표시하게 된다.
로딩바가 표시되는 동안에 요소들을 클릭할 수 없는데, 이때 클릭 이벤트가 발생하여 의도했던 요소가 아닌 다른 요소가 해당 클릭 이벤트를 수신하게 되어 에러가 발생하였다.
에러 로그를 읽어보면 Other element would receive the click: <div class="wrap-loading">...</div>라고 되어있다.
즉, 우리는 저 <div class="wrap-loading">이 사라질 때까지 대기하였다가 로그인 버튼을 클릭하면 되는 것이다.
물론 presence_of_element_located가 아닌 element_to_be_clickable를 사용해 보았지만 동일한 오류가 발생하였다.
화면에서 요소가 사라지는 것을 대기하는 방법으로는 두 가지 방법이 있다.
1. invisibility_of_element_located를 사용하여 대기하기
WebDriverWait(driver, 5).until(
EC.invisibility_of_element_located((By.XPATH, '//div[@class="wrap-loading"]'))
)
login_button.click()
WebDriverWait()와 invisibility_of_element_located()를 사용하여 해당 요소가 보이지 않는 것을 대기한 후, 로그인 버튼을 클릭하면 쉽게 해결할 수 있다.
원하는 데로 동작하나 요소가 사라진 후에도 꽤나 시간이 걸린다.
2. is_displayed를 사용하여 대기하기
loading = driver.find_element(By.XPATH, '//div[@class="wrap-loading"]')
while loading.is_displayed():
"WAIT"
login_button.click()
Selenium의 element는 is_displayed()라는 요소가 표시되고 있는지 확인하는 메서드를 가지고 있다.
이를 이용하여 while 문과 조건으로 is_displayed()를 사용하여 해당 요소가 사라질 때까지 대기를 줄 수 있다.
invisibility_of_element_located()를 사용한 대기와는 다르게 해당 요소가 사라지자마자 클릭 이벤트가 발생하는 것을 볼 수 있다.
두 가지 방법 모두 원하는 데로 동작하는 것을 확인할 수 있는데, invisibility_of_element_located()를 이용한 방식이 왜 요소가 사라진 이후에 시간이 조금 더 소요되는지 알아볼 필요가 있을 것 같다.