Python/웹 스크래핑 및 웹 자동화

selenium 을 이용해 특정상품 네이버쇼핑에서 순위 확인하기

P_eli 2024. 2. 27. 17:56
728x90
반응형

1. 필요한 라이브러리 가져오기

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
import time
import chromedriver_autoinstaller

 

  • selenium: 웹 페이지를 자동으로 조작하기 위한 라이브러리
  • chromedriver_autoinstaller: Chrome 브라우저의 드라이버를 자동으로 설치하기 위한 도구

2. Chrome 드라이버 자동 설치

chromedriver_autoinstaller.install()

 

Chrome 브라우저를 제어하기 위해 필요한 Chrome 드라이버를 자동으로 설치합니다.

3. Chrome 웹 드라이버 인스턴스 생성

driver = webdriver.Chrome()

 

웹 드라이버를 생성하여 Chrome 브라우저를 제어할 수 있는 인스턴스를 생성합니다.

4. 크롤링 할 페이지 태그 확인하기

현재 네이버쇼핑 HTML 코드를 확인하면 a태그에 엘리먼트 data-nclick 로 순위를 가져올수 있고 data-i 로 코드번호를 가져올 수 있는걸 확인할 수 있습니다.

# 상품코드
current_items_count = len(driver.find_elements(By.CSS_SELECTOR, "a[data-i]"))

# 상품랭킹
target_data = target_item_element.get_attribute('data-nclick')

 

상품랭킹을 print로 확인해보면 "N=a:lst*N.image,r:121,i:85961363225" 를 가져오는걸 확인할 수 있습니다.

하지만 위에 태그의 엘리먼트 값을 보면 "N=a:lst*N.title,i:85961363225,r:121" 인데 i 값과 r값이 순서가 바뀌어 출력되는걸

볼 수 있습니다. "data-nclick" 속성 값을 가져올 때 순서가 바뀌어 반환된 것으로 보입니다. 이는 HTML 요소에서 속성이 정의된 순서와는 관련이 없을 수 있습니다. 즉, 속성 순서는 HTML 요소에 대한 정보를 저장하는 데 사용되지 않으므로 순서가 바뀔 수 있습니다.

따라서 속성 값을 출력해서 확인 할 필요가 있습니다.

 

필요한 값은 r:121 만 필요하므로 split를 이용해 문자열을 잘라옵니다.

# 타겟 상품 순위 추출
rank = target_data.split(",")[1]
# rank 출력값 : r:121
real_rank = rank.split(":")[1]
# real_rank 출력값 : 121

5. 페이지 파라미터 확인해보기

search_link 를 보면 파라미터 값에 pagingIndex 보시면 현재 페이지를 확인 할 수 있습니다. pagingIndex를 변수로 바꾸어주어 해당 페이지에서 타겟 상품을 못찾으면 페이지를 이동 시키기 위해 다음 페이지로 가기위해 for문으로 묶어줍니다. 

search_query = "배즙"

for page_index in range(1, 15):
    search_link = f"https://search.shopping.naver.com/search/all?adQuery={search_query}&origQuery={search_query}&pagingIndex={page_index}&pagingSize=40&productSet=total&query={search_query}&sort=rel&timestamp=&viewType=list"
    driver.get(search_link)

6. 스크롤 해야하는지 확인해보기

각 페이지의 검색 결과를 확인하고, 원하는 상품의 위치를 찾기 위해 스크롤을 내려주는 코드를 추가 시킵니다.

while True:
        driver.execute_script("window.scrollBy(0,10000);")
        time.sleep(2)
        current_items_count = len(driver.find_elements(By.CSS_SELECTOR, "a[data-i]"))
        if current_items_count == prev_items_count:
            break
        prev_items_count = current_items_count

 

7. 상품의 고유 코드를 이용해 해당 상품의 요소를 찾아 순위정보 추출하기

상품의 고유 코드를 사용하여 해당 상품의 요소를 찾고, 그 요소에서 순위 정보를 추출합니다.

try:
        target_code = "85961363225"
        target_item = f"a[data-i='{target_code}']"
        target_item_element = driver.find_element(By.CSS_SELECTOR, target_item)
        target_data = target_item_element.get_attribute('data-nclick')
        rank = target_data.split(",")[1]
        real_rank = rank.split(":")[1]
        total_rank = int(real_rank) - (int(page_index) - 1) * 40
        break
    except NoSuchElementException:
        print(f"{page_index} 페이지에서 타겟 상품을 찾을 수 없음.")

8. 결과 출력 및 종료

최종적으로 얻은 결과를 출력하고, Chrome 웹 드라이버를 종료합니다.

print("내 상품의 등수는", real_rank, "등 입니다.")
print(f"내 상품은 {page_index} 페이지의 {total_rank} 번째에 노출되고 있습니다.")

driver.quit()

 

 

전체코드

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException  # 예외를 처리하기 위해 추가
import time
import chromedriver_autoinstaller

# 크롬 드라이버 자동 설치
chromedriver_autoinstaller.install()

# 크롬 웹 드라이버 인스턴스 생성
driver = webdriver.Chrome()
real_rank = -1
total_rank = -1
search_query = "배즙"

for page_index in range(1, 15):
    # 네이버 쇼핑 검색 링크 설정
    search_link = f"https://search.shopping.naver.com/search/all?adQuery={search_query}&origQuery={search_query}&pagingIndex={page_index}&pagingSize=40&productSet=total&query={search_query}&sort=rel&timestamp=&viewType=list"

    # 검색 링크로 이동
    driver.get(search_link)

    # 이전에 로드된 아이템 수
    prev_items_count = 0

    # 무한 스크롤로 추가 아이템 로드
    while True:
        # 스크롤하여 아이템 추가 로드
        driver.execute_script("window.scrollBy(0,10000);")
        time.sleep(2)
        # 현재 로드된 아이템 수 확인
        current_items_count = len(driver.find_elements(By.CSS_SELECTOR, "a[data-i]"))
        # 추가로 아이템이 로드되지 않으면 반복 종료
        if current_items_count == prev_items_count:
            break
        # 이전 아이템 수 업데이트
        prev_items_count = current_items_count

    try:
        # 타겟 상품 코드 설정
        target_code = "85961363225"
        target_item = f"a[data-i='{target_code}']"
        # 타겟 상품 요소 찾기
        target_item_element = driver.find_element(By.CSS_SELECTOR, target_item)
        # 타겟 상품 데이터 추출
        target_data = target_item_element.get_attribute('data-nclick')
        # 타겟 상품 순위 추출
        rank = target_data.split(",")[1]
        real_rank = rank.split(":")[1]
        # 실제 등수 계산
        total_rank = int(real_rank) - (int(page_index) - 1) * 40
        # 타겟 상품을 찾았으므로 반복 종료
        break
    except NoSuchElementException:
        # 타겟 상품을 찾지 못한 경우 메시지 출력
        print(f"{page_index} 페이지에서 타겟 상품을 찾을 수 없음.")

# 결과 출력
print("내 상품의 등수는", real_rank, "등 입니다.")
print(f"내 상품은 {page_index} 페이지의 {total_rank} 번째 에 노출되고 있습니다.")

# 크롬 드라이버 종료
driver.quit()

 

결과값

 

728x90
반응형