2021.11.09 - [Selenium] 암시적 대기(Implicit Wait)
위 글에서는 Selenium의 대기 방식 중 웹 페이지가 모두 로딩될 때까지 기다리는 암시적 대기 방식에 대해 다뤘다.
이 글에서는 Selenium의 대기 방식 중, 명시적 대기 방식에 대해 다룬다.
명시적 대기 (Explicit Wait)
지정한 요소가 웹 페이지 내에서 지정한 조건을 만족할 때까지 기다린다.
필요성
Ajax를 이용해 동적 변경이 발생하는 웹 페이지인 경우 Web Elemnet가 나타날 때까지 시간이 걸릴 수 있는데, Web Element가 나타나기 전에 참조하고자 하면 오류가 발생할 수 있으므로 대기하는 시간이 필요하다.
암시적 대기는 웹 페이지 전체가 로딩될 때까지 기다리는 반면 명시적 대기는 특정 요소가 특정 조건이 될 때까지 기다리는 방법으로, 웹 페이지의 모든 요소를 기다리지 않을 수 있다.
코드
공식 문서(https://selenium-python.readthedocs.io/waits.html) 내 예제 코드이다.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
WebDriverWait
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None) 객체를 생성한다.
- driver : 사용할 webdriver 객체를 전달한다.
- timeout : 최대 대기 시간을 초 단위로 지정한다.
- poll_frequency : 대기하는 동안 Element를 호출하는 시간 간격이다. 기본값은 0.5초다.
- ignored_exceptions : Element 호출 시도 시 발생하는 Exception 중 어떤 예외를 무시할지 지정한다. 기본적으로 NoSuchElementException만 무시하며, 그 외의 예외를 무시하고자 할 때에는 iterable 한 형식으로 전달한다.
until/until_not
WebDriverWait이 제공하는 메서드이다.
- until(method, message='')
method를 실행한 반환 값이 False가 아닐 때까지 기다린다.
# 람다식으로 someId라는 id를 가진 element를 찾을 때 False가 아닐 값을 반환할 때까지 until(lambda x: x.find_element_by_id(“someId”))
- until_not(method, message='')
method를 실행한 반환값이 False일 때까지 기다린다.
until_not(lambda x: x.find_element_by_id(“someId”).is_displayed())
message 매개변수에 값을 전달해 에러 메시지를 설정할 수 있다.
Expected Conditions
Selenium에서는 until/until_not에서 빈번하게 사용되는 대기 조건, 즉 method을 미리 정의하여 제공하고 있다. 사용 시에는 아래와 같이 import가 필요하다.
from selenium.webdriver.support import expected_conditions as EC
목록
- title_is
- title_contains
- presence_of_element_located : Element가 DOM에 존재하는지 확인한다. 브라우저 상에 Element가 보이지 않아도 DOM 상에 존재하기만 하면 해당 WebElement 객체를 반환한다.
- visibility_of_element_located : Element가 visible 한 지 확인한다.
- visibility_of
- presence_of_all_elements_located
- text_to_be_present_in_element : Element의 innerText가 특정 문자열로 표시되었는지 확인한다.
- text_to_be_present_in_element_value
- frame_to_be_available_and_switch_to_it
- invisibility_of_element_located
- element_to_be_clickable : Element가 clickable 상태가 되는지 확인한다.
- staleness_of
- element_to_be_selected
- element_located_to_be_selected
- element_selection_state_to_be
- element_located_selection_state_to_be
- alert_is_present
Locate elements By
HTML 내에서 요소를 찾을 때 어떤 속성으로 찾을지 정의한다. 즉, find_element_by_XXX 함수에서 찾는 속성을, 함수 내에서 매개변수로 지정하는 것과 같다. 사용 시에는 By 모듈을 import 해야 한다.
from selenium.webdriver.common import By
목록
- CLASS_NAME = 'class name'
- ID = 'id'
- NAME = 'name'
- TAG_NAME = 'tag name'
- XPATH = 'xpath'
- PARTIAL_LINK_TEXT = 'partial link text'
- LINK_TEXT = 'link text'
- CSS_SELECTOR = 'css selector'
참고 문서
https://velog.io/@log327/Python-Selenium-Explicit-Waits-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
https://selenium-python.readthedocs.io/waits.html
https://selenium-python.readthedocs.io/api.html#selenium.webdriver.support.wait.WebDriverWait.until
https://thesoul214.github.io/python/2019/06/01/Python-Selenium-2.html