호요랩 자동 출석 체크 프로그램 만들기 프로젝트1(iframe 주의하기)

호요버스 게임은 출석체크를 호요랩이라는 페이지에 들어가서 따로 해야한다

 

etc-image-0

 

 

 

하지만 보상도 적고 그러다보니 귀찮기도 하고 그러다보니 까먹기도 한다

 

보상이 적은 만큼 최소한의 노력으로 출석체크를 다 하고 싶다는 마음에서 자동으로 출석 체크를 하는 프로그램을 만들어보고 싶었다

 

웹 페이지를 보니 Selenium으로 자동으로 위치를 찾아가면 할 수 있을 것 같았다

 

먼저 웹페이지를 webdriver로 열어준다

 

from selenium import webdriver
from selenium.webdriver.common.by import By

# 웹 드라이버 실행 (Chrome 기준)

driver = webdriver.Chrome()
driver.get("https://act.hoyolab.com/ys/event/signin-sea-v3/index.html?act_id=e202102251931481&hyl_auth_required=true&hyl_presentation_style=fullscreen&utm_source=hoyolab&utm_medium=tools&lang=ko-kr&bbs_theme=light&bbs_theme_device=1")  # 원하는 웹사이트 URL

 

 

웹페이지를 열면 이런 화면이 뜬다

 

먼저 방해되는 창을 닫아야한다.

 

etc-image-1

 

 

 

개발자 도구를 이용해 x표시의 xpath를 찾는다

 

etc-image-2

 

 

찾은 xpath를 이용해 위치를 찾고 click을 해준다

 

# XPath를 사용하여 버튼 요소 찾기
button = driver.find_element(By.XPATH, "/html/body/div[4]/div/div/span")

# 버튼 클릭
button.click()

 

 

다음으로 로그인 창을 열어야한다

 

우상단 동그라미 표시를 클릭해야한다

 

역시 개발자 도구로 xpath를 찾고, 해당 위치를 클릭한다

 

etc-image-3

 

 

 

# XPath를 사용하여 버튼 요소 찾기
button = driver.find_element(By.XPATH, "/html/body/div[1]/div[2]/div/div/div/div[2]/div[1]/img")

# 버튼 클릭
button.click()

 

 

이제 아이디, 비밀번호를 입력해야한다.

 

etc-image-4

 

 

 

아이디 칸의 위치를 찾고, 해당 칸을 눌러주자

 

id = driver.find_element(By.XPATH, "/html/body/div[2]/div/div/div[2]/div[1]/form/div[3]/div[1]/input")

# 3. 클릭
id.click()

 

etc-image-5

 

 

 

근데 실행해보니 에러가 난다?

 

etc-image-6

 

 

 

해당 위치를 찾지 못할때 발생하는 에러이다.

 

예전에도 비슷한 경험을 한 적이 있다.

 

로그인 팝업창 같은 것은 자바스크립트로 동적으로 구성되어 있어서

 

iframe을 옮겨야한다는 것을

 

로그인 창을 보면 클래스 명이 이렇게 되어있는데  el-dialog hyv-web-login-dialog iframe-level-1

 

iframe level 1에 있다는 것을 말하는 것 같다

 

etc-image-7

 

 

 

 

iframe은 순서대로 0,1,2,... 이렇게 되어 있는 것 같고

 

첫번째 iframe으로 이동하고 싶으면

 

driver.switch_to.frame(0)

 

 

이렇게 이동을 하고 나서, 해당 아이디 칸 위치를 찾으면 에러가 나지 않는다.

 

해당 아이디 칸 위치를 찾아 클릭 후에, 아이디를 입력한다. send_keys()를 이용하면 가능하다

 

id = driver.find_element(By.XPATH, "/html/body/div[2]/div/div/div[2]/div[1]/form/div[3]/div[1]/input")

# 3. 클릭
id.click()

# # 4. 아이디 입력
id.send_keys(".....")  # 여기에 아이디 입력

 

 

etc-image-8

 

 

 

마찬가지로 비밀번호도 똑같이 입력해준다.

 

비밀번호 칸을 찾아 클릭하고, 해당 위치에 send_keys()로 비밀번호를 입력

 

password = driver.find_element(By.XPATH, "/html/body/div[2]/div/div/div[2]/div[1]/form/div[4]/div[1]/input")

# 3. 클릭
password.click()

password.send_keys("......")

 

 

 

etc-image-9

 

 

 

이제 바로 아래 검은색 로그인 박스 버튼을 찾아 클릭하면 된다.

 

login = driver.find_element(By.XPATH,"/html/body/div[2]/div/div/div[2]/div[1]/form/button")

login.click()

 

 

etc-image-10

 

 

그러면 이제 13일차 버튼을 찾아 클릭해야한다.

 

어떻게 가능할까?

 

근데 그 전에 먼저 iframe(0)으로 이동해있고, 현재 창은 최상위 창이기 때문에 다시 되돌아와야한다.

 

되돌아오지 않으면 앞으로 위치를 못찾아 에러난다

 

# 로그인 후, 기본(원래) 프레임으로 돌아가기
driver.switch_to.default_content()

 

 

이제 13일차 버튼을 찾아야하는데, 좌상단에 "이번 달 출석체크 12일(누적)"하고 

 

그동안 몇일이나 출석 체크를 했는지 알려준다

 

etc-image-11

 

 

이 위치를 찾아 텍스트를 긁어오면 몇일 출석했는지 알 수 있다

 

count = driver.find_element(By.XPATH,"/html/body/div[1]/div[5]/div/div/div/div[1]/div[1]/div[1]/span").text

count = int(count)

print(count)
12

 

 

따라서 우리가 찾아야할 버튼의 위치는 count+1 = 13이다.

 

13일차 버튼의 위치를 찾아 클릭하면 된다.

 

그 전에 아래 더보기 버튼을 눌러 출석체크 판을 펼쳐준다.

 

etc-image-12

 

 

 

button = driver.find_element(By.XPATH,"/html/body/div[1]/div[5]/div/div/div/div[3]/span[1]")

button.click()

 

 

이걸 하는 이유는 13일차의 xpath가 달라지기 때문이다.

 

펼치지 않으면

 

/html/body/div[1]/div[5]/div/div/div/div[2]/div[6]

 

펼치면

 

/html/body/div[1]/div[5]/div/div/div/div[2]/div[13]

 

펼치는 경우, /html/body/div[1]/div[5]/div/div/div/div[2]/div[13]으로 맨 마지막 div에 써진 숫자가,

 

해당 출석체크 날짜와 동일해지는데, 펼치지 않으면 이 숫자를 예상하기 어렵다.

 

실제로 나머지 날짜도, /html/body/div[1]/div[5]/div/div/div/div[2]/div[(target숫자)]으로 형태가 모두 동일하다.

 

target = count + 1

xpath = f'/html/body/div[1]/div[5]/div/div/div/div[2]/div[{target}]'

button = driver.find_element(By.XPATH,xpath)
button.click()

 

 

이러면 원하는 날짜의 출석체크 버튼을 클릭하고, 출석에 성공한다.

 

etc-image-13

 

 

이제, x버튼을 클릭해서 해당 창을 닫고, 웹 드라이버를 종료한다.

 

button = driver.find_element(By.XPATH,"/html/body/div[5]/div[2]/div[2]/div")

button.click()


driver.quit()

 

728x90