본문 바로가기
PROGRAMMING/Python

[PYTHON] 파이썬 유튜브_크롤링 (COLDPLAY X BTS)

by HYUNHP 2021. 10. 9.
반응형

안녕하세요 파이썬과 관련하여 추가적으로 필요한 정보가 있으시면,

DATA101에서 확인 가능하십니다.

감사합니다.


안녕하세요, Hello

이번에는 유튜브 크롤링을 진행해보려고 합니다.

신사업 구축, 경쟁사 분석, 시장 동향 등 다양한 목적으로 유튜브 데이터를 수집하여, 활용할 수 있습니다.

- 댓글 내 이메일 주소 등을 활용한, 서비스 이용자 DB 확보

- 댓글 내 영상 시간을 활용한 구독자 하이라이트 검토

- 댓글 반응을 통한 영상 우호도 확인

- 댓글 텍스트 데이터를 활용한 머신러닝/딥러닝 학습 목적

데이터 수집에 활용할 영상은 2021년 9월 30일에 등록된, Coldplay X BTS - My Universe입니다.

 

kmong.com/gig/341599

별도의 유튜브 크롤링 데이터가 필요하면, 이미지의 링크를 통해 연락주시면 회신드리도록 하겠습니다.


페이지 구성

1. LIBRARY IMPORT

2. 크롤링 전 세팅

3. 소스코드

4. CSV 저장


1. LIBRARY IMPORT

LIBRARY는 아래와 같습니다

 

import pandas as pd
import time
from tqdm.auto import tqdm
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

a. Chrome driver(크롬 드라이버) 설치

Selenium을 사용해서 웹 자동화를 위해 크롬 웹 드라이버를 설치합니다.

ChromeDriver - WebDriver for Chrome 사이트에 들어가서 Driver를 다운받습니다.


b. from selenium.webdriver.common.by import By

각 element에 따라 method를 여러개 사용하는 것 보다 By로 정리하기 쉽습니다.

driver.find_element(By.<속성>, '<속성 값>')으로 사용 가능하며,

복수의 항목을 찾을 경우에는, find_elements로 할 수 있습니다.


c. from selenium.webdriver.common.keys import Keys

키보드 입력을 입력하여, SCROLL UP, DOWN, 텍스트 입력 등을 수행할 수 있습니다.

키보드 입력은 send_keys(*value) 함수를 통해 할 수 있습니다.


d. from selenium.webdriver.support.ui import WebDriverWait

0. Wait till Load Webpage(로딩 대기)

브라우저에서 해당 웹 페이지의 요소들을 로드하는 데 시간이 걸립니다.

이로인해 element가 없다는 error를 회피하기 위해, 해당 요소가 전부 준비가 될 때까지 대기해야 합니다.

1. Implicit Waits(암묵적 대기)

driver.implicitly_wait(time_to_wait=5)

찾으려는 element가 로드될 때까지 지정한 시간만큼 대기할 수 있습니다.

2. Explicit Waits(명시적 대기)

time.sleep(secs)

element 값 여부에 상관없이 지정된 시간을 대기한다.


e. from selenium.webdriver.support import expected_conditions as EC

expected_conditions(EC)는 만약 element를 찾을 수 있었으면 True를, 아니라면 False를 반환합니다.


2. 크롤링 전 기본 세팅

 

# 크롤링 전 세팅
chrome_driver_path = r'(크롬드라이브 설치 경로)'

# 크롤링 URL
# 향후 찾고 싶은 영상 URL만 변경
url_path = 'https://www.youtube.com/watch?v=3YqPKLZF_WU'

# 크롤링 반복 횟수
repeat = 3

3. 소스코드

 

# 댓글 작성자
commenter_lst = []
# 댓글
comment_lst=[]
# 좋아요 개수
like_count_lst = []
# 크리에이터 하트 여부
heart_exist_lst = []

with Chrome(executable_path = chrome_driver_path) as driver:
    # 찾으려는 대상이 불러올 때까지 지정된 시간만큼 대기하도록 설정한다.
    # 인자는 초(second) 단위이며, Default 값은 0초이다. 
    wait = WebDriverWait(driver, 20)
    driver.get(url_path) # 영상 url
    time.sleep(3)
    
    # 유튜브 실행 시 자동 영상 재생일 경우, 영상 종료되면 바로 다음 영상으로 넘어가게 된다.
    # 이를 방지하기 위해, 유튜브 영상 중지 후 크롤링 진행
    if driver.find_element_by_class_name("ytp-play-button").get_attribute('aria-label') == '일시중지(k)':
        driver.find_element_by_class_name("ytp-play-button").click()
    else:
        pass
    
    # 최초 1회 PAGE_DOWN
    wait.until(EC.visibility_of_element_located((By.TAG_NAME, "body"))).send_keys(Keys.PAGE_DOWN)
    time.sleep(3)

    # END 반복 실행
    # 실행 횟수 체크
    for item in tqdm(range(repeat)): # END버튼 반복 횟수, 1회당 20개씩 댓글 업데이트 
        wait.until(EC.visibility_of_element_located((By.TAG_NAME, "body"))).send_keys(Keys.END)
        time.sleep(1) # END버튼 클릭 이후, 1초 대기 후, 다시 END 버튼 진행
                
    # 크롤링 데이터 수집 진행

    # 작성자 가져오기
    # 댓글 작성자 중 확인된 사용자, 공식 아티스트 채널 값은 text로 가져올 시, (공백) 처리됨
    try:
        for commenter in tqdm(wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#author-text')))):
            # 작성자 이름 없는 경우에, 공백 표시
            # 확인된 사용자, 공식 아티스트 채널의 경우, innertext를 가져옴
            if commenter.text != '':
                commenter_lst.append(commenter.text)
            else:
                commenter_temp = commenter.get_attribute("innerText").strip().replace('\n', '')
                commenter_lst.append(commenter_temp)                
    except:
        # 크롤링 값이 없을 경우에
        commenter_lst.append('')

    # 댓글 가져오기    
    try:
        for comment in tqdm(wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#content-text')))):
            if comment.text != '':
                comment_temp = comment.text.replace('\n', ' ')
                comment_lst.append(comment_temp)
            else:
                comment_lst.append(' ')            
    except:
        # 크롤링 값이 없을 경우에
        comment_lst.append('')
                
    # 좋아요 개수 가져오기
    try:
        for like_count in tqdm(wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#vote-count-middle')))):
            if like_count.text != '':
                like_count_lst.append(like_count.text)
            else:
                like_count_lst.append('0')
    except:
        # 좋아요 개수가 없을 경우에
        like_count_lst.append('0')
        
    # 크리에이터 하트 여부 체크하기
    for creater_heart in tqdm(wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#creator-heart')))):
        # 크리에이터 하트 html 존재 여부로 체크
        try:
            if creater_heart.find_element_by_css_selector('#creator-heart-button'):
                heart_exist_lst.append('하트')
            else:
                heart_exist_lst.append('없음')
        except:
            # 크롤링 값이 없을 경우에
            heart_exist_lst.append('없음')           
        
print('done')

4. CSV 저장

 

# 저장 위치
save_path = r'(파일 저장 위치)'

df = pd.DataFrame({'댓글 작성자' : commenter_lst,
                   '댓글' : comment_lst,
                   '좋아요 개수' : like_count_lst,
                   '하트 유/무': heart_exist_lst})

# 인덱스 1부터 실행
df.index = df.index+1

# to_csv 저장
df.to_csv(save_path + '유튜브 댓글 크롤링 ' + str((repeat +1) * 20) +'개 크롤링.csv' , encoding='utf-8-sig')

print('save done')

 

이처럼 저장하게 되면 아래처럼 csv 파일이 저장됩니다

 

최종 결과물


■ 마무리

 

 

포스팅 내용이 학교 프로젝트, 데이터 구축, 업무 목적 등 다양한 목적에 도움이 되었으면 합니다.

위 포스팅은 카카오 티스토리, 네이버 블로그에도 동일하게 업로드합니다.

반응형

댓글