[토이 프로젝트] 자동 갱신 게임 명부 제작(4) - selenium wait() 사용하기

chaejm55·2022년 5월 7일
0

0. 이번 단계 진행 아이디어

selenium의 wait()를 사용하여 좀더 깔끔하게 갱신을 처리해보자!😀

1. selenium wait 살펴보기

1) time.sleep

기존 코드에서 갱신을 기다리기 위해 사용한 코드입니다. 무조건 지정한 시간만큼 기다리는 방법입니다.

2) implicitly wait

웹 페이지 로딩 시까지 암묵적으로 기다리는 메서드입니다. 지정한 시간만큼 기다리는데, 지정한 시간이전에 웹 페이지가 로딩 되면 다음 명령을 실행합니다. 또한 지정한 시간이 넘어가면 웹 페이지 로딩이 끝나지 않더라도 다음 명령을 실행합니다.

3) explicitly wait(webdriver wait)

전체적인 웹 페이지 로딩이 아닌 내가 원하는 element가 원하는 상태가 될 때까지 명시적으로 기다리는 메서드입니다.
상황별로 많은 메서드들이 정의 되어있으며 대표적으로 EC.presence_of_element_located()를 많이 사용합니다. 메서드 목록은 링크를 참조바랍니다.
여기서는EC.text_to_be_present_in_element()를 사용해보았습니다.

2. wait를 사용해 코드 작성하기

explicitly wait를 적용할 부분은 갱신버튼을 가져오는 부분과 클릭하는 부분입니다.


import gspread
import time
from selenium import webdriver
from selenium.common.exceptions import UnexpectedAlertPresentException, WebDriverException, TimeoutException, \
    NoSuchElementException
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager

TIMEOUT = 15  # 타임아웃 시간 설정


def main():
	...
    
    for character in character_list:
        if character == '' or character in worlds:
            continue
        base_url = 'https://maple.gg/u/'
        url = base_url + character
        try:
            driver.get(url)  # 검색 결과 페이지로 이동
            driver.implicitly_wait(TIMEOUT)
        except WebDriverException:
            print("웹 페이지 로딩 중 오류가 발생했습니다.")
            time.sleep(3)  # 스크래핑 사이 딜레이 삽입
            continue

        try:
            refresh = driver.find_element(by=By.XPATH, value='//*[@id="btn-sync"]')  # 갱신버튼 가져오기
        except NoSuchElementException:
            print("올바르지 않은 캐릭터명이거나 올바르지 않은 경로입니다.")
            continue
        else:
            try:
                refresh.click()  # 갱신버튼 클릭
            except WebDriverException:
                print("웹 페이지 로딩이 완료되지 않았거나 일시적인 오류입니다.")
                continue

        try:
            update_status = WebDriverWait(driver, TIMEOUT).until(
                EC.text_to_be_present_in_element((By.XPATH, '//*[@id="btn-sync"]/span'), "최신정보")
            )
        except TimeoutException:
            print("갱신 대기 시간이 초과 되었습니다.")
        except UnexpectedAlertPresentException:
            print("Alert")
            Alert(driver).accept()
        except AttributeError as e:
            print("웹 페이지 로딩이 완료되지 않았거나 일시적인 오류입니다.")
        except WebDriverException:
            print("갱신 중 오류가 발생했습니다.")
    	time.sleep(3)


if __name__ == '__main__':
    main()

  • driver.implicitly_wait(TIMEOUT): 페이지가 로딩될 때까지 묵시적으로 기다립니다.
  • Alert(driver).accept(): alert 발생 시 확인버튼을 눌러 닫습니다. dismiss()로 닫을 수도 있습니다.
  • WebDriverWait(driver, TIMEOUT).until(EC.text_to_be_present_in_element((...), ...) : 지정한 위치에 해당 텍스트가 나타날 때까지 until과 explicitly wait로 기다립니다.

alert 등의 예외 처리방법은 chromedriver 버전에 따라 달라지기도 합니다. 해당 포스팅에서는 101.0.4951 버전을 사용하였습니다. 참고 부탁드립니다.

3. 다음 고민

매일 직접 실행하는 것도 귀찮고 번거로운데 실행마저 자동화 시킬 수는 없을까? 🤔

4.Reference

Selenium 4.1.0 documentation

셀레니움 wait 개념 이해하기 (implicitly wait VS explicitly wait)

profile
여러가지를 시도하는 학생입니다

0개의 댓글