호요랩 자동 출석 체크 프로그램 만들기 프로젝트2(상대적 xpath? css selector?)

원래 잘 작동하던 프로그램이 어느날 갑자기..

 

etc-image-0

 

 

 

에러나더라??

 

왜 안되나 봤는데 원래 이렇게 되어있던 xpath가

 

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

 

 

/html/body/div[5]/div/div/span

 

이렇게 바뀌어있더라?

 

웹페이지 구조가 살짝 바뀔수도 있나봐?

 

https://www.geeksforgeeks.org/difference-between-relative-and-absolute-xpath-in-selenium/#choosing-the-right-xpath-strategy

 

Difference between Relative and Absolute XPath in Selenium - GeeksforGeeks

Understanding the differences between Absolute and Relative XPath is essential for effective Selenium automation, with Relative XPath offering flexibility and adaptability, while Absolute XPath provides precision but is less flexible.

www.geeksforgeeks.org

 

 

절대적 xpath가 있고 상대적 xpath가 있는듯

 

Selenium에서 절대 XPath와 상대 XPath의 차이에 대한 FAQ

Selenium에서 절대 XPath와 상대 XPath의 차이는 무엇인가요?


답: 절대 XPath는 HTML 문서의 루트부터 요소까지의 전체 경로를 제공하여 정확성이 높지만 유연성이 낮습니다. 반면, 상대 XPath는 요소 간의 관계를 기반으로 탐색하여 더 높은 적응성을 제공합니다.

 

절대 XPath를 상대 XPath보다 언제 사용해야 하나요?


답: 절대 XPath는 요소의 정확한 위치를 찾아야 할 때 유용하지만, 유연성이 낮고 변경에 취약합니다. 요소의 위치가 변하지 않을 경우에만 제한적으로 사용하는 것이 좋습니다.

 

Selenium에서 상대 XPath의 장점은 무엇인가요?


답: 상대 XPath는 웹페이지 구조 변경에 강하며, 가독성이 좋고 효율적이며 유연성이 뛰어납니다.

 

Selenium 자동화에서 적절한 XPath 전략을 선택하는 방법은?


답: 요소의 안정성을 고려하고, 웹페이지에서 단서를 찾아 활용하며, 특별한 경우가 아니라면 상대 XPath를 선호하세요. 또한, XPath 표현식을 다양한 브라우저에서 테스트하여 신뢰성을 확인하는 것이 중요합니다.

 

결론

결론적으로, 절대 XPath와 상대 XPath의 차이를 이해하는 것은 효과적인 Selenium 자동화를 위해 매우 중요합니다. 절대 XPath는 정확성을 제공하지만 유연성이 낮고 변경에 취약합니다. 반면, 상대 XPath는 유연성과 적응력이 뛰어나 대부분의 자동화 작업에서 선호됩니다. 프로젝트의 요구 사항에 따라 적절한 XPath 전략을 선택하고 모범 사례를 따르면, 견고하고 유지보수하기 쉬운 Selenium 스크립트를 만들 수 있습니다. 또한, 웹페이지 구조 변경에 대비하여 XPath 표현식을 정기적으로 검토하고 업데이트하는 것이 원활하고 신뢰할 수 있는 자동화를 보장하는 데 도움이 됩니다.

 

--------------------------------------------------------------------------------------------------------------------------------------------------

 

이런 문제를 해결하는 방법으로 상대적 xpath를 사용하는 것이 방법이 될 수 있다고 한다

 

copy xpath하면 절대적 xpath가 보통 나오기 때문에... 상대적 xpath로 바꿀려면?

 

방법이 있는것 같은데 그냥 chatgpt에 물어보는게 낫겠다

 

원하는 위치에 copy element하고 chatgpt한테 상대적 xpath로 바꿔달라하면 됨

 

etc-image-1

 

 

 

그래서 일단 이렇게 코드를 수정함

 

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time

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

time.sleep(2)

# XPath를 사용하여 버튼 요소 찾기
button = driver.find_element(By.XPATH, "//span[contains(@class, 'guide-close')]")

# 버튼 클릭
button.click()

time.sleep(1)

# XPath를 사용하여 버튼 요소 찾기
button = driver.find_element(By.XPATH, "//img[contains(@class, 'mhy-hoyolab-account-block__avatar-icon')]")

# 버튼 클릭
button.click()

time.sleep(1)

# 2. 입력 필드 찾기 (XPath 사용)
        
# change the control to signin page
#iframe = driver.find_element(By.XPATH,"/html/body/div[2]/div/div[1]")
driver.switch_to.frame(0)

id = driver.find_element(By.XPATH, "//input[@name='username' and @type='text']")

# 3. 클릭
id.click()

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

password = driver.find_element(By.XPATH, "//input[@name='password' and @type='password']")

# 3. 클릭
password.click()

# 4. 아이디 입력
password.send_keys("....")  # 여기에 아이디 입력
time.sleep(1)

login = driver.find_element(By.XPATH,"//button[@type='submit' and contains(@class, 'el-button--primary')]/span[text()='로그인']")

login.click()

time.sleep(2)

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

button = driver.find_element(By.XPATH,"//span[text()='더보기']")

button.click()
time.sleep(2)

count = driver.find_element(By.XPATH,"//span[@class='sign-num']").text

count = int(count)

target = count + 1

xpath = f"//div[contains(@class, 'components-home-assets-__sign-content-test_---item-day---1C_BmH') and contains(text(), '{target}일째')]"

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

time.sleep(2)

driver.quit()

time.sleep(1)

 

728x90