크롬 드라이버와 셀레니엄을 통해 로그인을 하는데 headless로 했더니 아래와 같이 버튼 클릭시 에러가 납니다.
오늘은 헤드리스로 느린 우분투 서버에서 동작시킬때 왜 문제가 발생하는지 알아보겠습니다.
Traceback (most recent call last):
File "web-tools/ss-crawling/apiSellout.py", line 31, in main
inStockOriginProductsNo.extend(crawlerupick.checkInStockAPI(productsCodes))
File "/home/ubuntu/web-tools/ss-crawling/crawlerUPick.py", line 840, in checkInStockAPI
inStockCodes = self.checkInStock(sellerCodes)
File "/home/ubuntu/web-tools/ss-crawling/crawlerUPick.py", line 849, in checkInStock
self.login()
File "/home/ubuntu/web-tools/ss-crawling/crawlerUPick.py", line 73, in login
login_button.click()
File "/home/ubuntu/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 94, in click
self._execute(Command.CLICK_ELEMENT)
File "/home/ubuntu/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 395, in _execute
return self._parent.execute(command, params)
File "/home/ubuntu/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 354, in execute
self.error_handler.check_response(response)
File "/home/ubuntu/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 229, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <a href="#none" class="btnSubmit gFull size L" onclick="MemberAction.login('member_form_4077296188'); return false;">...</a> is not clickable at point (382, 389). Other element would receive t he click: <ul class="bottom-nav__tabBar">...</ul>
(Session info: chrome=129.0.6668.58)
Stacktrace:
#0 0x55ecf457413a <unknown>
#1 0x55ecf425a5e0 <unknown>
#2 0x55ecf42b0866 <unknown>
#3 0x55ecf42ae78d <unknown>
#4 0x55ecf42ac237 <unknown>
#5 0x55ecf42ab646 <unknown>
#6 0x55ecf429ea98 <unknown>
#7 0x55ecf42ceb22 <unknown>
#8 0x55ecf429e478 <unknown>
#9 0x55ecf42cecee <unknown>
#10 0x55ecf42edd7d <unknown>
#11 0x55ecf42ce8c3 <unknown>
#12 0x55ecf429c6b3 <unknown>
#13 0x55ecf429d68e <unknown>
#14 0x55ecf453eb3b <unknown>
#15 0x55ecf4542ac1 <unknown>
#16 0x55ecf452b335 <unknown>
#17 0x55ecf4543642 <unknown>
#18 0x55ecf451049f <unknown>
#19 0x55ecf4563038 <unknown>
#20 0x55ecf4563203 <unknown>
#21 0x55ecf4572f8c <unknown>
#22 0x7f3d41f87609 start_thread
먼저 위의 에러에서 ElementClickInterceptedException 오류는 클릭하려는 요소가 페이지의 다른 요소에 의해 가려지거나, 클릭이 가로채졌을 때 발생합니다.
주로 headless 모드에서 발생하는 이유는 화면 크기나 렌더링 속도 차이 때문에 페이지 레이아웃이 달라지기 때문입니다.
이 문제를 해결하기 다음의 몇 가지 방법을 적용해볼 수 있습니다:
1. 명시적 대기(Explicit Wait) 사용하기
페이지가 완전히 로드되기 전에 클릭을 시도할 경우 발생할 수 있는 문제를 해결할 수 있습니다. 요소가 클릭 가능한 상태가 될 때까지 기다리도록 코드를 수정합니다.
find_element와 같은걸 대신해서 element_to_be_clickable로 바꿔서 대기해 봅니다.
def login(self):
# Explicit wait to ensure the login button is clickable
wait = WebDriverWait(self.driver, 10)
login_button = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "btnSubmit")))
# Try clicking the login button
login_button.click()
2. JavaScript로 클릭 실행하기
headless 모드에서 발생하는 화면 요소 문제를 피하기 위해 JavaScript를 통해 강제로 클릭할 수 있습니다.
click()을 호출하는 대신에 execute_script 안에 click()을 넣어서 javascript를 강제로 호출하는 방법을 사용해 봅니다.
def login(self):
# Locate the login button
login_button = self.driver.find_element(By.CLASS_NAME, "btnSubmit")
# Use JavaScript to click the button
self.driver.execute_script("arguments[0].click();", login_button)
3. 화면 크기 설정
headless 모드에서 화면 크기를 설정하지 않으면 기본적으로 매우 작은 크기로 설정되기 때문에, 요소가 화면 밖에 있을 수 있습니다. 이 문제는 특히, 크롤링 할 때 헤드리스를 사용하면 다른 문제를 발생시킬 수도 있으므로 화면 크기는 꼭 적절하게 설정해 주어야 합니다.
아래와 같이 add_argument에 window-size=1920x1080을 넣어줍니다.
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
# Set the window size
chrome_options.add_argument("window-size=1920x1080")
driver = webdriver.Chrome(options=chrome_options)
4. headless 모드 사용 중지
만약 위의 방법으로 다 해봤는데 해결되지 않는다면, headless 모드를 일시적으로 중지하고 디버깅을 해야합니다. ㅠㅠ
페이지가 실제로 어떻게 렌더링되는지 확인하면서 디버깅 해봐야 합니다. ㅠㅠ
5. 결론
headless 모드를 사용하면 일반 화면과 기본적으로 다르게 동작하는 것이 윈도우 크기이므로, 윈도우 크기는 기본적으로 꼭 설정해주시고, 느린 장비에서 버튼을 대기하는 시간을 가질 수 있도록 해주는 것이 중요합니다.
이상으로 저는 문제가 해결되었습니다.
다른 분들도 위의 방법으로 해결되길 바랍니다~
오늘도 수고하셨습니다.
'IT' 카테고리의 다른 글
네이버 스마트스토어 상품 가져와서 쿠팡에 자동으로 올리는 프로그램 만들기 (5) | 2024.10.28 |
---|---|
우분투 20.04 리눅스에서 crontab(크론탭)으로 주기적인 작업 자동화하기 (0) | 2024.10.21 |
파이썬으로 웹 페이지 크롤링 - 홈페이지 로그인 하기 (1) | 2024.09.23 |
리눅스(우분투 20.04)에서 커맨드라인으로 구글 크롬(google-chrome) 설치하기 (1) | 2024.09.23 |
워드프레스 블로그 홈페이지 1분만에 자동 목차 차례 만들고 적용하기 - 플러그인으로 가장 쉽게 하기 (9) | 2024.08.28 |