본문 바로가기
개발일지/selenium, BeautifulSoup, requests

BeautifulSoup youtube 채널 데이터 스크래핑, 시각화 기본 루틴

by 다니엘의 개발 이야기 2022. 7. 6.
320x100

실행 준비 및 테스트

 

from selenium import webdriver
from bs4 import BeautifulSoup

import chromedriver_autoinstaller
import time
import pandas as pd

 

chromedriver_autoinstaller.install()

 

browser = webdriver.Chrome('/Users/daniel_choi/opt/anaconda3/envs/ds_study/lib/python3.8/site-packages/chromedriver_autoinstaller/103/chromedriver')
url = 'https://youtube-rank.com/board/bbs/board.php?bo_table=youtube'
browser.get(url)

 

 

html = browser.page_source
soup = BeautifulSoup(html, 'html.parser')

 

channel_list = soup.select('table > tbody > tr')[:-1]

 

# 카테고리 정보
channel_list[0].select('p.category')[0].text.strip()

 

# 채널명

channel_list[0].select('h1 > a')[0].text.strip()

 

# 구독자수
# channel_list[0].select('td.subscriber_cnt')[0].text

# view 수
# channel_list[0].select('td.view_cnt')[0].text

# 동영상 수 
channel_list[0].select('td.video_cnt')[0].text

 

for i in channel_list:
    # 카테고리 정보
    category = i.select('p.category')[0].text.strip()

    # 채널명
    chnnal_name = i.select('h1 > a')[0].text.strip()

    # 구독자수
    subcribe = i.select('td.subscriber_cnt')[0].text

    # view 수
    views = i.select('td.view_cnt')[0].text

    # 동영상 수 
    videos = i.select('td.video_cnt')[0].text

    print(category, chnnal_name, subcribe, views, videos)
    break


result = []

for i in range(10):
    url = f'https://youtube-rank.com/board/bbs/board.php?bo_table=youtube&page={i+1}'
    browser.get(url)
    time.sleep(2)
    html = browser.page_source
    soup = BeautifulSoup(html, 'html.parser')
    channel_list = soup.select('table > tbody > tr')[:-1]
    
    for channel in channel_list:
        # 카테고리 정보
        category = channel.select('p.category')[0].text.strip()

        # 채널명
        chnnal_name = channel.select('h1 > a')[0].text.strip()

        # 구독자수
        subcribe = channel.select('td.subscriber_cnt')[0].text

        # view 수
        views = channel.select('td.view_cnt')[0].text

        # 동영상 수 
        videos = channel.select('td.video_cnt')[0].text

        datas = [chnnal_name, category, subcribe, views, videos]
        result.append(datas)

browser.close()
len(result)

 

df = pd.DataFrame(result)
df.info()

 

# df에 담긴 유튜브 랭킹 컬럼 값이 단순 숫자다. 따라서 이렇게 새로 지정해준다. (컬럼값 지정)
df.columns = ['title', 'category', 'subscriber', 'view', 'video']

# 엑셀로 담을건데, 행 값으로 나오던 숫자들 (인덱스값)은 제거 하고 저장한다.
df.to_excel('./youtube_rank.xlsx', index = False)


# 한글 변환 코드 (중요)
# 이 코드는 정확히, 자신의 컴퓨터 플랫폼 (윈도우 또는 맥 os)에서 사용 가능한
# 한글 폰트를 matplotlib에서 사용할 수 있도록 설정해 주는 코드다.

import matplotlib.pyplot as plt
import seaborn as sns
import platform
from matplotlib import font_manager, rc

get_ipython().run_line_magic('matplotlib', 'inline')
# %matplotlib inline

path = 'C:/Windows/Fonts/malgun.ttf'

if platform.system() == 'Darwin':
    rc('font', family='Arial Unicode MS')
elif platform.system() == 'Windows':
    font_name = font_manager.Fontproperties(fname=path).get_name()
    rc('font', family=font_name)
else:
    print('Unknown system sorry')

 

 

df = pd.read_excel('./youtube_rank.xlsx')
df.head(2)

 

# 데이터 값 변경하기.
# 데이터 중에서 만, 억 등의 표현이 있다. 이것을 변환해주는 원리적 코드다

df['subscriber'].str.replace('만', '0000')

# 하지만 이렇게 한다고 해서 바뀐 값이 적용되진 않는다.
# 옛날 값 = 새로운 값 으로 해줘야한다.

 

 

df['replaced_subscriber'] = df['subscriber'].str.replace('만', '0000')
df.head()

 

df.info()

 

# 시각화를 하기 위해서는 int값으로도 변환해줘야하는데, 여전히 object 로써 문자열 타입이다.
# 판다스 데이터 타입 변환 (pandas data type change)

df['replaced_subscriber'] = df['replaced_subscriber'].astype('int')
df.info()

 

# 카테고리별 채널 수와 구독자 수를 파이차트로 시각화하기 위한 준비

pivot_df = df.pivot_table(index = 'category', values = 'replaced_subscriber', aggfunc = ['sum', 'count'])
pivot_df.head(2)

 

 

# 데이터프레임의 칼럼명 변경하기
pivot_df.columns = ['subscriber_sum', 'category_count']
pivot_df.head(2)

# 기존에 이중컬럼이던것이 각 단일 컬럼으로 변경되었다.
# sum	                count
# replaced_subscriber	replaced_subscriber

 

# 기존의 인덱스 넘버가 데이터프레임 병합 a, b로 나뉘어있었다가 합쳐주었기 때문에 리셋해준다.
pivot_df = pivot_df.reset_index()
pivot_df.head()

 

# 데이터 프레임을 내림차순으로 정렬

pivot_df = pivot_df.sort_values(by='subscriber_sum', ascending=False)
pivot_df.head()

 

# 카테고리 별 구독자 수 시각화 하기
plt.figure(figsize=(30,10))
plt.pie(pivot_df['subscriber_sum'], labels=pivot_df['category'], autopct='%1.1f%%')
plt.show()

 

 

# 카테고리 별 채널 수 시각화 하기
pivot_df = pivot_df.sort_values(by='category_count', ascending=False)
pivot_df.head()
plt.figure(figsize=(30,10))
plt.pie(pivot_df['category_count'], labels= pivot_df['category'], autopct='%1.1f%%')
plt.show()


 

300x250