본문 바로가기
문송충의 코딩하기/파이썬 데이터 분석

[파이썬] - 아마존에서 삼성 QLED TV 고객 리뷰 크롤링해서 가져오기

by 동장군님 2020. 11. 3.
728x90
반응형

[파이썬] - 아마존에서 삼성 QLED TV 고객 리뷰 크롤링해서 가져오기

이번 포스팅에서는 세계 최대 이커머스 사이트 아마존에서 소비자들이 남긴 제품 리뷰를 파이썬으로 크롤링해서 가져오고자 한다. 예전 직장에서 많이 했던 작업이라서 굉장히 추억이 많은 코드다. 우선 오늘은 데이터를 어떻게 가져오는지만 해보고 다음 시간에는 추출한 텍스트 데이터를 가져오고 상세한 텍스트 분석을 해보고자 한다. 텍스트 마이닝 분야는 내가 굉장히 약한 분야라서 시간이 조금 오래 걸린다. 여하튼 이번 포스팅에서는 우리가 모두 탑승하고 있는 삼성전자의 QLED TV 제품에 고객들이 남긴 리뷰를 다루겠다. 링크는 아래와 같다.

 

www.amazon.com/product-reviews/B084RGZ3P7/ref=cm_cr_arp_d_viewopt_srt?ie=UTF8&reviewerType=all_reviews&sortBy=recent&pageNumber=1

 

Amazon.com

Enter the characters you see below Sorry, we just need to make sure you're not a robot. For best results, please make sure your browser is accepting cookies.

www.amazon.com

 

 

Python Code #1 - 데이터 추출

크롤링의 대표 패키지 Selenium을 활용해서 고객 리뷰를 가져오도록 하겠다. 코드는 굉장히 길어서 어려워 보이지만 하나하나 살펴보면 엄청 쉬운 코드다. 파이썬을 조금 공부한 사람들이라면 다 이해할 것이다. 여기서는 리뷰 타이틀, 리뷰 작성 날짜, 리뷰 평점, 리뷰 콘텐츠를 반복문을 통해서 갖고 오겠다.

 

from selenium import webdriver as wd
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import requests
import re
import time
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup as bs
import pandas as pd
import os
from datetime import datetime

def dong_amazon_reviews(asin):
    
    options=Options()
    options.add_argument("--headless")
    options.add_argument("--window-size=1920x1080")
    options.add_argument("disable-gpu")
    # 여기 Path 부분에 Chromedriver.exe가 설치된 경로를 지정
    driver=wd.Chrome(executable_path = 'chromedriver.exe',options=options)

    url=f'https://www.amazon.com/product-reviews/{asin}/ref=cm_cr_arp_d_viewopt_srt?ie=UTF8&reviewerType=all_reviews&sortBy=recent&pageNumber=1'
    #Driver Get Url
    driver.get(url)
    driver.implicitly_wait(10)
    res=driver.page_source
    obj=bs(res,'html.parser')

    # 총 리뷰수 가져오기
    rev=obj.select('#filter-info-section > div > span')[0].get_text().strip()
    rev=int(re.findall('\d+',rev)[1])

    titles=[]
    stars=[]
    dates=[]
    contents=[]

    while len(titles)<rev:
        time.sleep(3)
        source=driver.page_source
        bs_obj=bs(source,"html.parser")
        
        #리뷰 타이틀 가져오기
        for i in bs_obj.findAll('a',{'data-hook':'review-title'}):
            titles.append(i.get_text().strip())
            
        
        #리뷰 날짜 가져오기
        for n in bs_obj.findAll('span',{'data-hook':'review-date'}):
            nn=''.join(n.get_text().split(' ')[-3:])
            date=datetime.strptime(nn, '%B%d,%Y').date()
            dates.append(date)
        
        #리뷰 내용 가져오기
        for a in bs_obj.findAll('span',{'data-hook':'review-body'}):
            contents.append(a.get_text().strip())
        
        #리뷰 평점 가져오기
        for u in bs_obj.findAll('i',{'data-hook':'review-star-rating'}):
            stars.append(int(u.get_text()[0]))
            
        for u in bs_obj.findAll('i',{'data-hook':'cmps-review-star-rating'}):
            stars.append(int(u.get_text()[0])) 
        
        if len(titles) ==rev:
            break
        
        #다음 리뷰 페이지롤 넘어갈 수 있는 Next Button 클릭
        driver.find_element_by_xpath('//*[@id="cm_cr-pagination_bar"]/ul/li[2]/a').click()
        WebDriverWait(driver, 15).until(
                    # 지정한 한개 요소가 올라면 웨이트 종료
            EC.presence_of_element_located((By.XPATH, '//*[@id="a-autoid-3"]/span/input'))
        )
        
    driver.close()
    driver.quit()        
    
    df=pd.DataFrame({'Date':dates,'Rating':stars,"Title":titles,"Body":contents})
    
    return df 

data=dong_amazon_reviews('B084RGZ3P7')

data.to_csv('삼성TV 아마존 리뷰.csv')

 

삼성TV 아마존 리뷰.csv
0.11MB

위 코드를 돌리고 데이터 프레임을 csv 파일로 출력하면 위 자료처럼 나오는 것을 확인할 수 있을 것이다. 코드가 문제 있다면 댓글로 남겨주기 바란다.

 

 

Python Code #2 - 데이터 시각화

아마존에서는 제품 리뷰 평점을 1점부터 5점까지 부여할 수 있다. 그래서 첫 번째로는 리뷰 평점 별로 리뷰 개수를 아래와 같이 세보고 시각화해보도록 하겠다.

import matplotlib.pyplot as plt

df=pd.DataFrame(data.groupby('Rating').count()['Title'])
df=df.rename(columns={"Title": "리뷰 수"})

plt.rcParams["font.family"] = 'Malgun Gothic'
plt.rcParams["font.size"] = 12
plt.figure(figsize=(16,8))

plt.bar(df.index,df['리뷰 수'])
for x,y in enumerate(list(df['리뷰 수'])):
    plt.text(x+1, y, y, fontsize=13, color='#ff0000', 
                    horizontalalignment='center', verticalalignment='bottom')
    
plt.title('평점 별 리뷰 개수')
plt.ylim(0,80,20)
plt.show()

 

위 그래프를 보면 알 수 있겠지만 삼성 QLED TV는 호불호가 조금 갈리는 제품으로 보인다. 5점, 4점 다음으로 가장 많은 평점이 1점이다. 이거만 봐도 확실히 삼성 QLED TV 제품에 불만이 있다는 점은 확실하다고 볼 수 있다.

 

 

그 다음으로는 시계열로 월별 리뷰 수를 확인하도록 하겠다. 데이터를 보니 삼성 QLED Q80 TV 제품은 아마존에 20년 2월에 출시됐다. 그래서 데이터에서는 현재 약 8개월치의 리뷰 데이터가 있는 상황이다.

 

import datetime as dt

data['year_month']=data['Date'].apply(lambda x: str(x.year) +'-'+ str(x.month) if len(str(x.month)) >1 else str(x.year) +'-'+ '0' + str(x.month))
data=data.sort_values(by='year_month',ascending=True)
summary=pd.DataFrame(data.groupby('year_month').count()['Title'])
summary=summary.rename(columns={'Title':'리뷰 수'})

plt.rcParams["font.family"] = 'Malgun Gothic'
plt.rcParams["font.size"] = 12
plt.figure(figsize=(16,8))

plt.plot(summary.index,summary['리뷰 수'])
for x,y in enumerate(list(summary['리뷰 수'])):
    plt.text(x,y,str(y)+'개',fontsize=13, color='#ff0000', 
                    horizontalalignment='center', verticalalignment='bottom')

plt.legend(['리뷰 수'], loc='upper left')
plt.title('삼성 QLED TV 월별 소비자 리뷰 수')
plt.ylim(0,50,10)

데이터를 시각화해서 보니 7월, 8월, 9월 여름 성수기에 확실히 제품이 많이 팔렸는지 제품 리뷰가 많이 작성된 점을 확인할 수 있다. 

 

다음 포스팅에서는 이번에 추출한 리뷰 콘텐츠를 가지고 텍스트 마이닝을 해보도록 하겠다! 

 

 

 

 

 

728x90
반응형

댓글