- 레이어 알림이 존재할 경우 자동으로 닫는 기능을 보강하여 클릭 시 간섭 방지 - 클릭 시 팝업이 가로채는 경우를 처리하는 safe_click 함수 추가 - 자동번호 선택 및 구매 버튼 클릭 시 안전한 클릭 로직 적용 - 코드 가독성을 높이기 위해 주석 추가
This commit is contained in:
@@ -228,9 +228,55 @@ def buy_lotto(driver, game_count=5):
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def ensure_no_layer_alert(max_rounds: int = 3) -> None:
|
||||
"""popupLayerAlert가 떠 있으면 닫히는 것까지 보장(짧게 재시도)."""
|
||||
for _ in range(max_rounds):
|
||||
closed = close_layer_alert_if_present(timeout_s=0.6)
|
||||
try:
|
||||
WebDriverWait(driver, 1.2).until(
|
||||
EC.invisibility_of_element_located((By.ID, "popupLayerAlert"))
|
||||
)
|
||||
return
|
||||
except Exception:
|
||||
if not closed:
|
||||
return
|
||||
time.sleep(0.2)
|
||||
|
||||
def safe_click(locator, timeout_s: float = 10, retries: int = 2) -> None:
|
||||
"""클릭이 팝업에 가로채이면 popupLayerAlert 닫고 재시도."""
|
||||
from selenium.common.exceptions import ElementClickInterceptedException
|
||||
|
||||
last_exc = None
|
||||
for _ in range(retries + 1):
|
||||
ensure_no_layer_alert()
|
||||
el = WebDriverWait(driver, timeout_s).until(EC.element_to_be_clickable(locator))
|
||||
try:
|
||||
el.click()
|
||||
return
|
||||
except ElementClickInterceptedException as e:
|
||||
last_exc = e
|
||||
# 팝업이 클릭을 가로채는 경우가 대부분이라 닫고 재시도
|
||||
close_layer_alert_if_present(timeout_s=0.8)
|
||||
time.sleep(0.3)
|
||||
except Exception as e:
|
||||
last_exc = e
|
||||
break
|
||||
|
||||
# 마지막 fallback: JS click
|
||||
try:
|
||||
ensure_no_layer_alert()
|
||||
el = WebDriverWait(driver, timeout_s).until(EC.presence_of_element_located(locator))
|
||||
driver.execute_script("arguments[0].click();", el)
|
||||
return
|
||||
except Exception:
|
||||
if last_exc:
|
||||
raise last_exc
|
||||
raise
|
||||
|
||||
# 첫 상호작용 전에 레이어 알림이 떠 있으면 먼저 닫기
|
||||
if close_layer_alert_if_present():
|
||||
logger.info("초기 popupLayerAlert 감지 — 닫기 처리 완료")
|
||||
ensure_no_layer_alert()
|
||||
|
||||
# 모든 레이어 팝업을 JS로 직접 숨기기 (z-index 오버레이 완전 제거)
|
||||
driver.execute_script("""
|
||||
@@ -242,16 +288,14 @@ def buy_lotto(driver, game_count=5):
|
||||
time.sleep(0.5)
|
||||
logger.info("팝업 레이어 숨김 처리 완료")
|
||||
|
||||
# "자동" 탭 선택 — onclick 함수(selectWayTab)를 직접 호출
|
||||
# (간헐적으로 popupLayerAlert가 클릭을 가로채므로 전/후로 닫기 처리 + 1회 재시도)
|
||||
for attempt in range(2):
|
||||
close_layer_alert_if_present(timeout_s=0.5)
|
||||
# "자동" 탭 선택 (id=num2). 팝업이 클릭을 가로채는 케이스 방지.
|
||||
try:
|
||||
safe_click((By.ID, "num2"), timeout_s=10, retries=2)
|
||||
except Exception:
|
||||
# fallback: 함수 직접 호출
|
||||
ensure_no_layer_alert()
|
||||
driver.execute_script("selectWayTab(1);")
|
||||
time.sleep(1)
|
||||
if not close_layer_alert_if_present(timeout_s=0.5):
|
||||
break
|
||||
logger.info("자동 탭 선택 중 popupLayerAlert 재발 — 닫기 후 재시도")
|
||||
time.sleep(0.5)
|
||||
|
||||
# 게임 수 설정 (드롭다운에서 선택)
|
||||
from selenium.webdriver.support.ui import Select
|
||||
@@ -263,14 +307,12 @@ def buy_lotto(driver, game_count=5):
|
||||
except Exception:
|
||||
# 드롭다운이 없는 경우 자동번호 버튼을 game_count번 클릭
|
||||
for i in range(game_count):
|
||||
auto_select_btn = driver.find_element(By.ID, "btnSelectNum")
|
||||
auto_select_btn.click()
|
||||
safe_click((By.ID, "btnSelectNum"), timeout_s=10, retries=2)
|
||||
time.sleep(0.5)
|
||||
|
||||
# "자동번호 선택" 버튼 클릭
|
||||
try:
|
||||
select_num_btn = driver.find_element(By.ID, "btnSelectNum")
|
||||
select_num_btn.click()
|
||||
safe_click((By.ID, "btnSelectNum"), timeout_s=10, retries=2)
|
||||
time.sleep(1)
|
||||
except:
|
||||
pass
|
||||
@@ -283,14 +325,20 @@ def buy_lotto(driver, game_count=5):
|
||||
buy_btn = wait.until(
|
||||
EC.element_to_be_clickable((By.ID, "btnBuy"))
|
||||
)
|
||||
try:
|
||||
buy_btn.click()
|
||||
except Exception:
|
||||
safe_click((By.ID, "btnBuy"), timeout_s=10, retries=2)
|
||||
time.sleep(2)
|
||||
|
||||
# 구매 확인 팝업 "확인" 클릭
|
||||
confirm_btn = wait.until(
|
||||
EC.element_to_be_clickable((By.CSS_SELECTOR, "#popupLayerConfirm input[value='확인']"))
|
||||
)
|
||||
try:
|
||||
confirm_btn.click()
|
||||
except Exception:
|
||||
safe_click((By.CSS_SELECTOR, "#popupLayerConfirm input[value='확인']"), timeout_s=10, retries=2)
|
||||
time.sleep(3)
|
||||
|
||||
logger.info("구매 요청 완료! 구매 결과를 확인합니다...")
|
||||
|
||||
Reference in New Issue
Block a user