PYTHON

[NLP①] 네이버 쇼핑 리뷰 크롤링 (생수)

한번해보즈아 2022. 6. 19. 12:35

이번에는 정형데이터가 아닌 비정형데이터를 분석하도록 하겠습니다. 분석하기 앞서 데이터를 직접 추출할건데 네이버 쇼핑에 판매하고 있는 삼다수 리뷰를 긁어 올것입니다. NLP 시리즈에서는 삼다수, 백산수, 석수, 몽베스트, 스파클, 아이시스 총 6가지의 브랜드의 데이터를 각각 2,000개씩 긁어와서 약 12,000개를 사용할 예정입니다.

네이버 쇼핑에서 제공하고 있는 리뷰는 네이버 쇼핑 자체에서 만들어진 리뷰가 아니라 "우물샵", "NS홈쇼핑", "장대리"등 다양한 인터넷 쇼핑몰에서 리뷰를 긁어오고 있는 형태입니다. 

 

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
from time import sleep
import requests
import re
import pandas as pd
import numpy as np
import os

from selenium.webdriver.common.keys import Keys

import warnings
warnings.filterwarnings('ignore')

selenium, BeautifulSoup 등 기본적인 라이브러리를 가져옵니다. 

 

 

name=['삼다수']
category=['별점']

#삼다수 제품 페이지
ns_address="https://search.shopping.naver.com/catalog/27965424524?query=%EC%83%9D%EC%88%98&NaPm=ct%3Dl4dtm8j4%7Cci%3D1fcd6007615ed624e6d57b7435a0427975caba75%7Ctr%3Dslsl%7Csn%3D95694%7Chk%3D2da538351834fa5690b8afefbb68c3debcac098c"
#xpath 리뷰 페이지로 이동할수있는 주소 저장
shoppingmall_review="/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[2]/div/div[2]/ul/li[3]/a/strong"

header = {'User-Agent': ''}
d = webdriver.Chrome('chromedriver.exe') # webdriver = chrome
d.implicitly_wait(3)
d.get(ns_address)
req = requests.get(ns_address,verify=False)
html = req.text 
soup = BeautifulSoup(html, "html.parser")
sleep(2)
element=d.find_element_by_xpath(shoppingmall_review)
d.execute_script("arguments[0].click();", element)
sleep(2)

위의 코드를 실행하면 쇼핑몰리뷰 페이지로 이동하게 된다.

 

 

 

shoppingmall_review="/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[2]/div/div[2]/ul/li[3]/a/strong"

여기에 있는 html/bod/ ... 은 크롤링하려는 페이지에서 F12를 누르고 ctrl + shift + c를 눌러서 마우스오버를 하면 경로를 확인할수 있다.

 

def add_dataframe(name,category,reviews,stars,cnt):  #데이터 프레임에 저장
    #데이터 프레임생성
    df1=pd.DataFrame(columns=['type','category','review','star'])
    n=1
    if (cnt>0):
        for i in range(0,cnt-1):
            df1.loc[n]=[name,category,reviews[i],stars[i]] #해당 행에 저장
            i+=1
            n+=1
    else:
        df1.loc[n]=[name,category,'null','null']
        n+=1    
    return df1


# 최신순 리뷰 가져오기
d.find_element_by_xpath("/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[5]/div[2]/div[1]/div[1]/a[2]").click()  #스크롤 건드리면 안됨
name_=name[0]
category_=category[0]
reviews=[]
stars=[]
cnt=1   #리뷰index
page=1

데이터 프레임 함수 생성 및 , 리뷰, 별점을 저장해둘 리스트 생성

 

while True:
    j=1
    print ("페이지", page ,"\n") 
    sleep(2)
    while True: #한페이지에 20개의 리뷰, 마지막 리뷰에서 error발생
        try:
            star=d.find_element_by_xpath('/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[5]/ul/li['+str(j)+']/div[1]/span[1]').text
            stars.append(star)
            review=d.find_element_by_xpath('/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[5]/ul/li['+str(j)+']/div[2]/div[1]/p').text
            reviews.append(review)
            if j%2==0: #화면에 2개씩 보이도록 스크롤
                ELEMENT = d.find_element_by_xpath('/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[5]/ul/li['+str(j)+']/div[2]/div[1]/p')
                d.execute_script("arguments[0].scrollIntoView(true);", ELEMENT)       
            j+=1
            print(cnt, review ,star, "\n")
            cnt+=1 
        except: break
            
    sleep(2)
    
    if page<11:#page10
        try: #리뷰의 마지막 페이지에서 error발생
            # page += 1
            next_page=d.find_element_by_xpath('/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[5]/div[3]/a['+str(page+1)+']').click() 
            page += 1
            
        except: break #리뷰의 마지막 페이지에서 process 종료
        
    else : 
        try: #page11부터
            # page += 1
            if page%10==0: next_page=d.find_element_by_xpath('/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[5]/div[3]/a[12]').click()
            else : next_page=d.find_element_by_xpath('/html/body/div/div/div[2]/div[2]/div[2]/div[3]/div[5]/div[3]/a['+str(page%10+2)+']').click()
            page+=1
           
        except: break
    if page == 101:
        break
        
df4=add_dataframe(name_,category_,reviews,stars,cnt)
df4
type	category	review	star
1	삼다수	별점	무라벨로 주문했는데 유라벨로 왔습니다.\n재고가 없다면 관련해서 구매자가 문의하기 ...	평점2
2	삼다수	별점	3번째 주문합니다. 앞의 두 번 모두 현관문이 열리는 방향이 아니라 문의 중심축 옆...	평점5
3	삼다수	별점	별하나 주기도 아까움\n돈더주고 무라벨 시켰더니 유라벨로 발송\n본사가 송장을 유라...	평점1
4	삼다수	별점	배송이 무지 오래 걸렸습니다. 3주? 보통 쿠팡에서 사서 담날 받다가 여긴 무라벨이...	평점4
5	삼다수	별점	늘 삼다수 애정하는데 금번에는 물들이 병입구가 다 찌그러져 배송되었어요. 어떤 충격...	평점1
...	...	...	...	...
1996	삼다수	별점	물이 맛있네요 시원하고	평점5
1997	삼다수	별점	배송도 빠르고 최고예요	평점5
1998	삼다수	별점	만족하며 마시고 있어요	평점5
1999	삼다수	별점	너무좋아요 또 구매예정	평점5
2000	삼다수	별점	배달이 뻘라서 좋습니다	평점3
2000 rows × 4 columns

다른곳에서 처음 코드를 가져왔을때는 12, 22 ,32 페이지가 안긁어와졌는데 하루종일 머리털 잡아뜯은 결과 page 

+= 1을 위에가 아닌 밑에다가 해주면 정상적으로 리뷰를 긁어온다 .

추가로 리뷰갯수는 100페이지(즉 2,000개) 까지만 긁어와지고 이후로는 안되는거같다 ... 방법 아시는분은 알려주시면 감사하겠습니다