from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException import logging import time # 로거 인스턴스 가져오기 logger = logging.getLogger('default_logger') def click_element(driver, element_type, element_identifier, wait_time=10, click_type='normal'): """ 주어진 요소를 찾아 클릭합니다. Parameters: - driver: WebDriver 인스턴스 - element_type: 요소를 찾는 방법 ('CSS_SELECTOR', 'CLASS_NAME', 'XPATH', 'ID') - element_identifier: 요소의 식별자 - wait_time: 요소가 나타날 때까지 대기하는 시간 (초) - click_type: 클릭 방식 ('normal' 또는 'js' 또는 'ac') - visibility_of_element_located : 사용자가 실제로 볼 수 있고, 상호작용할 수 있는 요소에 대한 작업을 진행하기 전에 요소의 가시성을 보장 - presence_of_element_located : 페이지 로딩이 완료되었는지 확인하거나, 특정 요소가 DOM에 추가되었는지를 확인할 때 """ try: element = WebDriverWait(driver, wait_time).until( EC.visibility_of_element_located((getattr(By, element_type), element_identifier)) ) if click_type == 'normal': element.click() elif click_type == 'js': driver.execute_script("arguments[0].scrollIntoView();", element) time.sleep(0.2) driver.execute_script("arguments[0].click();", element) elif click_type == 'ac': actions = ActionChains(driver) actions.move_to_element(element).perform() # 요소로 스크롤 logger.debug(f"'{element}' 요소로 스크롤 실행") time.sleep(0.2) actions.click(element).perform() logger.debug(f"'{element_identifier}' 요소를 성공적으로 클릭함.") except TimeoutException: logger.error(f"'{element_identifier}' 요소를 {wait_time} 초 이내에 찾지 못함.") except Exception as e: logger.error(f"예상치 못한 오류 발생: {e}", exc_info=True) def return_element(driver, element_type, element_identifier, wait_time=10): """ 주어진 요소를 찾아 클릭합니다. Parameters: - driver: WebDriver 인스턴스 - element_type: 요소를 찾는 방법 ('CSS_SELECTOR', 'CLASS_NAME', 'XPATH', 'ID') - element_identifier: 요소의 식별자 - wait_time: 요소가 나타날 때까지 대기하는 시간 (초) - visibility_of_element_located : 사용자가 실제로 볼 수 있고, 상호작용할 수 있는 요소에 대한 작업을 진행하기 전에 요소의 가시성을 보장 - presence_of_element_located : 페이지 로딩이 완료되었는지 확인하거나, 특정 요소가 DOM에 추가되었는지를 확인할 때 """ try: # 요소가 DOM에 존재하는지 확인 element_present = EC.presence_of_element_located((getattr(By, element_type), element_identifier)) element = WebDriverWait(driver, wait_time).until(element_present) # 요소가 사용자 화면에 보이도록 스크롤 driver.execute_script("arguments[0].scrollIntoView(true);", element) # 요소가 실제로 사용자에게 보이는지 다시 확인 element_visible = WebDriverWait(driver, wait_time).until( EC.visibility_of_element_located((getattr(By, element_type), element_identifier)) ) logger.debug(f"'{element_visible}' 요소를 성공적으로 찾음.") return element_visible except TimeoutException as e: logger.debug(f"'{element_identifier}' 요소를 {wait_time} 초 이내에 찾지 못함. 예외: {e}", exc_info=True) # 시각적으로 보이지 않는 경우, DOM 내 존재 여부만 확인 try: element_in_dom = driver.find_element(getattr(By, element_type), element_identifier) logger.debug(f"'{element_identifier}' 요소는 DOM 내에 존재하지만 보이지 않음.") return element_in_dom except Exception as e: logger.debug(f"DOM 내에서도 '{element_identifier}' 요소를 찾을 수 없음. 예외: {e}", exc_info=True) return None except Exception as e: logger.debug(f"예상치 못한 오류 발생: {e}", exc_info=True) return None def wait_element(driver, element_type, element_identifier, wait_time=10): try: element = WebDriverWait(driver, wait_time).until( EC.visibility_of_element_located((getattr(By, element_type), element_identifier)) ) if element: logger.debug(f"'{element_identifier}' 요소를 {wait_time} 초 이내에 찾음") return True except TimeoutException: logger.error(f"에러 : '{element_identifier}' 요소를 {wait_time} 초 이내에 찾지 못함.") return False except Exception as e: logger.error(f"예상치 못한 오류 발생: {e}", exc_info=True) return False def click_and_confirm_tab(driver, data_node_key, timeout=10): """ data-node-key 속성을 이용하여 특정 탭을 클릭하고, 해당 탭이 선택되었는지 확인합니다 (aria-selected="true"). :param driver: WebDriver 인스턴스 :param data_node_key: 클릭하려는 탭의 data-node-key 속성 값 :param timeout: 최대 대기 시간(초) """ end_time = time.time() + timeout while True: try: # 탭 요소를 data-node-key 속성을 이용하여 찾아 클릭 tab_css_selector = f'div[data-node-key="{data_node_key}"] .ant-tabs-tab-btn' tab_element = WebDriverWait(driver, timeout).until(EC.element_to_be_clickable((By.CSS_SELECTOR, tab_css_selector))) tab_element.click() # 해당 탭의 aria-selected 속성이 "true"인지 확인 selected = WebDriverWait(driver, 2).until( lambda d: d.find_element(By.CSS_SELECTOR, tab_css_selector).get_attribute("aria-selected") == "true" ) if selected: print("탭 선택 확인됨.") return True except TimeoutException: print("탭 선택 상태가 확인되지 않음. 다시 시도합니다.") if time.time() > end_time: print("타임아웃: 탭 선택을 확인할 수 없습니다.") return False