Skip to content

[Python] 使用 pytube 套件下載 Youtube 影片

Last Updated on 2021-05-07 by Clay

現代人的各種電子娛樂很大程度上都離不開 YouTube,不論是追劇、學習、聽音樂 …… 說 YouTube 是現代人最重要的網站也不為過

有時候,我們會想要從 YouTube 上下載影片或是音樂。當然,這件事情本身很有可能觸犯智慧財產權,所以今天,我會紀錄如何透過 Python 中的 pytube 套件來做到『下載』這個動作,不過包含我本人在內,我們的範例程式僅限於教學與學術研究、絕非商業用途。

當然,下載後的影片也要於一定時間內刪除才行。

舉個非商業用途的下載例子:或許學校老師們會想要藉由 YouTube 影片向班上同學們授課,但是總難免會碰上網路訊號不好的時候,而在課堂上等待影片的播放難免浪費時間。

那麼,除了使用網路上各種 YouTube 下載網頁之外,或許也可以考慮使用 Python 來完成下載影片的工作。當然如果你是撰寫程式來下載,那麼你當然可以批量一口氣下載多部影片

正如前述,本文介紹的是如何使用 Python 中著名的 pytube 套件。更詳細的資訊可以去開發者的 Github 看看: https://github.com/nficano/pytube

本篇心得教學分成兩階段:

  • 下載影片檔
  • (Optional)使用 moviepy 套件將 mp4 轉成 mp3

使用 pytube 下載 YouTube 的影片

首先,我們需要先安裝 pytube 套件:

pip3 install pytube

在我使用的現在,pytube 的最新版本是 9.5.3。但在我之前嘗試的時候,我是失敗的:我沒辦法順利地使用 9.5.2 的 pytube 下載 YouTube 網站上的影音檔。

2021/05/07 更新距離撰寫這篇文章已經過去了很長一段時間,為了因應 YouTube 網站的改版,pytube 套件自然也迭代了許多新的版本,本次文章更新最重要的便是修正了自定義的『下載進度條』相關的程式碼。目前 pytube 最新版本為 10.7.2

在使用這個套件前,有個簡單的觀念要說明:YouTube 對於這種使用爬蟲技術來下載影片的方法一直都在換著花樣阻擋,必須要隨時更新我們使用的套件版本才行。

以下我們拿一個影片來示範: https://www.youtube.com/watch?v=JwBXgJeqeOs

以上這是個由日本 Falcom 公司所製作的遊戲《空之軌跡 3rd》當中的 op(開場曲),而這裡我們透過 pytube 套件來下載這部影片。

# -*- coding: utf-8 -*-
from pytube import YouTube


url = 'https://www.youtube.com/watch?v=JwBXgJeqeOs'
YouTube(url).streams.first().download()



這樣稍等一會兒,我們就會看到影片存放在我們當前資料夾底下了。


(2021/05/07 更新)如果遇到以下報錯(比方說 MacOS):

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:847)>

則可以在程式開頭加上:

import ssl
ssl._create_default_https_context = ssl._create_unverified_context



比較詳細的解釋紀錄在這篇:[已解決] urllib.error.URLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed


進度條

但這時候我們一定會很疑惑,咦?沒有任何進度條出現欸?這樣如果需要一次下載較大的影片,不就不知道現在下載進度了嗎?

這倒不用擔心,在 pytube 的 YouTube 類別中,存在著 on_progress_callback callback 參數,可以讓我們撰寫自己的進度條。

就像我這樣的配置:(已經不再適用)

# -*- coding: utf-8 -*-
from pytube import YouTube


def progress(stream, chunk, file_handle, bytes_remaining):
    contentSize = video.filesize
    size = contentSize - bytes_remaining

    print('\r' + '[Download progress]:[%s%s]%.2f%%;' % (
    '█' * int(size*20/contentSize), ' '*(20-int(size*20/contentSize)), float(size/contentSize*100)), end='')


url = 'https://www.youtube.com/watch?v=JwBXgJeqeOs'
yt = YouTube(url, on_progress_callback=progress)
video = yt.streams.first()
video.download()



(2021/05/07 更新)目前自定義的進度條程式規格應如下:

# coding: utf-8
from pytube import YouTube


def progress(chunk, file_handle, bytes_remaining):
    contentSize = video.filesize
    size = contentSize - bytes_remaining

    print('\r' + '[Download progress]:[%s%s]%.2f%%;' % (
    '█' * int(size*20/contentSize), ' '*(20-int(size*20/contentSize)), float(size/contentSize*100)), end='')



if __name__ == "__main__":
    # Init
    url = 'https://www.youtube.com/watch?v=JwBXgJeqeOs'
    yt = YouTube(url, on_progress_callback=progress)
    video = yt.streams.first()
    
    # file_size
    file_size = video.filesize

    # Download
    video.download()



Output:


使用 moviepy 轉換 MP4 成 MP3

將影片檔(mp4)轉成音訊檔(mp3)的程式跟套件有很多,在這裡我直接選擇了 moviepy 套件,因為其程式碼既短又清晰。

首先,我們同樣需要下載 moviepy 套件。

sudo pip3 install moviepy

下載好之後,我們來將剛才下載的檔案轉換成 test.mp3(名稱可以自己取)。

# -*- coding: utf-8 -*-
from moviepy.editor import *

video = VideoFileClip('Sora no Kiseki the 3rd Evolution [BGM RIP] - Cry for your Eternity.mp4')
video.audio.write_audiofile('test.mp3')



Output:

MoviePy - Writing audio in test.mp3
MoviePy - Done.

這樣一來,我們的轉換就完成了。


References


Read More

Leave a Reply