Python

[Selenium] 명시적 대기 (Explicit Wait)

비번변경 2021. 11. 13. 15:58

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이 제공하는 메서드이다.

  1. until(method, message='')
    method를 실행한 반환 값이 False가 아닐 때까지 기다린다.
    # 람다식으로 someId라는 id를 가진 element를 찾을 때 False가 아닐 값을 반환할 때까지
    until(lambda x: x.find_element_by_id(“someId”))
  2. 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