김빵디

특정 유투브채널 게시글을 텍스트 크롤링해보자(feat.세분일레분) 본문

외로운 싸움/Selenium

특정 유투브채널 게시글을 텍스트 크롤링해보자(feat.세분일레분)

김빵디 2022. 7. 14. 12:19
728x90

 

막연하게 고민고민하다가 크롤링한 작업으로 분석까지 해보고싶었다.

1. 특정 유투브 채널을 접속한다.

2. 텍스트 크롤링(아이디 / 글 내용 / 좋아요)

 

크롤링 시도 전 HTML 구조에 대해 파악한 후 진행해야 한다.
(구조에 따라 방법이 달라지기 때문)

스크롤 다운방식으로 html 값들이 나오는 구조일경우 그에따른 코드가 필요하다.
대표적인 예시) 유투브


BeautifulSoup이란?
- HTML과 XML 파일로부터 데이터를 추출하기 위한 파이썬 라이브러리
- HTML 문서 → Python 객체로 변경

from bs4 import BeautifulSoup


soup = BeautifulSoup(html, 'lxml')
#html→'lxml' parser 사용하여 분석
▶ 아래 코드에서는 'lxml' 말고 'html.parser'를 사용했다.

※ 웹페이지가 정확한 html규격을 지키고있지 않으면,
사용하는 파서에 따라서 html유효한 태그가아니면 무시/틀린태그 매칭 등 작업이 이루어진다고 하니 참고하기!

나는 특정유투브를 고르다가 세븐일레븐을 골랐다.. 만두를 사면 명품을 준다구...!?

다들 어떤 댓글들을 달았는지 함 보자!

 

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
from tqdm import tqdm
from openpyxl import Workbook

#import
import time
import pandas as pd



url = 'https://www.youtube.com/watch?v=g9l7OCcGvDA'
coments = []

wb = Workbook(write_only=True)
ws = wb.create_sheet()

#driver
#driver = webdriver.Chrome()
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(1)
driver.maximize_window()
#유투브 바로가기

driver.get(url)

#body = driver.find_element_by_tag_name('body')
#위 코드로 하면 자바스크립트 오류떠서 아래의 drive.execute_script로 진행해야한다.

driver.execute_script('window.scrollTo(0,800)')
time.sleep(1)

last_height = driver.execute_script('return document.documentElement.scrollHeight')
#return document.documentElement.scrollHeight: 현재 스크롤된 페이지 좌표

#스크롤 내리기
while True:
    #driver.execute_script('windows.scrollTo(0, document.body.scrollHeight);')
    driver.execute_script('window.scrollTo(0, document.documentElement.scrollHeight);')
    #driver.execute_script: 자바스크립트를 파이썬으로 받아오기
    time.sleep(3.0)
    
    new_height = driver.execute_script('return document.documentElement.scrollHeight')

    if new_height == last_height:
        break
    last_height = new_height

time.sleep(1)

#유투브 댓글 가져오기(대댓글X)
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')

user_ID = soup.select('#author-text > span')
user_comment = soup.select('yt-formatted-string#content-text')
user_Like = soup.select('#vote-count-middle')

str_userID = []
str_userComment = []
str_userLike = []

for i in range(len(user_ID)):
    
    str_tmp = str(user_ID[i].text)
    str_tmp = str_tmp.replace('\n', '')
    str_tmp = str_tmp.replace('\t', '')
    str_tmp = str_tmp.replace('', '')
    str_tmp = str_tmp.lstrip()
    str_tmp = str_tmp.rstrip()
    #문자열 왼/오 공백까지 없애주기
    str_userID.append(str_tmp)
    
    
    str_tmp = str(user_comment[i].text)
    str_tmp = str_tmp.replace('\n', '')
    str_tmp = str_tmp.replace('\t', '')
    str_tmp = str_tmp.replace('                ', '')
    str_tmp = str_tmp.lstrip()
    str_tmp = str_tmp.rstrip()
    str_userComment.append(str_tmp)
    
    str_tmp = str(user_Like[i].text)
    str_tmp = str_tmp.replace('\n', '')
    str_tmp = str_tmp.replace('\t', '')
    str_tmp = str_tmp.replace('                ', '')
    str_tmp = str_tmp.lstrip()
    str_tmp = str_tmp.rstrip()
    str_userLike.append(str_tmp)

data = {'ID': str_userID, 'comment': str_userComment, 'Like': str_userLike}
pd_data = pd.DataFrame(data)
pd_data.to_excel('경로/파일이름.xlsx')

 

간간히 주석에다가 남겨두긴했지만.. 나도 참고문서를 보고 해본거라 자세한건 아래의 문서들을 같이 보기!

 

결과

 

문서를 열어보니 이쁘게 나왔다! 뿌듯뿌듯,,

 

 

 

 

 

[참고문서]

- 크롤링방법
https://summaryday.tistory.com/34
https://somjang.tistory.com/entry/PythonSelenium%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EC%9C%A0%ED%8A%9C%EB%B8%8C-%EB%8C%93%EA%B8%80-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0
- 파서 차이점
https://blog.naver.com/shino1025/221366807529
- 공백제거
https://blockdmask.tistory.com/568

728x90