본문 바로가기
웹 크롤링(Web Crawling)/크롤링 프로젝트(시행 착오 노트)

[Python] 네이버 쇼핑 상품 정보 크롤링 프로그램

by 현군의 coding&IT story 2024. 2. 5.

구현 목표 (요구 사항)

- 크롤링 대상 url : https://shopping.naver.com/home

 

네이버쇼핑

온/오프라인 상품 탐색과 쇼핑정보, 가격비교, 제품리뷰 등을 만나보세요

shopping.naver.com

- 네이버 쇼핑 페이지에서 검색어 입력 시 상품의 "링크, 상품명, 가격, 사업자번호" 순으로 데이터가 저장되도록 한다.

- 저장 형식 : 엑셀(.xlsx) 파일

- 조회 페이지 : 30~40페이지

Trouble Shooting(문제 상황 및 해결)

마주친 문제 상황 1 ) XPATH가 규칙적인 상황에서 그 모든 값을 가지고 와야 하는 경우에 직면

XPATH가 다음과 같이 규칙성을 띄는 경우, 이 모든 요소들을 다 가지고 와야한다면 어떻게 해야할까?

//*[@id="content"]/div[1]/div[2]/div/div[1]/div/div/div[2]/div[2]/strong/span[1]/span/em

//*[@id="content"]/div[1]/div[2]/div/div[2]/div/div/div[2]/div[2]/strong/span[1]/span/em

//*[@id="content"]/div[1]/div[2]/div/div[3]/div/div/div[2]/div[2]/strong/span[1]/span/em

 

이 경우 중간에 div[1], div[2], div[3] 부분만 다르고 나머지 부분은 모두 같다.

그래서 다음과 같이 추출할 수 있다.

    subject_elements = driver.find_elements(By.XPATH, '//*[@id="content"]/div[1]/div[2]/div/div[*]/div/div/div[2]/div[1]/a')
//*[@id="content"]/div[1]/div[2]/div/div[*]/div/div/div[2]/div[1]/a

위 코드처럼 추출하면 중간에 div[*]인 부분은 div[1], div[2] .. div[9999] 등 아무 숫자나 와도 다 가져올 수 있다.

마주친 문제 상황 2 ) 페이지마다 무한 스크롤 처리를 해야 했다.

- 페이지를 내리기 전에는 요소들이 숨겨졌다가 페이지를 내리면 요소들이 나타나는 구조로 페이지에 있는 모든 상품의 정보를 가져오려면 스크롤을 끝까지 내린 다음 요소들을 가져와야 했다.

- 이전 스크롤의 Y 위치를 저장해놓고, END키를 눌러 스크롤을 한 번 내린 다음의 Y 위치를 저장한 다음에,

이전 스크롤의 Y위치 == 스크롤을 내린 후의 Y위치 이면 더 이상 내릴 곳이 없다는 의미이므로 무한 스크롤을 종료하고,

이전 스크롤의 Y위치 != 스크롤을 내린 후의 Y위치 이면 아직 끝까지 내리지 않았다는 의미이므로 스크롤을 한 번 더 내리기 위해 스크롤을 내린 후의 Y위치를 before_height 변수에 저장함으로써 끝까지 내리도록 할 수 있다.

- 네이버에서 무한 스크롤 처리 로직은 거의 정형화 된 것 같다.

import time

before_height = driver.execute_script("return window.scrollY")

 while True:
        time.sleep(1)
        driver.find_element(By.CSS_SELECTOR, "body").send_keys(Keys.END) # 스크롤 내리기
        # 스크롤 되는 동안 로딩 시간을 준다.
        time.sleep(1)
        # 스크롤 후 높이 체크
        after_height = driver.execute_script("return window.scrollY")

        if after_height == before_height: # 끝까지 내린 경우 내린 window.ScrollY 위치가 이전 위치와 같다.
            break # 이 경우에는 탈출한다.

        before_height = after_height

 

구현 영상