- 레이어 알림이 존재할 경우 자동으로 닫는 기능을 보강하여 클릭 시 간섭 방지 - 클릭 시 팝업이 가로채는 경우를 처리하는 safe_click 함수 추가 - 자동번호 선택 및 구매 버튼 클릭 시 안전한 클릭 로직 적용 - 코드 가독성을 높이기 위해 주석 추가
This commit is contained in:
@@ -228,9 +228,55 @@ def buy_lotto(driver, game_count=5):
|
|||||||
except Exception:
|
except Exception:
|
||||||
return False
|
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():
|
if close_layer_alert_if_present():
|
||||||
logger.info("초기 popupLayerAlert 감지 — 닫기 처리 완료")
|
logger.info("초기 popupLayerAlert 감지 — 닫기 처리 완료")
|
||||||
|
ensure_no_layer_alert()
|
||||||
|
|
||||||
# 모든 레이어 팝업을 JS로 직접 숨기기 (z-index 오버레이 완전 제거)
|
# 모든 레이어 팝업을 JS로 직접 숨기기 (z-index 오버레이 완전 제거)
|
||||||
driver.execute_script("""
|
driver.execute_script("""
|
||||||
@@ -242,16 +288,14 @@ def buy_lotto(driver, game_count=5):
|
|||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
logger.info("팝업 레이어 숨김 처리 완료")
|
logger.info("팝업 레이어 숨김 처리 완료")
|
||||||
|
|
||||||
# "자동" 탭 선택 — onclick 함수(selectWayTab)를 직접 호출
|
# "자동" 탭 선택 (id=num2). 팝업이 클릭을 가로채는 케이스 방지.
|
||||||
# (간헐적으로 popupLayerAlert가 클릭을 가로채므로 전/후로 닫기 처리 + 1회 재시도)
|
try:
|
||||||
for attempt in range(2):
|
safe_click((By.ID, "num2"), timeout_s=10, retries=2)
|
||||||
close_layer_alert_if_present(timeout_s=0.5)
|
except Exception:
|
||||||
|
# fallback: 함수 직접 호출
|
||||||
|
ensure_no_layer_alert()
|
||||||
driver.execute_script("selectWayTab(1);")
|
driver.execute_script("selectWayTab(1);")
|
||||||
time.sleep(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
|
from selenium.webdriver.support.ui import Select
|
||||||
@@ -263,14 +307,12 @@ def buy_lotto(driver, game_count=5):
|
|||||||
except Exception:
|
except Exception:
|
||||||
# 드롭다운이 없는 경우 자동번호 버튼을 game_count번 클릭
|
# 드롭다운이 없는 경우 자동번호 버튼을 game_count번 클릭
|
||||||
for i in range(game_count):
|
for i in range(game_count):
|
||||||
auto_select_btn = driver.find_element(By.ID, "btnSelectNum")
|
safe_click((By.ID, "btnSelectNum"), timeout_s=10, retries=2)
|
||||||
auto_select_btn.click()
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
# "자동번호 선택" 버튼 클릭
|
# "자동번호 선택" 버튼 클릭
|
||||||
try:
|
try:
|
||||||
select_num_btn = driver.find_element(By.ID, "btnSelectNum")
|
safe_click((By.ID, "btnSelectNum"), timeout_s=10, retries=2)
|
||||||
select_num_btn.click()
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@@ -283,14 +325,20 @@ def buy_lotto(driver, game_count=5):
|
|||||||
buy_btn = wait.until(
|
buy_btn = wait.until(
|
||||||
EC.element_to_be_clickable((By.ID, "btnBuy"))
|
EC.element_to_be_clickable((By.ID, "btnBuy"))
|
||||||
)
|
)
|
||||||
buy_btn.click()
|
try:
|
||||||
|
buy_btn.click()
|
||||||
|
except Exception:
|
||||||
|
safe_click((By.ID, "btnBuy"), timeout_s=10, retries=2)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
# 구매 확인 팝업 "확인" 클릭
|
# 구매 확인 팝업 "확인" 클릭
|
||||||
confirm_btn = wait.until(
|
confirm_btn = wait.until(
|
||||||
EC.element_to_be_clickable((By.CSS_SELECTOR, "#popupLayerConfirm input[value='확인']"))
|
EC.element_to_be_clickable((By.CSS_SELECTOR, "#popupLayerConfirm input[value='확인']"))
|
||||||
)
|
)
|
||||||
confirm_btn.click()
|
try:
|
||||||
|
confirm_btn.click()
|
||||||
|
except Exception:
|
||||||
|
safe_click((By.CSS_SELECTOR, "#popupLayerConfirm input[value='확인']"), timeout_s=10, retries=2)
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
|
||||||
logger.info("구매 요청 완료! 구매 결과를 확인합니다...")
|
logger.info("구매 요청 완료! 구매 결과를 확인합니다...")
|
||||||
|
|||||||
Reference in New Issue
Block a user