selenium 을 이용해 특정상품 네이버쇼핑에서 순위 확인하기
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×tamp=&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×tamp=&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()
결과값