최근 오랜만에 크롤링을 할 일이 있었는데 이번엔 유튜브 비디오를 다운 로드 받는 일이었다.
간단한 서치후 발견한 pytube 라는 모듈이 정말 이 작업을 정말 편하게 해주어 이를 소개해 보고자 한다.
환경
os: ubuntu 20.04
언어 : Python 3.7.11
required modules:
pytube 11.0.1
requests-html 0.10.0
pytube & requests-html
pytube 과 requests-html은 아래 명령어로 쉽게 설치 할수 있다.
pip install pytube
pip install requests-html
pytube는 youtube stream을 다운받는 역할을 하고 requests-html은 HTML의 파싱을 쉽게 해주는 모듈이다.
예제
import http
from requests_html import HTMLSession
import pytube
from pytube.cli import on_progress
def download(url, id, save_dir="./downloads"):
yt = pytube.YouTube(url, on_progress_callback=on_progress) # youtube 오브젝스 생성, on_progess_callback은 video stream 의 chunk 가 다운로드 됐을때 마다 실행되는 함수. 여기서는 프로그래서 바를 그리는 용도
stream = yt.streams.filter(progressive=True, file_extension="mp4").order_by("resolution").desc().first()# progressive는 스트리밍 서비스의 종류. mp4 포멧의 비디오 파일만 필터링.
filepath = stream.download(save_dir) #다운로드.
if __name__=='__main__':
s = HTMLSession()
urls = ['https://youtube.com/playlist?list=PLWo1h5t1i9PHtpcwXa04EWQri_ZZeTFGY']
total=0
i=0
save_dir = './downloads'
for url in urls:
r = s.get(url) # 원하는 url에 GET request 를 보낸다.
r.html.render(sleep=0, keep_page = True, scrolldown = 10) # get 한 웹페이지를 해석하는 부분이라고 생각하면 됨
length= len(r.html.find('a#video-title'))
total+=length
for links in r.html.find('a#video-title'): #위 url 페이지에 리스팅된 제목에 해당하는 영상들의 정보를 검색
link = next(iter(links.absolute_links)) # 각 리스팅된 영상중 하나의 url을 받음
print('link:{}'.format(link))
try:
download(link,i,save_dir) # 다울로드
i+=1
print(fr' number of videos:{i}/{total}')
except http.client.IncompleteRead as e:
print('fail: {} \n'.format(link))
print(fr'total videos:{i}/{total}')
위 예제 코드는 내가 사용한 코드이다. 각 부분에 주석을 달아 놓았으니 편하게 읽어 보면 된다.
코드에서 $ r.html.find('a#video-title') $ 이 부분은 아래와 같은 페이지에서 리스팅된 제목에 해당하는 영상의 정보를 들고 가지고 잇는 html 요소를 찾아서 리턴해 주는 역할을 한다. 즉 '푸드얍 15초 공식 광고' 와 같은 제목에 해당하는 영상의 정보를 리턴해주는 메서드.
yt.streams.filter(progressive=True, file_extension="mp4").order_by("resolution").desc().first() 라인에서
order_by("resolution").desc().first() 부분의 시청가능한 영상의 화질 중 가장 높은 화질을 다운로드하겠다는 의미이다.
즉, 아래 처럼 유튜브의 화질 설정에서 설정 가능 한 가장 높은 화질 아래 예에서는 720p를 다운로드 하겠다는 의미이다.
위 코드를 돌리면 $ ./downloads $ 디렉토리 아래에 원하는 영상이 다운받아 진다.