Data Analysis/LifeStyles

카카오 지도에서 오레노라멘 맛집 리뷰 파이썬으로 크롤링 & 분석 해보자

동장군님 2021. 7. 2. 22:27

내가 가장 좋아하는 라멘 집을 하나 꼽자면 바로 상수역 쪽에 위치한 오레노 라멘이다. 미슐랭 가이드로 꼽힐 만큼 진짜 맛있는 라멘인데 오늘 포스팅에서는 오레노라멘을 방문한 사람들이 오레노 라멘을 어떻게 평가하는지 알아보도록 하겠다. 네이버가 방문 리뷰 수가 압도적으로 많아서 네이버 리뷰를 분석하면 좋겠지만 네이버 리뷰를 도저히 가져올 방법은 못 찾아서 대안으로 카카오 지도에서 리뷰를 가져오도록 하겠다. 역시나 이번에도 파이썬을 사용하도록 하겠다.

 

1. 카카오 지도에서 "합정 라멘" 검색 결과 가져오기

카카오 지도에서 바로 오레노라멘을 검색해서 결과를 가져올 수 있지만 그냥 참고차 합정 라멘을 검색해서 오레노 라멘을 가져오는 방식을 한번 구현해보도록 하겠다. Selenium 라이브러리가 설치되어 있고, chromedriver가 있으면 아래 코드로 쉽게 데이터를 가져올 수 있을 것이다.

 

%matplotlib inline

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

import warnings
warnings.filterwarnings("ignore")

from selenium import webdriver
from bs4 import BeautifulSoup
import re
import time
from selenium.webdriver.common.keys import Keys
import math

path = 'chromedriver'
excutable_path = 'chromedriver.exe'
source_url = "https://map.kakao.com/"
driver = webdriver.Chrome(executable_path=excutable_path)

driver.get(source_url)

search=driver.find_element_by_xpath('//*[@id="search.keyword.query"]')
search.send_keys("합정 라멘")
search.send_keys(Keys.ENTER)

time.sleep(2)

html = driver.page_source
soup = BeautifulSoup(html, "html.parser")
moreviews = soup.find_all(name="a", attrs={"class":"moreview"})

driver.close()

urls=[]
for i in moreviews:
    page_url=i.get("href")
    urls.append(page_url)
    
ramen=urls[0]

 

2. 오레노 라멘 방문 리뷰 가져오기

 

오레노 라멘 상세 페이지 (https://place.map.kakao.com/1916682638)로 들어가면 볼 수 있는 총 278개 리뷰를 크롤링하도록 하겠다.

 

columns = ['score', 'review']
df = pd.DataFrame(columns=columns)

stars=[]
reviews=[]

driver = webdriver.Chrome(executable_path=excutable_path)
driver.get(ramen)

last_height = driver.execute_script("return document.body.scrollHeight")

while True:
            
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")

    time.sleep(2)

            # 스크롤 다운 후 스크롤 높이 다시 가져옴
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height

    tmp=driver.page_source
    tmp2 = BeautifulSoup(tmp, "html.parser")

    total_reviews=int(tmp2.select('#mArticle > div.cont_evaluation > div.evaluation_sorting > a > span.color_b')[0].get_text())
    pages=math.ceil(total_reviews/5)
    print(pages)
    time.sleep(5)

for i in range(1,pages+1):
    t1=driver.page_source
    t2=BeautifulSoup(t1, "html.parser")
    t3=t2.find(name="div", attrs={"class":"evaluation_review"})

    star=t3.find_all('em',{'class':'num_rate'})
    review=t3.find_all('p',{'class':'txt_comment'})

    stars.extend(star)
    reviews.extend(review)

    i=i+1
                
    if i > pages:
        break

    next_page = driver.find_element_by_xpath("//a[@data-page='" + str(i) + "']")
    next_page.send_keys(Keys.ENTER)
    time.sleep(5)
    
driver.close()

columns = ['score', 'review']
df = pd.DataFrame(columns=columns)
for s, r in zip(stars, reviews):
    row = [s.text[0], r.find(name="span").text]
    series = pd.Series(row, index=df.columns)
    df = df.append(series, ignore_index=True)
    
df.to_csv('oreno_ramen.csv',encoding='utf-8-sig')

위 코드가 문제 없이 돌아간다면 아래와 같이 사이트에서 확인할 수 있는 리뷰와 동일한 수치의 데이터를 가져올 수 있을 것이다.

 

 

3. 많이 언급된 키워드 시각화

텍스트 마이닝을 하고 싶지만 내 실력은 전혀 그 수준이 아니기 때문에 이번 포스팅에서는 270 여개 리뷰에서 가장 많이 언급된 키워드 100개를 뽑아서 어떤 특징이 있는지 보도록 하겠다. 

 

아래 코드가 복잡해보이기는 하는데 보면 굉장히 쉽다. 리뷰에서 한글만 갖고 오고, 그다음에 문자를 단어로 구분하고, 또 그중에서 명사만 따로 추출하겠다.

 

import re

df_=df[df['review']!='']

def text_cleaning(text):

    hangul = re.compile('[^ ㄱ-ㅣ가-힣]+')
    result = hangul.sub('', text)
    return result

df_['ko_text'] = df_['review'].apply(lambda x: text_cleaning(x))
df_ = df_[df_['ko_text'].str.len() > 1]

from konlpy.tag import Okt 
okt=Okt()

nouns=[]
adj=[]

for i in df_['ko_text']:
    words=okt.pos(i)
    for u in words:
        if u[1] =='Noun':
            nouns.append(u[0])
    
nouns=[x for x in nouns if len(x)>1]

from collections import Counter

countn = Counter(nouns)
n_100=countn.most_common(30)
tb=pd.DataFrame(n_100)
tb.columns=['Keywords','Counts']

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_style('darkgrid')
plt.rcParams["font.family"] = 'Malgun Gothic'
plt.subplots(figsize=(20,13))
ax=sns.barplot(x="Counts", y="Keywords", data=tb)
ax.set_yticklabels(tb['Keywords'], fontsize=12)

ax.set_title('오레노라멘 리뷰 내 키워드별 언급량',fontsize=20)

for p in ax.patches:
    ax.annotate("%d" % p.get_width(), xy=(p.get_width(), p.get_y()+p.get_height()/2),
            xytext=(5, 0), textcoords='offset points', ha="left", va="center")

 

KONLPY 라이브러리를 설치하고 사용하는 방법이 조금 짜증나기는 하는데 해당 부분만 잘해놓으면 굉장히 빠르게 코드가 돌아갈 것이다. 아래 그래프는 위 코드의 결과물이라고 볼 수 있다.

 

확실히 국물과 육수에 특히 언급이 많은 점이 특이하다. 여기서 "추가"라는 키워드도 같이 많이 언급되고 있는데 오레노 라멘 단골로서 예상하자면 여기 라멘은 면이 추가 리필이 가능해서 해당 키워드가 탑에 위치한 것으로 보인다. 아래 무료도 같은 맥락이지 않을까 생각된다. 미슐랭 가이드 맛집이기 때문에 미슐랭도 꽤 많이 언급되고 있다.