

Qoo10 리뷰 크롤링 시 페이징 버튼이 화면에 표시되지 않는 문제 때문에 기존의 시각적 버튼 클릭 방식 대신 다른 접근 방식을 사용했다.

공부의 축복이 끝이 없어 ~~!!!!!!!
대부분의 웹 크롤링 튜토리얼에서는 find_element로 "다음" 버튼을 찾아 click()하는 방식으로 페이징을 처리한다.
하지만, 특정 웹사이트(예: Qoo10 리뷰 페이지)에서는 총 리뷰 개수는 많은데도 불구하고, 페이지 하단의 "1, 2, 3, 다음"과 같은 페이징 UI 요소가 아예 HTML에 렌더링되지 않는 문제가 발생할 수 있다.
이는 서버 응답 오류, JavaScript 로딩 실패, 또는 특정 조건(예: 검색 결과 없음)에 따른 의도된 동작일 수 있다고 한다.
이러한 상황에서는 WebDriverWait으로 next_button을 아무리 기다려도 찾을 수 없으므로, 기존 방식으로는 다음 페이지로 넘어갈 수 없다 ㅠㅠ
((개발이 빨리 끝날 줄 알았지만 ... 페이징이 안뜨는 이슈를 못찾아서 삽질만 왕창 ..))
페이징 UI가 없더라도, 웹사이트는 다음 페이지의 데이터를 어딘가에서 가져와야 한다. 이는 주로 AJAX(Asynchronous JavaScript and XML) 통신을 통해 이루어진다!!
Qoo10 리뷰 페이지의 경우, HTML 소스코드나 JavaScript 이벤트 리스너를 분석해보면 javascript:opinionList(페이지번호); 와 같은 JavaScript 함수 호출이 다음 페이지 로드를 담당한다는 것을 확인할 수 있었다.
<a href="#" onclick="javascript:opinionList(2); return false;">2</a>
Selenium WebDriver는 브라우저의 JavaScript 환경에서 임의의 JavaScript 코드를 실행할 수 있는 driver.execute_script() 메서드를 제공한다.
이 메서드를 활용하여, 웹사이트 내부적으로 다음 페이지를 로드하는 데 사용되는 JavaScript 함수(opinionList())를 우리가 직접 호출하는 방식으로 페이지를 이동시킬 수 있다.
driver.execute_script(f"javascript:opinionList({target_page});")
이 방식은 브라우저가 화면에 특정 요소를 렌더링하기를 기다릴 필요 없이, 필요한 액션을 직접 지시하는 방법이다.
opinion_count) 확인:math.ceil(total_reviews / 10)).execute_script 호출:while 루프 내에서 현재 page 번호에 1을 더한 target_page를 인자로 opinionList() 함수를 호출한다.driver.execute_script(f"javascript:opinionList({target_page});")time.sleep(2)).WebDriverWait을 사용하여 새로운 리뷰 엘리먼트가 로드될 때까지 기다리거나, 이전 페이지의 리뷰 엘리먼트가 사라지는 것(EC.staleness_of)을 기다린다.last_review_text_on_previous_page 변수를 사용하여, execute_script를 호출했음에도 불구하고 다음 페이지의 첫 번째 리뷰 내용이 이전 페이지의 마지막 리뷰 내용과 동일하다면, 더 이상 새로운 콘텐츠가 없다고 판단하고 크롤링을 종료한다.ABSOLUTE_MAX_PAGES (예: 500페이지) 제한을 두어, 혹시 모를 로직 오류나 웹사이트의 비정상적인 동작으로 인한 무한 루프를 방지한다.finally 블록을 통한 WebDriver 종료:try...except 블록 바깥의 finally 블록에서 driver.quit()을 호출하여 크롤링 성공 여부나 오류 발생 여부와 상관없이 항상 WebDriver(브라우저)를 깔끔하게 종료하고 리소스를 해제한다. 크롤러의 안정성과 시스템 리소스 관리에 매우 중요하다.execute_script는 웹사이트의 원래 동작 방식과 다를 수 있으며 문제가 발생할 수도 있다.