defset_selenium_option():globaloptions# Settingos.chdir('C:\\\\Users\\\\bunga\\\\Desktop\\\\python\\\\youtube')options=webdriver.ChromeOptions()user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'# Option Controloptions.add_argument('user-agent='+user_agent)options.add_argument('headless')# 창을 띄우지 않습니다options.add_argument('window-size=1920x1080')options.add_argument('disable-gpu')options.add_argument('disable-infobars')options.add_argument('--disable-extensions')options.add_argument('--mute-audio')options.add_argument('--blink-settings=imagesEnabled=false')# 브라우저에서 이미지 로딩을 하지 않습니다.options.add_argument('incognito')# 시크릿모드의 브라우저가 실행됩니다.options.add_argument('--start-maximized')returnoptions
Step 3. Youtube 영상 리스트 및 구독자수 크롤링
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
defscrollToEnd():prev_height=driver.execute_script("return document.documentElement.scrollHeight")# 웹페이지 맨 아래까지 무한 스크롤whileTrue:# 스크롤을 화면 가장 아래로 내린다element=driver.find_element(By.TAG_NAME,'body')element.send_keys(Keys.END)# 페이지 로딩 대기time.sleep(2)# 현재 문서 높이를 가져와서 저장curr_height=driver.execute_script("return document.documentElement.scrollHeight")if(curr_height==prev_height):breakelse:prev_height=driver.execute_script("return document.documentElement.scrollHeight")
defyoutube_video_list_subscriber(channel_name,selenium_option):# Channel URLchannel_url='https://www.youtube.com/'+channel_name+'/videos'# 페이지 탐색globaldriverdriver=webdriver.Chrome('chromedriver.exe',options=selenium_option)driver.get(channel_url)driver.switch_to.window(driver.window_handles[-1])scrollToEnd()# 페이지 정보 추출html=driver.page_sourcesoup=BeautifulSoup(html,'lxml')# Driver 닫기driver.close()# 영상 링크 추출sample_list=soup.find_all('a',class_='yt-simple-endpoint focus-on-expand style-scope ytd-rich-grid-media')video_link_list=[]forsampleinsample_list:video_link=sample.get_attribute_list('href')[0]video_link_list.append('https://youtube.com'+video_link)# 구독자 수 추출subscriber=soup.find_all(id='subscriber-count')[0].textscale=subscriber[-2:-1]ifscale=='만':subscriber=re.sub(r'[^0-9.]','',subscriber)subscriber=np.float_(subscriber)*10000elifscale=='천':subscriber=re.sub(r'[^0-9.]','',subscriber)subscriber=np.float_(subscriber)*1000else:subscriber=subscriber[:-1]subscriber=int(np.round(subscriber))returnvideo_link_list,subscriber
defprevious_csv(csv_name):# 최근 csv 불러오기 (없으면 빈 데이터프레임 만들기)try:latest_date=get_latest_date(csv_name)latest_filename=csv_name+'_'+latest_date+'.csv'df=pd.read_csv('result/'+latest_filename)except:print('이전 파일이 없습니다.')df_columns=['crawl_datetime','channel','subscriber','title','length','views','publish_date','video_url','thumbnail_url','keywords','description']df=pd.DataFrame(columns=df_columns)returndf
Step 6. Pytube 활용하기
제목, 영상길이, 게시자, 게시날짜, 조회수, 키워드, 설명, 썸네일 등의 정보를 간단하게 얻을 수 있다. pytube 중에서 Channel이라는 class가 있는데, 2023년 1월 9일 기준으로는 주요 함수(ex. 업로드 영상들의 URL 반환하는 함수)들에서 empty list만 리턴하는 문제가 있다. 해당 문제가 해결이 된다면, Step3. Youtube 영상 리스트 크롤링 과정이 단순화될 수 있다.
defupdate_video_info(df,video_link_list,subscriber,verbose=True):print('--------------------------------------------------------------------------')today_datetime=datetime.today()foridx,urlinenumerate(video_link_list):# 유튜브 정보 불러오기youtube=YouTube(url)# 전체 영상 수 ifidx==0:print('{} / 영상: {}개'.format(youtube.author,len(video_link_list)))# 개별 영상 정보new=[today_datetime,youtube.author,subscriber,youtube.title,youtube.length,youtube.views,youtube.publish_date.date(),youtube.watch_url,youtube.thumbnail_url,youtube.keywords,youtube.description]df_new=pd.DataFrame([new],index=[idx],columns=df.columns)df=pd.concat([df,df_new])# 진행상황 체크ifverboseand(idx+1)%10==0:print('{}번째 영상정보 정리 완료!'.format(idx+1))print('\n')returndf
# example URLurl='https://www.youtube.com/watch?v=Ktw22y8VFHs'youtube=YouTube(url)# All argumentsyoutube.age_restrictedyoutube.allow_oauth_cacheyoutube.authoryoutube.bypass_age_gateyoutube.caption_tracksyoutube.captionsyoutube.channel_idyoutube.channel_urlyoutube.check_availabilityyoutube.descriptionyoutube.embed_htmlyoutube.embed_urlyoutube.fmt_streamsyoutube.from_idyoutube.initial_datayoutube.jsyoutube.js_urlyoutube.keywordsyoutube.lengthyoutube.metadatayoutube.publish_dateyoutube.ratingyoutube.register_on_complete_callbackyoutube.register_on_progress_callbackyoutube.stream_monostateyoutube.streaming_datayoutube.streamsyoutube.thumbnail_urlyoutube.titleyoutube.use_oauthyoutube.vid_infoyoutube.video_idyoutube.viewsyoutube.watch_htmlyoutube.watch_url
Step 7. 이전 csv 지우기
1
2
3
4
defdelete_previous_csv(csv_name,latest_date):iflatest_date!='X':# 이전 파일이 없는 경우latest_filename=csv_name+'_'+latest_date+'.csv'send2trash.send2trash('result/'+latest_filename)