2021.04.07 - [프로젝트/유튜브 댓글분석] - [댓심]유튜브 댓글 크롤링 프로그램 제작기1
우선 대댓글이 달린 원 댓글을 대댓글 데이터에 함께 저장하려 시도했다. FK 개념으로 원 댓글에 고유 번호를 부여한 후 대댓글에 FK를 부여하려 했지만, 대댓글이 달리지 않은 댓글의 경우 크롤링 할 내용이 없기 때문에 NULL 값이 아닌 아예 건너뛰게 된다.
정리해보면
1. 대댓글이 없는 댓글을 식별할 수 없다
2. 원 댓글과 인덱스를 맞출 수 없음.
3. 댓글과 대댓글의 관계를 정보화 할 수 없음
역시 비슷한 문제를 해결하신 분이 계셨다.
blog.naver.com/blueqnpfr1/222069530876
[PYTHON] 셀레니움(selenium)을 활용한 유튜브 댓글 크롤링
계기오랜만에 포스팅을 한다. 최근에 알게 된 지인으로부터 크롤링 외주 의뢰를 하나 받았는데그걸 하고 나...
blog.naver.com
과정은 이렇다.
1. 유튜브 페이지 열기
2. 페이지 스크롤 다운
3. 대댓글 다열기
4. 파싱 - 댓글별 대댓글 파싱
추가해보자면 댓글과 대댓글의 관계만 표시해서 가져오면 끝!
여기서 조금 수정해야 할 건 기존의 댓글 내용, 아이디, 좋아요수를 개별적으로 파싱했던 것을 댓글별로 파싱하는 것으로 수정해야 한다.
comments = soup.select("yt-formatted-string#content-text")
comments = soup.find_all("ytd-comment-thread-renderer", class_ = "style-scope ytd-item-section-renderer")
댓글을 찾고, 그 안에 댓글 내용, ID, 좋아요수 그리고 대댓글까자 불러와야 하기 때문에 더 상위개념을 파싱했다.
최종 생각한 테이블을 정리해보면
(원 댓글)
인덱스 | 아이디 | 내용 | 좋아요수 |
1 | a | ㅇㅇ | 123 |
2 | b | ㅇㅇㅇ | 23 |
3 | c | ㅇㅇㅇㅇ | 15 |
4 | d | ㅇㅇㅇㅇ | 746 |
(대댓글)
원댓글 인덱스 | 아이디 | 내용 | 좋아요수 |
1 | xw | ㅇㅇ | 123 |
이렇게 정리해서 보면 좋을 듯 하다.
최종 결과물은 이렇다!
최종 코드
#패키지 불러오기
from selenium import webdriver as wd
from bs4 import BeautifulSoup
import time
import re
import pandas as pd
#기본 설정
driver = wd.Chrome(executable_path="C:/Users/MSI/OneDrive/바탕 화면/youtube/chromedriver.exe")
url = 'https://www.youtube.com/watch?v=yDD4K-XxuDY'
driver.get(url)
#스크롤 내리기
last_page_height = driver.execute_script("return document.documentElement.scrollHeight")
while True:
driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);")
time.sleep(3.0)
new_page_height = driver.execute_script("return document.documentElement.scrollHeight")
if new_page_height == last_page_height:
time.sleep(3.0)
if new_page_height == driver.execute_script("return document.documentElement.scrollHeight"):
break
else:
last_page_height = new_page_height
#대댓글 다열기
rereple = driver.find_elements_by_css_selector("#more-replies")
for re in rereple:
driver.execute_script("arguments[0].click()", re)
#파싱
source = driver.page_source
soup = BeautifulSoup(source, 'lxml')
#데이터 저장
ids = []
com = []
like = []
N = 1
comments = soup.find_all("ytd-comment-thread-renderer", class_ = "style-scope ytd-item-section-renderer")
re_ids = []
re_coms = []
re_likes = []
#댓글별 ID,내용,좋아요,대댓글 저장
for comment in comments :
#ID 넣기
ids_temp = str(comment.find("span", class_="style-scope ytd-comment-renderer").text)
ids_temp = ids_temp.replace('\n', '')
ids_temp = ids_temp.replace(' ', '')
ids_temp = ids_temp.replace(' ', '')
ids_temp = ids_temp.replace(' ', '')
ids.append(ids_temp)
#댓글 내용
com_temp = str(comment.find("yt-formatted-string", id="content-text").text)
com_temp = com_temp.replace('\n', '')
com.append(com_temp)
#좋아요
likes_temp = str(comment.find("span", id = "vote-count-middle").text)
likes_temp = likes_temp.replace('\n', '')
likes_temp = likes_temp.replace(' ', '')
likes_temp = likes_temp.replace(' ', '')
like.append(int(likes_temp))
#대댓글
replies = comment.find_all("ytd-comment-renderer", class_="style-scope ytd-comment-replies-renderer")
for replie in replies:
#ID 넣기
re_ids_temp = str(replie.find("span", class_="style-scope ytd-comment-renderer").text)
re_ids_temp = re_ids_temp.replace('\n', '')
re_ids_temp = re_ids_temp.replace(' ', '')
re_ids_temp = re_ids_temp.replace(' ', '')
re_ids_temp = re_ids_temp.replace(' ', '')
re_id = (N, re_ids_temp)
re_ids.append(re_id)
#댓글 내용
re_com_temp = str(replie.find("yt-formatted-string", id="content-text").text)
re_com_temp = re_com_temp.replace('\n', '')
re_com = (N, re_com_temp)
re_coms.append(re_com)
#좋아요
re_likes_temp = str(replie.find("span", id = "vote-count-middle").text)
re_likes_temp = re_likes_temp.replace('\n', '')
re_likes_temp = re_likes_temp.replace(' ', '')
re_likes_temp = re_likes_temp.replace(' ', '')
re_like = (N, re_likes_temp)
re_likes.append(re_like)
N = N+1
re_df = pd.DataFrame({"INDEX": list(range(1, len(ids)+1)), "ID": ids, "REPLY" : com, "LIKE" : like})
rere_id = pd.DataFrame(re_ids)
rere_com = pd.DataFrame(re_coms)
rere_like = pd.DataFrame(re_likes)
rere_df = pd.DataFrame({"INDEX" : rere_id[0], "ID": rere_id[1], "REPLY" : rere_com[1], "LIKE" : rere_like[1]})
이젠 분석할 시간
'프로젝트(홀딩) > 유튜브 댓글분석' 카테고리의 다른 글
[댓심] Pororo 설치가 부른 나비효과 (7) | 2021.05.05 |
---|---|
[댓심]댓글 분석1 : 가상환경 구축 (0) | 2021.04.28 |
[댓심]댓글 크롤링 프로그램 제작1 : 코드 완성 (0) | 2021.04.07 |
두 번째 프로젝트 : 댓심 프로젝트 (0) | 2021.03.31 |
댓글