from urllib.request import urlopen
from bs4 import BeautifulSoup
from pytz import timezone
import pandas as pd
import datetime
๐ผ ํฌ๋กค๋ง์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(url, BeautifulSoup ๋ฑ)์ ์์ง์ผ์๋ฅผ ์ถ๋ ฅํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ํฌํธ
๐ผ ํฌ๋กค๋งํ ๋ญํน ๋ด์ค ํ๋ฉด
๊ฐ๋ฐ์ ๋ชจ๋๋ก ๋ณด๋ฉด ๐ฝ
์ด๋ฐ์์ผ๋ก ๋ณผ ์ ์๋ค. ์ด html ํ๊ทธ๋ค์ ํ์ธํ๋ฉด์ ํฌ๋กค๋งํด์ผํ๋ค.
# 1) ๋ฐ์ดํฐ ํ๋ ์ ์์ฑ
data = pd.DataFrame(columns=['์ธ๋ก ์ฌ๋ช
', '์์', '๊ธฐ์ฌ์ ๋ชฉ', '๊ธฐ์ฌ๋งํฌ', '์์ง์ผ์'])
# 2) ๋ค์ด๋ฒ ๋ญํน ๋ด์ค ์ ์ ์ฃผ์ ์ค๋น : https://news.naver.com/main/ranking/popularDay.naver
url = 'https://news.naver.com/main/ranking/popularDay.naver'
# 3) url์์ html ๊ฐ์ ธ์ค๊ธฐ
html = urlopen(url)
# 4) html์ ํ์ฑํ ์ ์๋ object๋ก ๋ณํ
bsObject = BeautifulSoup(html, 'html.parser', from_encoding='UTF-8')
๐ผ ๋จผ์ ํฌ๋กค๋งํ ๊ฒ์ ๋ด์ ๋ฐ์ดํฐ ํ๋ ์์ ํ์ฑํ๊ณ url์ ์ ๋ ฅํ urlopen์ ํด์ค๋ค. BeautifulSoup์ ์ด์ฉํ์ฌ ํ์ฑํ ์ ์๊ฒ ๋ณํ.
# 5) ๋ค์ด๋ฒ ๋ญํน ๋ด์ค ์ ๋ณด๊ฐ ์๋ div๋ง ๊ฐ์ ธ์ค๊ธฐ
div = bsObject.find_all('div', {'class', 'rankingnews_box'})
๐ผ ์์ ์บก์ณ๋ณธ์ ๋ค์ ๋ณด๋ฉด ํ์ธํ ์ ์๋ฏ ๋ญํน ๋ด์ค ์ ๋ณด๊ฐ div ํ๊ทธ ์์ rankingnews_box ๋ผ๋ ํด๋์ค๋ก ์ ์ธ๋์ด ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
find_all์ ์ฌ์ฉํ์ฌ ์ด๊ฒ๋ค์ ๊ฐ์ ธ์จ๋ค.
๐ผ ์์ ์บก์ณ๋ณธ์ ํ์ธํด๋ณด๋ฉด ์ธ๋ก ์ฌ๋ช
์ด
<strong class="rankingnews_name">์์์๊ฒฝ์ </strong>
๋ก ์ ์ธ๋์ด ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
# 6) ๋ค์ด๋ฒ ๋ญํน ๋ด์ค ์์ธ ์ ๋ณด ์ถ์ถ
for index_div in range(0, len(div)):
# 6-1) ์ธ๋ก ์ฌ๋ช
์ถ์ถ
strong = div[index_div].find('strong', {'class', 'rankingnews_name'})
press = strong.text
๐ผ ํด์ find๋ฅผ ์ด์ฉํด์ 'strong'์์ class ๋ช
rankingnews_name์ ์
๋ ฅํด์ ์ถ์ถ. ๊ทธ ํ press๋ผ๋ ๋ณ์์ ์ ์ฅ.
(โ๏ธ find์ find_all์ ์ฐจ์ด๋?
๐ผ ์๋ฅผ ๋ณด๋ฉด ul ํ๊ทธ ์ class = "rankingnews_list"๋ก ์ ์ธ๋์ด ๋ญํน ๋ด์ค๋ค์ด li ํ๊ทธ๋ก ํ๋ ํ๋ ์ ๋ ฅ๋์ด ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
# 6-2) ๋ญํน ๋ด์ค ์ ๋ณด ์ถ์ถ
ul = div[index_div].find_all('ul', {'class', 'rankingnews_list'})
for index_r in range(0, len(ul)):
li = ul[index_r].find_all('li')
for index_l in range(0, len(li)):
try: # ์์ธ์ฒ๋ฆฌ
# ์์
rank = li[index_l].find('em', {'class','list_ranking_num'}).text
# ๋ด์ค ์ ๋ชฉ
title= li[index_l].find('a').text
# ๋ด์ค ๋งํฌ
link = li[index_l].find('a').attrs['href']
# 7) dataframe ์ ์ฅ(append)
data = data.append({'์ธ๋ก ์ฌ๋ช
':press,
'์์':rank,
'๊ธฐ์ฌ์ ๋ชฉ':title,
'๊ธฐ์ฌ๋งํฌ':link,
'์์ง์ผ์':datetime.datetime.now(timezone('Asia/Seoul')).strftime('%Y-%m-%d %H:%M:%S')}, ignore_index=True)
except:
pass
print('Complets of ' + rank + ' : ', title)
print('----------------------------------------')
print(data)
๐ผ ํด์ for๋ฌธ์ ์ฌ์ฉํด ul ํ๊ทธ ์์ li ํ๊ทธ๋ค์ ํ๋ํ๋ ๋ถ๋ฌ์จ๋ค.
๊ทธ ํ ๋ for๋ฌธ๊ณผ try๋ฅผ ์ด์ฉํ์ฌ li ํ๊ทธ ์ ์์, ๋ด์ค ์ ๋ชฉ, ๋ด์ค ๋งํฌ๋ฅผ ๋ฐ์ดํฐ ํ๋ ์์ appendํ๋ค.
๐ผ ์ด๋ฅผ ๋ณด๋ฉด ์์๋ <em class="list_ranking_num">1</em>
,
๊ธฐ์ฌ ์ ๋ชฉ๊ณผ ๋งํฌ๋
<a href="https://n.news.naver.com/article/052/0001788082?ntype=RANKING" class="list_title nclicks('RBP.rnknws')">ํด๊ฐ์ฒ ยท๋ช
์ ๋๋ ค์ด ๋ฐ๋ ค๊ฒฌ๋ค..."์ถ์์ ๊ฐ์กฑ๊ณผ ํจ๊ปํ๊ณ ์ถ์ด์"</a>
(a ํ๊ทธ ์์ ๊ฐ์ด ์์ง๋ง ๋งํฌ๋ href๋ก ์ ์ธ๋์ด์์ด์ attrs['href']๋ก ์ถ์ถํ๊ณ ์ ๋ชฉ์ ํ
์คํธ๋ฏ๋ก .text๋ก ์ถ์ถ)
์์ง์ผ์๋ ์์์ ์ํฌํธํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ์ฌ ํ์ฌ์๊ฐ์ ํ๊ตญ์๊ฐ์ผ๋ก ๋ณํํ์ฌ ์ถ๋ ฅ.
data.to_csv('๋ค์ด๋ฒ๋ญํน๋ด์ค_๋ง์ด๋ณธ๋ด์ค_ํฌ๋กค๋ง_20220901.csv', encoding='utf-8-sig', index=False)
๐ผ ํฌ๋กค๋งํ ๋ฐ์ดํฐ๋ ์ ์ฅ!!
day_df = pd.read_csv('/content/๋ค์ด๋ฒ๋ญํน๋ด์ค_๋ง์ด๋ณธ๋ด์ค_ํฌ๋กค๋ง_20220901.csv')
๐ผ ๊ทธ ํ ๋ฐ์ดํฐ ํ๋ ์ ํ์์ผ๋ก ๋ถ๋ฌ์จ๋ค.
day_df['๊ธฐ์ฌ์ ๋ชฉ'].replace('[^\w]', ' ', regex=True, inplace=True)
๐ผ ๊ทธ ๋ค์์๋ ๊ธฐ์ฌ์ ๋ชฉ์ ์๋ ํน์๋ถํธ๋ค์ ์์ ๊ธฐ ์ํ ์ ์ฒ๋ฆฌ๋ฅผ ํด์ค๋ค.
import matplotlib.pyplot as plt
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
๐ผ ์๋ํด๋ผ์ฐ๋๋ฅผ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ํฌํธ.
์ฝ๋ฉ์ ํ๊ธ ๊นจ์ง ๋ฐฉ์ง ์ฝ๋๋ ์คํ์์ผ์ฃผ์ด์ผ ํจ!!
# wordCloud ๋ผ์ด๋๋ฒ๋ฆฌ์์๋ ํ๋์ ๋ฌธ์์ด๋ก ์ ๊ณตํด์ผํจ
# 391์ ๊ธฐ์ฌ์ ๋ชฉ์ ํ๋์ text๋ก ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
day_text = " ".join(li for li in day_df.๊ธฐ์ฌ์ ๋ชฉ.astype(str))
day_text
๐ผ ์๋ํด๋ผ์ฐ๋๋ฅผ ์ํ ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
plt.subplots(figsize=(25,15))
wordcloud = WordCloud(background_color='white', width=1000, height=700, font_path=fontpath).generate(day_text)
plt.axis('off')
plt.imshow(wordcloud, interpolation='bilinear')
plt.show()
๐ผ ์๋ํด๋ผ์ฐ๋๋ฅผ ์คํ์ํค๋ฉด!
๐ผ ์ด๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค. ์ด๋ 9์ 12์ผ์ ๊ธฐ์ค์ผ๋ก ํฌ๋กค๋ง๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ํ ์๋ ํด๋ผ์ฐ๋์ด๋ค.
๋๊ธ ๋ง์ ๋ด์ค๋ ๋งํฌ๋ง ์์ ํ๊ณ ์ฝ๋๋ ์์ ๋์ผํ๊ฒ ํ๋ฉด ๋๋ค.
(๋งํฌ:https://news.naver.com/main/ranking/popularMemo.naver)
data.to_csv('๋ค์ด๋ฒ๋ญํน๋ด์ค_๋๊ธ๋ง์๋ด์ค_ํฌ๋กค๋ง_20220901.csv', encoding='utf-8-sig', index=False)
memo_df = pd.read_csv('/content/๋ค์ด๋ฒ๋ญํน๋ด์ค_๋๊ธ๋ง์๋ด์ค_ํฌ๋กค๋ง_20220901.csv')
๐ผ ๋ฐ์ดํฐ ์ ์ฅ ํ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์จ ๋ค์
import re
def clean_text(inputString):
text_rmv = re.sub('[-=+,#/\?:^.@*\"โป~ใ!ใโ|\(\)\[\]`\'โฆใ\โ\โ\โยท]', ' ', inputString)
return text_rmv
# text ๋ถ์ด๋ฉด์ ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
memo_text = " ".join(clean_text(li) for li in memo_df.๊ธฐ์ฌ์ ๋ชฉ.astype(str)) # df.๊ธฐ์ฌ์ ๋ชฉ = df['๊ธฐ์ฌ์ ๋ชฉ']
๋ง์ด ๋ณธ ๋ด์ค์ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ. re๋ผ๋ ๊ฒ์ ์ํฌํธ ํ ํ ํน์๊ธฐํธ๋ฅผ ์ญ์ ํ๋ ํจ์๋ฅผ ์ ์ธํ๋ค. ๊ทธํ join์ ์ด์ฉํด ํ ์คํธ๋ฅผ ๋ถ์ผ ๋ ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ๊น์ง ํ๋ฒ์ ํ๋ ๋ฐฉ์.
๊ทธ ํ ์๋ ํด๋ผ์ฐ๋๋ฅผ ํด์ฃผ๋ฉด(์ฝ๋๋ ์์ ๋์ผํ๋ค)
๐ผ ์ด๋ฐ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค(์ด ์ญ์ 9์ 12์ผ์ ๋ญํน๋ด์ค ๊ธฐ์ค ์๊ฐํ)