just-coding-it

파이썬으로 네이버 쇼핑 리스트를 크롤링하자

fffman 2022. 11. 7. 23:13

오늘은 네이버 쇼핑을 크롤링하는 기능을 구현해볼 것이다.

URL은 https://search.shopping.naver.com/search/all?query=키보드&frm=NVSHATC 이다. 네이버 쇼핑에서 "키보드" 를 검색한 1페이지에 해당한다.

 

네이버 쇼핑몰도 서버에서 모든 HTML을 만들어 주지 않는다. 간단히 브라우저의 javascript 기능을 잠시 disabled해두고 새로고침만 해봐도 추가적인 목록이 렌더링 되지 않는 걸 확인할 수 있다.

크롬 개발자 도구의 예시

그러면 어디에서 해당 내용들을 불러오는걸까. 특정 엔드포인트를 호출하면 상품 목록을 불러올 수 있을까?

개발자도구의 네트워크 탭을 살펴봐도 좋고, HTML코드를 둘러봐도 좋다. 주어진 정보들을 살펴보다보면 어디서 정보를 가져올 수 있을지 단서를 발견하게 된다.

 

열심히 둘러보던 중, HTML에서 script태그 중, id값이 __NEXT_DATA__라는 태그가 눈에 들어왔다. 내용 전체가 json형태이고 페이지에 관한 데이터를 가지고 있는듯 했다. 찾아보니 next.js의 SSR 방식인 것 같다.

 

자 그럼 해당 json을 분석하기 쉽도록 일단 파일로 저장해보자.

import json
import requests
from bs4 import BeautifulSoup as bs

url = 'https://search.shopping.naver.com/search/all?query=키보드&frm=NVSHATC'
response = requests.get(url)
html = response.text

soup = bs(html, 'html.parser')
script = soup.select_one('#__NEXT_DATA__')
data = json.loads(script.text)

with open('test.json', 'w', encoding='utf-8') as f:
    f.write(json.dumps(data, indent=4, ensure_ascii=False))

저장된 파일을 분석해보니, 확실히 감이 온다.

props.pageProps.banners.initialState.products.list에 상품 목록이 저장되어 있다.

또한 각 목록들은 item.productTitle로 제품명을 확인할 수 있고, item.adId를 가지고 있으면 광고에 해당하는 상품이라는 것도 파악할 수 있었다.

 

따라서 광고가 아닌 1페이지의 상품을 얻어오려면 아래와 같이 코딩하면 되겠다.

import json
import requests
from bs4 import BeautifulSoup as bs

url = 'https://search.shopping.naver.com/search/all?query=키보드&frm=NVSHATC'
response = requests.get(url)
html = response.text

soup = bs(html, 'html.parser')
script = soup.select_one('#__NEXT_DATA__')
data = json.loads(script.text)

props = data['props']
page_props = props['pageProps']
banners = page_props['banners']
initial_state = page_props['initialState']
products = initial_state['products']['list']

for i, product in enumerate(products, start=1):
    item = product['item']
    isAd = 'adId' in item
    title = item['productTitle']
    if not isAd:
        print(i, title)

페이지의 변경 및 페이지당 아이템 숫자는 url의 쿼리스트링을 조금만 바꿔주면 되니 그리 어렵지 않다. 이로써 네이버 쇼핑 페이지도 문제없이 크롤링 할 수 있을 것이다.