데이터사이언스

외모지상주의 - 베스트 댓글 크롤링하기

ghtis1798 2021. 1. 12. 16:42

외모지상주의 댓글 수집

제가 즐겨 보는 네이버 웹툰인 외모지상주의 베스트 댓글을 수집하고 살펴보았습니다.

인기작가 '박태준'님의 신작으로 논란도 많았지만 그만큼 핫했던 작품입니다.

사람들은 어떤 베스트 댓글을 좋아했고, 어떤 내용의 회차였는지 궁금해서 크롤링을 해보았습니다.

 

1. 댓글 수집하기

 

1.1 셀레니움을 활용한 데이터 수집

 

크롤링을 위해 셀레니움을 사용했습니다.

BeautifulSoup은 사용해 봤는데, 셀레니움을 요즘은 많이 사용하는 것 같더군요.

사용해보니 굉장히 강력한 툴이라는 생각이 들었습니다.

셀레니움을 사용하기 위해서는 Chromedriver를 먼저 설치해야 합니다.

chromedriver.chromium.org/downloads

 

Downloads - ChromeDriver - WebDriver for Chrome

WebDriver for Chrome

chromedriver.chromium.org

또한, 셀레니움은 Colab보다는 주피터노트북에서 사용하는 것을 추천드립니다.

Colab에서도 사용해보았으나, webdrive의 path를 설정해야 하는데 인식을 하지 못하더군요.

따라서 주피터 노트북에서 사용했습니다.

import pandas as pd
import numpy as np

import time

# selenium 라이브러리의 webdriver를 가져온다.
from selenium import webdriver

필요한 라이브러리는 pandas, numpy, time, selenium의 webdriver입닌다.

time은 크롤링 과정에 중간 중간 텀을 두기 위해 사용할 것입니다.

예를 들면 크롤링을 하다 1~2초간 멈추기 위함입니다.

계속해서 크롤링하면 웹사이트에서 봇으로 인식해 막아버리는 경우가 종종 있습니다.

따라서 time의 sleep()함수를 이용합니다.

 

# webdriver로 크롬을 설정
driver = webdriver.Chrome("chromedriver.exe")
# webdriver의 get 함수로 url 오픈 : 예시입니다.
driver.get("https://comic.naver.com/webtoon/detail.nhn?titleId=641253&no=1")

import한 webdriver를 통해 chromedriver.exe 파일을 설정합니다.

저는 작업중인 워킹디렉토리(소스 파일이 있는 폴더)에 chromedriver.exe 파일을 넣어두었습니다.

따라서 파일명만 path로 주었으나, 다른 곳에 설치하신 경우 절대 경로를 넣어주면 될 것 같습니다.

현재 워킹디렉토리가 어디인지 확인하는 방법은 다음과 같습니다.

# 현재 워킹디렉토리 확인하기.
# 해당 위치에 chromedriver.exe 파일이 있어야합니다.
import os
os.getcwd()

 

이후에는 driver.get()함수를 사용하면 웹 사이트를 띄울 수 있습니다.

get함수의 파라미터로 url 주소를 주면 됩니다.

수집한 댓글을 저장할 데이터 프레임을 생성합니다.

data = pd.DataFrame(data=[], columns=['회차','날짜','이름','아이디','댓글','좋아요'])

 

댓글을 수집하는 collector라는 함수를 만들었습니다.

def collector(driver, data, k):
    # webdriver.Chorme(path) 설정을 매 번 해줘야 오류가 안나네요.
    driver = webdriver.Chrome("chromedriver.exe")
    # k번째 회차의 외모지상주의 웹사이트 오픈
    url = 'https://comic.naver.com/webtoon/detail.nhn?titleId=641253&no='+str(k)
    driver.get(url)
    
    time.sleep(1)
    
    # 댓글창에 해당하는 프레임 선택
    driver.switch_to.frame('commentIframe')
    
    # 회차,이름,날짜,아이디,댓글,좋아요/싫어요 수 전체 수집
    num = k
    names = driver.find_elements_by_css_selector('.u_cbox_nick')
    dates = driver.find_elements_by_css_selector('.u_cbox_date')
    nicks = driver.find_elements_by_css_selector('.u_cbox_id')
    reviews = driver.find_elements_by_css_selector('.u_cbox_text_wrap')
    likes = driver.find_elements_by_css_selector('.u_cbox_tool')
    
    # 총 n개의 댓글이 수집되므로 해당 댓글 수만큼 for문을 돕니다.
    for i in range(len(names)):
        # for문을 돌며, 댓글별 회차,날짜,이름,아이디,댓글,좋아요/싫어요를 저장
        temp = []
        temp.append(num)
        temp.append(dates[i].text)
        temp.append(names[i].text)
        temp.append(nicks[i].text)
        temp.append(reviews[i].text)
        temp.append(likes[i].text)

        temp = pd.DataFrame(data=[temp], columns=data.columns)
        data = pd.concat([data,temp])

    # 열어두었던 driver를 닫습니다.
    driver.close()

    print(str(num) + '화 베댓 수집 완료')

    return data

 

이제 이 함수로 첫화인 1페이지부터 현재 기준 최신화인 321회까지의 댓글을 수집하겠습니다.

for k in range(1, 322):
    data = collector(driver, data, k)

 

수집이 잘 되었는 지 확인해봅니다.

data.head(10)

외모지상주의 베스트댓글

 

1.2. 데이터 전처리

 

현재 좋아요 컬럼에 좋아요와 싫어요 데이터가 같이 수집되어 있습니다.

\n을 기준으로 나눠줘야 할 것 같네요.

참고로 \n은 개행문자를 의미합니다.

수집하는데 꽤 오랜 시간이 걸렸으므로 원본 데이터는 남겨두도록 하겠습니다.

# 혹시 몰라서, 원본은 data에 남겨둡니다.
tmp = data.copy()

 

# 좋아요 컬럼의 str을 \n을 기준으로 나누고, 1번째(좋아요 수)값을 저장합니다.
tmp['좋아요1'] = tmp['좋아요'].str.split('\n').str[1]
tmp['싫어요'] = tmp['좋아요'].str.split('\n').str[3]

.str.split('\n')함수를 이용하면 \n 문자를 기준으로 문자열을 나눌 수 있습니다.

1번째 행을 실행하면 ['좋아요', '좋아요 수', '싫어요', '싫어요 수'] 결과값이 나옵니다.

그 중에서 str[1] : 1번째 값인 좋아요 수만 기록한 것입니다.

2번째 행도 마찬가지입니다.

 

# 좋아요, 싫어요 컬럼명을 df.columns 함수를 이용해 변경합니다.
tmp = tmp[['회차','날짜','이름','아이디','댓글','좋아요1','싫어요']]
tmp.columns = ['회차','날짜','이름','아이디','댓글','좋아요','싫어요']

그 후 전처리한 컬럼들만 뽑아내었습니다.

좋아요 이름이 겹치고 있네요..

원래 수집한 값을 좋아요/싫어요로 설정할 걸 그랬습니다. 

하지만 좋아요, 싫어요가 한 번에 수집될 줄은 몰랐기 때문에 그냥 지금이라도 바꿔주겠습니다.. 🤦‍♂️

 

tmp.head(3)

외모지상주의 댓글 전처리 결과

전처리하고 보니 분석에 더 용이한 데이터가 되었습니다.

마지막으로 엑셀파일로 저장해주겠습니다.

tmp.to_excel('외모지상주의_데이터.xlsx')

 

2. 데이터 살펴보기

 

2.1. 사람들이 가장 좋아한 댓글은 어떤 댓글일까?

 

저장한 데이터를 불러와서 작업을 하도록 하겠습니다.

data = pd.read_excel('외모지상주의_데이터_전처리.xlsx')

 

살펴보니 전처리한 데이터 그대로네요.

data.head(3)

불러온 댓글 데이터

 

사람들이 가장 좋아요를 많이 누른 댓글 10개만 보도록 하겠습니다.

dataframe의 sort_values는 정렬해주는 함수입니다.

ascending=False 옵션은 역순으로 정렬하겠다는 것이고요.

data.sort_values(by='좋아요', ascending=False).head(10)

외모지상주의 베댓 좋아요 Top 10

 

데이터를 보니 조금 신기하네요.

우선 현재 321회차까지 나와있는데, 대부분 초창기의 댓글이 가장 많은 공감을 받았습니다.

또한 대부분 주인공 '형석'의 조력자로 나오는 '재열'이라는 캐릭터에 대한 호감형 댓글입니다.

1번째 댓글은 재열이가 형석을 대신해 강아지를 입양하는 내용에 대한 댓글입니다.

물론 설정상 재열이라는 캐릭터는 개를 굉장히 무서워합니다.

그 외에도 690, 285, 570, 705, 555 댓글 모두 '재열'이라는 캐릭터에 대한 내용이군요.

추가로 810번은 어린시절 학교폭력을 당했던 '바스코'에 대한 내용입니다.

악인을 처벌하는 더 악한 악인으로 노랑 머리를 한 '김준구'에 대한 베스트 댓글입니다.

다소 잔인하지만 굉장한 사이다를 선사했던 내용입니다.

465번 댓글은 특정 웹툰 캐릭터에 대한 소름돋는 내용,

630번 댓글은 감동적인 부분에 대한 내용이네요.

 

2.2. 사람들이 싫어한 베스트 댓글은 무엇일까?

 

베스트 댓글을 사람들이 좋아하기만 하지는 않습니다.

해당 댓글을 싫어하는 사람도 있죠.

이번엔 베스트 댓글 중에 싫어요 Top 10을 보도록 하겠습니다.

data.sort_values(by='싫어요', ascending=False).head(10)

외모지상주의 베댓 싫어요 Top 10

142, 143회차는 '함선농'이라는 지방에서 올라온 사람에 대한 묘사로 논란이 있었던 회차입니다.

특이한 사투리에 시골 산적? 같은 인물 묘사로 지방사람을 비하한다는 논란이 제기되었는데요.

비하가 맞다. 작가가 지방사람들에 대한 혐오가 있는 것 같다는 사람도 있었고,

그냥 웹툰인데 재미로 보면되지 왜 저렇게 진지하냐는 의견도 있었죠.

따라서 싫어요 Top 10에 집계된 것 같습니다.

추가적인 싫어요는 전자 vs 후자를 고르는 내용이나,

베댓되면 뭐 하겠다는 내용의 댓글에 싫어요가 많이 눌렸네요.

이런 댓글은 이제 그만 올라왔으면 좋겠습니다. 🤦‍♂️🤦‍♂️

이상으로 즐겨보는 웹툰의 베스트 댓글을 크롤링 해 보았습니다. 😀