셀레니움(Selenium)의 대기(Waits)

셀레니움으로 크롤링을 하다보면 접근하려는 요소가 존재하지 않는다는 의미의 NoSuchElementException에러가 발생하는 경우가 발생하곤 합니다. 대상 페이지가 서버와의 통신이 계속적으로 진행되는 동적페이지이거나, 인터넷 회선 지연 등의 원인으로 크롤링을 원하는 요소가 html 내에 존재하기 전에 접근을 시도할 때 발생하는 에러인데요,

그래서 Selenium은 접근을 원하는 요소가 생성되기까지 대기(Waits)하는 기능을 제공합니다. 우리는 이러한 기능을 사용하여 크롤링이 진행되는 전체적인 프로세스가 에러 없이 진행되도록 코딩할 수 있습니다.

요소를 찾을 수 없는 사례 살펴보기

NoSuchElementException에러가 발생하는 경우를 아래의 예시를 통해 직접 실습해보도록 하겠습니다.

위 html은 처음 페이지가 로드될 때에 p태그가 없습니다. 하지만 로드된 이후 버튼을 클릭하여 자신이 원하는 시점에 p태그를 생성할 수 있도록 짜여져 있습니다. 즉, 실제 크롤링을 할 때 페이지의 특정 요소가 생성되는 시간이 지연되는 상황을 가정하여 구성었으며, 원한다면 버튼을 클릭하여 p태그의 생성시점을 조절할 수 있습니다.

< 버튼 클릭 전후>

위 html을 다운로드하여 실습용도로 사용하실 수 있습니다.

powered by Advanced iFrame free. Get the Pro version on CodeCanyon.

위의 코드는 위에서 언급한 html을 실행한 코드입니다. 페이지 로드시 p태그가 생성되지 않으므로 NoSuchElementException에러가 발생하는 것을 확인할 수 있습니다. 이를 해결하기 위하여는 아래에 소개하는 셀레니움의 대기(Waits)기능을 이용하면 됩니다.

대기(Waits)

대기에는 아래와 같은 두 가지 유형이 있습니다.

WaitsExplicit Waitimplicit Wait
의미명시적 대기암시적 대기
대기 조건조건이 True가 될 때까지 지정된 시간만큼 대기지정된 시간만큼 대기
적용 요소특정 요소에 적용모든 요소에 적용

Explicit Wait

powered by Advanced iFrame free. Get the Pro version on CodeCanyon.

Explicit Wait는 명시된 조건을 충족(True)할 때 까지 대기합니다. 위 코드에서 Explicit Wait를 구성하는 코드는 밑줄 친 부분이며 아래와 같은 구조로 코딩하면 됩니다.

  1. WebDriverWait 클래스의 객체 생성시 Webdriver 객체와 대기시간(timeout)을 지정합니다.
  2. WebDriverWait의 until 메서드에는 대기의 조건을 명시합니다.
  3. 구체적인 대기의 조건은 EC(expected_conditions)모듈에 By 클래스와 패턴을 튜플의 형태로 전달합니다.

expected_conditions 모듈과 By 클래스

위의 세 번째 항목에서 알아본 것 처럼 until메서드에 EC모듈과 By클래스를 사용하여 대기의 조건을 명시해야 합니다.

이 중 expected_conditions 모듈은 요소에 대한 여러 상황이 메서드로 정의되어 있습니다. 따라서 요소에 접근할 때에는 자신이 크롤링할 요소에 적합한 메서드를 사용하면 됩니다. 보통은 요소가 html 내 존재하게 될 때까지 대기하는 presence_of_element_located가 많이 사용됩니다.

아래는 expected_conditions 모듈의 메서드 목록입니다.

  • title_is
  • title_contains
  • presence_of_element_located
  • visibility_of_element_located
  • visibility_of
  • presence_of_all_elements_located
  • text_to_be_present_in_element
  • text_to_be_present_in_element_value
  • frame_to_be_available_and_switch_to_it
  • invisibility_of_element_located
  • element_to_be_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

By 클래스에는 요소의 위치를 찾는 여러 종류의 Locator가 있습니다. 필요한 Locator를 사용하여 EC 모듈에 패턴과 함께 튜플로 전달하면 됩니다.

Locators내용
CLASS_NAMEclass name
CSS_SELECTORcss selector
IDid
LINK_TEXTlink text
NAMEname
PARTIAL_LINK_TEXTpartial link text
TAG_NAMEtag name
XPATHxpath

아래는 Explicit Wait에 대해 이제까지 배운 내용을 구현한 이미지입니다.

파이썬 코드를 실행하고, 페이지가 로드 되면 버튼을 눌러 p 태그를 생성합니다. 그러면 Explicit Wait로 대기중이던 셀레니움의 코드가 에러 없이 정상적으로 출력되는 것을 확인할 수 있습니다.

Implicit Wait

Implicit wait는 지정된 시간동안 모든 요소가 로드될 때까지 대기합니다.

powered by Advanced iFrame free. Get the Pro version on CodeCanyon.

Implicit Wait를 실행하기 위하여는 위 코드의 밑줄친 부분처럼 webdriver 객체의 메소드로 implicitly_wait를 입력하면 됩니다.

코드를 실행해보면 요소를 5초간 기다리게 됩니다. 대기 중에 페이지 상에서 버튼을 클릭했다면 p태그가 로드 되어 p태그를 찾게 됩니다. 5초가 모두 지나지 않더라도 5초 내 요소를 찾았다면 대기 작업은 완료되고, 다음 코드가 실행되어 print문이 실행되는 것을 확인할 수 있습니다.

Leave a Comment