<jupyter_start><jupyter_text>참고 사이트 : https://kimcoder.tistory.com/170  0. 크롤링 계획 세우기1. 필터로 업로드 날짜를 적용2. 업로드 날짜별로 잘 정렬되었는지 확인하기 위해 업로드 날짜별가 최신 순서로 위에서부터 콘솔창에 출력  1. 크롤링할 페이지 접속youtube에 접속한다.https://www.youtube.com   2. 크롤링 가능 여부 확인(필수)1. Youtube 메인 화면에서 돋보기 버튼을 누른 후 "세종대학원"입력하고 엔터2. 영상을 검색하면 url이 기존 youtube.com에서 youtube.com/results?search_query="세종대학원"로 변경됨3. https://www.youtube.com/robots.txt 을 입력하면 Disallow: /results가 있다.https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAdaHS%2FbtqMqdrDeGd%2F1UKNbafvkKYEin2Twmc2Lk%2Fimg.png  3. 검색할 키워드 입력창1. 개발자 도구 - 선택자를 클릭하고2. 검색할 키워드를 입력할 수 있는 input xpath 가져오기https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyxN7D%2FbtqMmpftKqR%2FDUfDsyeAAi0n6dAIf1trc1%2Fimg.png  4. 크롤링할 대상 결정1. 필터 아이콘을 누르면 이렇게 27종류의 필터 옵션들이 나온다.2. 필터 아이콘을 눌러도 url은 바뀌지 않는다.3. 우리는 정렬 기준 영역에 업로드 날짜를 클릭하여 최신(내림차순)된 동영상의 제목을 추출해볼 예정이다.  5. 크롤링할 데이터가 있는 태그 파악* 개발자 도구 - 선택자를 클릭하고 필터 아이콘 클릭Copy - copy Xpath : '//*[@id="container"]/ytd-toggle-button-renderer/a'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboqE4h%2FbtqMknPIbC7%2FABWTqKxIDwYX47rb1UZzTk%2Fimg.png - 업로드 날짜'//*[@id="endpoint"]' - 조회수https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdjKCf%2FbtqMgsEh0tn%2FVg7J0T2YpbXf38h5s1EAP1%2Fimg.png * 조회수 정보https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXMNw7%2FbtqMmpT0OZr%2FICBfzka55VpWfdPP2LIdx0%2Fimg.png  5. 태그 규칙 파악  크롬 브라우저 - 개발자 도구 - Copy -> Copy Xpath로 복사* name, tag, id, class 외에도 xpath로 요소를 찾을 수도 있다.*  필터 토글 버튼 : https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzxwmE%2FbtqMiZuNe9u%2F09DOL4OUXlsVWCkbzI2sm0%2Fimg.png 필터 옵션 : 두 필터 옵션은 id가 collapse-content인 요소에서 각각 4번째  태그 안에 있는 / 5번째  와, 5번째  태그 안에 있는 / 3번째  태그 안에서,  태그 형태로 존재한다.    (크리에이티브 커먼즈로 예를 들어, 4번째  인 '기능별' 필터 그룹 옵션에서 5번째  인 '크리에이티브 커먼즈' 필터 옵션이 있다.)    https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlVpRF%2FbtqMkmQRVBt%2FsUa5gK4GyFGuonubxGQE1K%2Fimg.png<jupyter_code># 조회수 정보 :  원하는 데이터들은 <ytd-video-renderer> 태그 안에 있는 
# / id가 'metadata-line'인 <div> 태그 안에 있는 
# / 1번째 <span> 태그마다 text 형태로 존재한다. 
# (<ytd-video-renderer> 태그를 고려하지 않으면 맨 위에 가끔 나타나는 
# 광고 영상의 조회수까지 콘솔에 출력되기 때문에 보기 안좋아질 것이다.) 
6. 코딩
 

중간에 0.5초씩 sleep함수를 이용해 동작마다 코드 수행을 지연시키는 이유는 웹 사이트에 모든 요소가 모두 로드 될 때 까지 기다려주기 위함이다. 이 지연 함수를 넣지 않으면 웹 사이트에 요소가 로드 되기도 전에 요소를 찾게 되어 오류가 날수도 있다.

위에서 설명한 모든 동작은 주석으로 달아 놓았다.<jupyter_output><empty_output><jupyter_text>**실제 코드** **1. 유튜브 사이트 접속***  driver.get('https://www.youtube.com')<jupyter_code># 1. 유튜브 사이트 접속

from selenium import webdriver
from time import sleep
from bs4 import BeautifulSoup

chrome_options = webdriver.ChromeOptions()

# 전체 화면으로 크롬 브라우저 실행
chrome_options.add_argument('--start-maximized')

# chrome_options=chrome_options에서 options=chrome_options로 명령어 변경 됨
driver = webdriver.Chrome('C:\chromedriver.exe', options=chrome_options)

driver.get('https://www.youtube.com')<jupyter_output><empty_output><jupyter_text>**2. 입력 창 요소 선택***  name = 'search_query'<jupyter_code># 2. 입력 창 요소 선택
search_bar = driver.find_element_by_name("search_query")<jupyter_output><empty_output><jupyter_text>**3. 입력란에 검색어 입력***  search_bar.send_keys(keyword)<jupyter_code>### 3. 입력란에 검색어 입력

# keyword = '세종대학원'
keyword = input("검색어를 입력하세요 : ")

# 입력 창에 text 입력
search_bar.send_keys(keyword)<jupyter_output>검색어를 입력하세요 : 세종대학원<jupyter_text>**4. 검색 버튼 xpath 찾기 및 클릭***  '//*[@id="search-icon-legacy"]'<jupyter_code># 4. 검색 버튼 xpath 찾기 및 클릭
driver.find_element_by_xpath('//*[@id="search-icon-legacy"]').click()
sleep(0.5)<jupyter_output><empty_output><jupyter_text>**5. 필터 토글 버튼 xpath 가져오기 & 버튼 클릭**<jupyter_code># 5. 필터 토글 xpath가져오기 & 버튼 클릭
driver.find_element_by_xpath('//*[@id="container"]/ytd-toggle-button-renderer/a').click()
sleep(0.5)<jupyter_output><empty_output><jupyter_text>**6. 업로드 날짜 클릭***  driver.find_element_by_css_selector :  css 선택자 방식*  'collapse-content > ytd-search-filter-group-renderer:nth-child(4) > ytd-search-filter-renderer:nth-of-type(2) a' :  css 방식 경로*  .click() :  클릭<jupyter_code># 6. 업로드 날짜 글자 클릭
driver.find_element_by_css_selector('#collapse-content > ytd-search-filter-group-renderer:nth-child(4) > ytd-search-filter-renderer:nth-of-type(2) a').click()
sleep(0.5)<jupyter_output><empty_output><jupyter_text>**7. 컨텐츠 추출***  driver.find_element_by_css_selector :  : css 선택자 방식*  divcontents > ytd-video-renderer.style-scope.ytd-item-section-renderer  : css 방식 경로*  .text() :  텍스트만 추출<jupyter_code># 컨텐츠 전체 영역 출력

contents = driver.find_elements_by_css_selector("div#contents > ytd-video-renderer.style-scope.ytd-item-section-renderer")

for content in contents:
    print(content.text)
# 컨텐츠 중에 제목만 나열하기

titles = content.find_elements_by_css_selector("div#meta > div#title-wrapper > h3 > a")

i = 0

for title in titles:
    print(i, ": ", title.text)
    i = i + 1
# 컨텐츠 중에 제목만 출력하기

contents = driver.find_elements_by_css_selector("div#contents > ytd-video-renderer.style-scope.ytd-item-section-renderer ")

for content in contents:
    # print(content.text)
    titles = content.find_elements_by_css_selector("div#meta > div#title-wrapper > h3 > a")

    for title in titles:
        print(i, ": ", title.text)
        i = i + 1
        
# 스크롤링 없이 한 페이지 최대 유튜브 갯수는 20개<jupyter_output><empty_output><jupyter_text>**8. 스크롤링을 통해 데이터베이스에서 컨텐츠 가져오기***  driver.execute_script("window.scrollTo(0, document.getElementById('content').scrollHeight);")  : PC별 높이 사이즈 정보를 가져옴<jupyter_code># 참고 사이트
# https://lcs1245.tistory.com/entry/Python-%EC%9B%B9-%ED%81%AC%EB%A1%A4%EB%A7%81%ED%95%98%EA%B8%B0-PART-2
# https://velog.io/@devmin/selenium-crawling-infinite-scroll-click

import time

# 연속 범위로 줘도 데이터베이스에서 가져오는게 정확하지 않음, 1번씩 할때는 정확함
# 2번 이상시에는 네트워크 및 유튜브 마음에 따라 진행됨(고로, 갯수가 딱 정확하게 들어오지 않음)
scroll_cnt = input("스크롤링을 몇 번 할까요? ")
# print(scroll_cnt)

SCROLL_PAUSE_TIME = int(input("스크롤링을 대기 시간을 몇 초로 할까요? "))

# Get scroll height
# last_height = driver.execute_script("return document.body.scrollHeight")

# 자바스크립트를 통해서 높이값을 저장하고 그 높이 * scroll_cnt 만큼 웹 페이지를 스크롤한다.
for i in scroll_cnt:
    # 스크롤을 화면 가장 아래로 내린다
    driver.execute_script("window.scrollTo(0, document.getElementById('content').scrollHeight);")
    
    time.sleep(SCROLL_PAUSE_TIME)                                               
# 제목 데이터만 title_filter 변수에 대입 => 추후 판다스 패키지를 통해 엑셀 저장

contents = driver.find_elements_by_css_selector("div#contents > ytd-video-renderer.style-scope.ytd-item-section-renderer ")

title_filter = []

for content in contents:
    # print(content.text)
    titles = content.find_elements_by_css_selector("div#meta > div#title-wrapper > h3 > a")

    for title in titles:
        title_filter.append(title.text)
        
print(title_filter)
print(len(title_filter))<jupyter_output>['TMI 캠퍼스투어 세종대학교🎓 1편을 보여드립니다! 근데 이제 투머치토커 박찬호 선수⚾에 빙의된..', '[ALLCOBI 세종대학교 위클리 프로젝트] 밸런스 게임', '[수액터스팜2021] [세종대학교영화예술학과 최종합격] "회전목마가 수없이 돌아가듯..." #세종대학교 #대진대학교 #6관왕 #김길원', '2021 댄스로맨스PROJECT.9 | 백제예대 | 세종대학원 | HOYA X KING SANG', '당신은 왜 설계를 하나요?', '[세종대학교/Sejong University] 경영대학 컨보케이션 - 경영대학 분야별 교수님 소개', '2021년 세종대학교 영화예술학과 4학년 프로젝트1 [맨 끝줄 소년, 맨 끝줄 소녀] 클라우디오 역 - 최용준 배우', '세종대학교 영화예술학과 21년도 3학년 프로젝트 맥베스:OPT 연습영상 (멜컴)', '[세종대학교/Sejong University] 경영대학 컨보케이션 - 경영대학 소개', '[세종대학교/Sejong University] 신입생과 함께하는 개강예배', '2021년 세종대학교 영화예술학과 4학년 프로젝트1 [맨 끝줄 소년, 맨 끝줄 소녀] 헤르만 역 - 이주원 배우', '[세종대학교/Sejong University] 경영대학 컨보케이션 - 개회사', "3℃. 연극영화과 대학원 석사 질문과답변 Q&A (배우 연극영화과 대학원 진학을 해야 할까요?) 졸업식 브이로그 / Master's Q&A, and graduation vlogs", '[세종대학교/Sejong University] 경영대학 컨보케이션 - 식순 안내', '[Team #트루나 작품] 세종대학교 융합예술대학원x미래교육원 실용무용 [2021-1학기 위클리 프로젝트]', '예비 샐러던트를 위한 직장과 병행 가능한 유망한 파트타임 박사과정 Top7', 'Chinese Traditional style Performance of Arirang중국 전통 스타일 버전의 아리랑 韩国民谣阿里郎中国民族风改编（강리즈,하가호,진징,소곤）4K', '6분만에 알아보는 고[...]<jupyter_text>**9.판다스 패키지로 엑셀 파일에 저장***  pd.DataFrame(title_filter)<jupyter_code># 판다스 패키지를 통해 엑셀에 저장한다.

# 판다스 패키지를 통해 엑셀로 확인

import pandas as pd

df = pd.DataFrame(title_filter)

# df

df.columns = ['제목']

df

file_name = input("파일명을 입력하세요 :")

# 유튜브_키워드_제목_크롤링결과
df.to_excel(f"./{file_name}.xlsx", index=False)<jupyter_output>파일명을 입력하세요 :유튜브_키워드_제목_크롤링결과
{'fraction_non_alphanumeric': 0.13266778927110898, 'fraction_numerical': 0.03211450565311523, 'mean_word_length': 4.614449696151249, 'pattern_counts': {'":': 2, '<': 42, '<?xml version=': 0, '>': 61, 'https://': 14, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '214791', 'license': 'MIT', 'n_tokens_mistral': 5183, 'n_tokens_neox': 6447, 'n_words': 790, 'path': '211031_youtube_filtering_playlist_crawling.ipynb', 'repo_name': 'sdw1621/sejong_uni_bigdataMBA', 'size': '8314'}