selenium의 wait()를 사용하여 좀더 깔끔하게 갱신을 처리해보자!😀
기존 코드에서 갱신을 기다리기 위해 사용한 코드입니다. 무조건 지정한 시간만큼 기다리는 방법입니다.
웹 페이지 로딩 시까지 암묵적으로 기다리는 메서드입니다. 지정한 시간만큼 기다리는데, 지정한 시간이전에 웹 페이지가 로딩 되면 다음 명령을 실행합니다. 또한 지정한 시간이 넘어가면 웹 페이지 로딩이 끝나지 않더라도 다음 명령을 실행합니다.
전체적인 웹 페이지 로딩이 아닌 내가 원하는 element가 원하는 상태가 될 때까지 명시적으로 기다리는 메서드입니다.
상황별로 많은 메서드들이 정의 되어있으며 대표적으로 EC.presence_of_element_located()
를 많이 사용합니다. 메서드 목록은 링크를 참조바랍니다.
여기서는EC.text_to_be_present_in_element()
를 사용해보았습니다.
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 버전을 사용하였습니다. 참고 부탁드립니다.
매일 직접 실행하는 것도 귀찮고 번거로운데 실행마저 자동화 시킬 수는 없을까? 🤔