.

[Python] 네이버 웹툰과 별점 그리고 언론보도

by 담배맛구마

파이썬 스터디 그룹을 진행하면서 웹 파싱해서 Pandas로 데이터를 확인하는 코드를 짤 일이 있었는데 나중에 쓸일이 있을 것 같아 기록해둔다.

 

Naver webtoon

간단한 네이버 웹툰에 대한 파싱 코드를 작성했었다. 특정 웹툰에 대한 정보를 Dictionary List로 출력하는 내용이다.

import bs4
import requests
from urllib.parse import urlparse

BASE_URL_WEBTOON = 'https://comic.naver.com'


def get_webtoon_list(base, page, result=[]):
    resp = requests.get(base + page)
    soup = bs4.BeautifulSoup(resp.text, 'html.parser')
    soup = soup.find('div', {'id': 'content', 'class': 'webtoon'})

    result += [ {
        'no': [q.split('=')[1] for q in urlparse(tr.a['href']).query.split('&') if q.startswith('no=')][0],
        'title': tr.find('td', {'class': 'title'}).text.strip(),
        'rank': tr.div.strong.text.strip(),
        'date': tr.find('td', {'class': 'num'}).text.strip(),
        'link': base + tr.a['href']
    } for tr in soup.table.find_all('tr', {'class': ''})[2:] ]

    # If next tag exists, Go to next page.
    _soup = soup.find('div', {'class': 'paginate'})
    if (page := _soup.find('a', {'class': 'next'})):
        return get_webtoon_list(base, page.get('href'), result)
    else:
        return result
        
    return result

# 복학왕 : '/webtoon/list.nhn?titleId=626907'
# 독립일기 : '/webtoon/list.nhn?titleId=748105'
result = get_webtoon_list(BASE_URL_WEBTOON, '/webtoon/list.nhn?titleId=626907')

result에 대한 값은 다음과 같이 출력된다.

[{'no': '335',
  'title': '333화 청첩장 3화',
  'rank': '9.68',
  'date': '2021.03.02',
  'link': 'https://comic.naver.com/webtoon/detail.nhn?titleId=626907&no=335&weekday=wed'},
 {'no': '334',
  'title': '332화 청첩장 2화',
  'rank': '9.61',
  'date': '2021.02.23',
  'link': 'https://comic.naver.com/webtoon/detail.nhn?titleId=626907&no=334&weekday=wed'},
  ...
 ]

 

Pandas and metaplotlib

그냥 별점 기준으로 그래프로 그려봤다.

import pandas as pd

import seaborn as sns
import matplotlib.pyplot as plt # must be import to use seaborn
from matplotlib import rc

plt.rcParams['axes.unicode_minus'] = False
rc('font', family='AppleGothic')

pd.set_option('display.max_columns', None)  # or 1000
pd.set_option('display.max_rows', None)  # or 1000
pd.set_option('display.max_colwidth', None)  # or 199

data = pd.DataFrame(result)
data.set_index('no', inplace=True)
data.index = data.index.astype('int64')
data.loc[:, 'date'] = data.loc[:, 'date'].astype('datetime64')
data.loc[:, 'rank'] = data.loc[:, 'rank'].astype('float64')
data = data.sort_index(axis=0, ascending=True)
data.head()

x = data.index
y = data.loc[x, 'rank']
plt.figure(figsize=(10,6))
plt.xlabel('회차')
plt.ylabel('별점')
plt.plot(x, y)

별점이 왜 저렇게 튀어버렸을까? 제일 낮은 별점은 2015년에 연재된 46화. 바락 우바마1로 현재 3.86이다.

 

Journal

저정도로 별점이 튀었다면, 특히나 기안84 정도쯤 되는 셀럽이라면 언론보도가 있었을 것이다.

import json
import requests
import datetime

def get_journal(date, title):
    date_ = datetime.datetime.strptime(date, '%Y-%m-%d') + datetime.timedelta(days=30) 
    payload = {
        "indexName": "news",
        "searchKey": title,
        "searchKeys": [{}],
        "byLine": "",
        "searchFilterType": "1",
        "searchScopeType": "1",
        "searchSortType": "date",
        "sortMethod": "date",
        "mainTodayPersonYn": "",
        "startDate": date,
        "endDate": date_.strftime('%Y-%m-%d'),
        "newsIds":[], "categoryCodes":[], "providerCodes":[], "incidentCodes":[], "networkNodeType":"","topicOrigin":"","dateCodes":[],
        "editorialIs": False,
        "startNo": 1,
        "resultNumber": 10,
        "isTmUsable": False,
        "isNotTmUsable": False
    }
    headers = {
        'Content-Type': 'application/json; charset=utf-8',
        'X-Requested-With': 'XMLHttpRequest',
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15',
        'Aceept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Encoding': 'gzip, deflate, br',
        'Origin': 'https://www.bigkinds.or.kr',
        'Referer': 'https://www.bigkinds.or.kr/v2/news/search.do'
    }
    resp = requests.post('https://www.bigkinds.or.kr/api/news/search.do', headers=headers, data=json.dumps(payload))

    return json.loads(resp.text)

웹툰이 게시된 일자와 해당 회차의 제목으로 기사를 검색해보니... 그렇다고 한다. 

journal = get_journal('2015-04-28', '46화. 바락 우바마 1')
for jn in journal['resultList']:
    print(f'''{jn['DATE']} : {jn['TITLE']}''')
    
# 20150429 : 복학왕 '바락 우바마' 등장에 악플 쏟아져 '또 닭 변신하나?'
# 20150429 : 복학왕 '바락 우바마' 등장에 네티즌들 술렁술렁 "무리수"
# 20150429 : 복학왕, ‘우바바’ 등장에 평점 3.3…독자들 뿔났다, 왜?
# 20150429 : 복학왕, ‘우바마’ 등장에 평점 3.3…독자들 뿔났다, 왜?
# 20150429 : 복학왕, ‘우바바’ 등장에 평점 3.3…독자들 뿔났다, 왜?
# 20150429 : 네이버 수요웹툰 복학왕 46화..오바마 아닌 우바마 떴다?..한국 잠행이유는?
# 20150429 : 네이버 인기 웹툰 '복학왕' 오바마 논란

기사 본문에서 긍정적인 단어들과 부정적인 단어들을 꺼내다가 봐도 재밋지 않을까 싶다.

 

반응형

'Dev-' 카테고리의 다른 글

[React-Native] 끄적이기  (0) 2020.04.01
[React-Native] 시작하기  (0) 2020.03.31
[Python] Bandizip Updater  (3) 2019.06.11
[Python] DNS Packet 구조 코드화  (0) 2018.07.29
[C#] Adobe Flash Player 자동 업데이트 문제와 해결  (0) 2018.07.29

블로그의 정보

정윤상이다.

담배맛구마

활동하기