這篇文章會介紹使用 Python 的 pytube 第三方函式庫,輸入 Youtube 網址後就會自動下載為影片檔 mp4,單純下載為聲音檔 mp3,甚至可以進一步下載有字幕影片的字幕,儲存為 srt 或 txt,最後還會讀取 Youtube 清單內容,並將清單裡的所有影片下載為 mp4。。
本篇使用的 Python 版本為 3.7.12,所有範例可使用 Google Colab 實作,不用安裝任何軟體 ( 參考:使用 Google Colab )
輸入下列指令,安裝 pytube ( 根據個人環境使用 pip、pip3 )
!pip install pytube
參考「pytube - YouTube Object」說明,使用 pytube 讀取 Youtube 網址後,就能取得關於該影片的各種資訊,下方的例子會取出標題、作者、作者頻道網址、影片縮圖網址、影片長度、觀看次數等資訊。
from pytube import YouTube
yt = YouTube('https://www.youtube.com/watch?v=R93ce4FZGbc') # baby shark 的音樂
print(yt.title) # 影片標題
print(yt.length) # 影片長度 ( 秒 )
print(yt.author) # 影片作者
print(yt.channel_url) # 影片作者頻道網址
print(yt.thumbnail_url) # 影片縮圖網址
print(yt.views) # 影片觀看數
參考「pytube - StreamQuery Object」說明,可以使用 get_highest_resolution() 方法,下載最高畫質的影片。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # 使用 Colab 要換路徑使用
from pytube import YouTube
yt = YouTube('https://www.youtube.com/watch?v=R93ce4FZGbc')
print('download...')
yt.streams.filter().get_highest_resolution().download(filename='baby_shart.mp4')
# 下載最高畫質影片,如果沒有設定 filename,則以原本影片的 title 作為檔名
print('ok!')
如果要指定下載影片的畫質,可以透過 get_by_resolution() 方法,填入像是 720p、480p、360p、240p 等標準影像解析度格式,就能下載對應的畫質 ( 注意,畫質會必須取決於該影片實際大小是否支援 )
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # 使用 Colab 要換路徑使用
from pytube import YouTube
yt = YouTube('https://www.youtube.com/watch?v=R93ce4FZGbc')
print('download...')
yt.streams.filter().get_by_resolution('360p').download(filename='oxxostudio_360p.mp4')
# 下載 480p 的影片畫質
print('ok!')
如果想知道影片支援哪些畫質,可印出 streams.all() 來查看。
from pytube import YouTube
yt = YouTube('https://www.youtube.com/watch?v=R93ce4FZGbc')
print(yt.streams.all())
透過宣告 yt 時的參數 on_progress_callback,可以回傳目前下載影片的進度 ( 可顯示下載進度 )。
from pytube import YouTube
def onProgress(stream, chunk, remains):
total = stream.filesize # 取得完整尺寸
percent = (total-remains) / total * 100 # 減去剩餘尺寸 ( 剩餘尺寸會抓取存取的檔案大小 )
print(f'下載中… {percent:05.2f}', end='\r') # 顯示進度,\r 表示不換行,在同一行更新
print('download...')
yt = YouTube('https://www.youtube.com/watch?v=R93ce4FZGbc', on_progress_callback=onProgress)
yt.streams.filter().get_highest_resolution().download(filename='oxxostudio.mp4')
# on_progress_callback 參數等於 onProgress 函式
print()
print('ok!')
使用 get_audio_only() 方法,能單獨取出 Youtube 的音軌儲存為 mp3 檔案 ( 預設為 mp4,存檔時改檔名為 mp3 就會變成 mp3 )。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # 使用 Colab 要換路徑使用
from pytube import YouTube
yt = YouTube('https://www.youtube.com/watch?v=R93ce4FZGbc')
print('download...')
yt.streams.filter().get_audio_only().download(filename='oxxostudio.mp3')
# 儲存為 mp3
print('ok!')
使用 yt.captions 方法,可以取得該 Youtube 影片全部的字幕 ( 如果是 auto 自動產生,字幕語系前方會出現 a. 標示 ),取得字幕後,透過 xml_captions 就能將指定語系的字幕轉換成 xml 檔案。
由於 pytube 內建的 generate_srt_captions() 方法會發生 KeyError: 'start' 錯誤,因此直接使用 BeautifulSoup 套件讀取 xml 的內容,再透過數學計算和字串格式化的方法,轉換成字幕檔案格式,最後輸出成為 srt 或 txt。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # 使用 Colab 要換路徑使用
from pytube import YouTube
from bs4 import BeautifulSoup
yt = YouTube('https://www.youtube.com/watch?v=R93ce4FZGbc')
print(yt.captions) # 取得所有語系
caption = yt.captions.get_by_language_code('en') # 取得英文語系
xml = caption.xml_captions # 將語系轉換成 xml
#print(xml)
def xml2srt(text):
soup = BeautifulSoup(text) # 使用 BeautifulSoup 轉換 xml
ps = soup.findAll('p') # 取出所有 p tag 內容
output = '' # 輸出的內容
num = 0 # 每段字幕編號
for i, p in enumerate(ps):
try:
a = p['a'] # 如果是自動字幕,濾掉有 a 屬性的 p tag
except:
try:
num = num + 1 # 每段字幕編號加 1
text = p.text # 取出每段文字
t = int(p['t']) # 開始時間
d = int(p['d']) # 持續時間
h, tm = divmod(t,(60*60*1000)) # 轉換取得小時、剩下的毫秒數
m, ts = divmod(tm,(60*1000)) # 轉換取得分鐘、剩下的毫秒數
s, ms = divmod(ts,1000) # 轉換取得秒數、毫秒
t2 = t+d # 根據持續時間,計算結束時間
if t2 > int(ps[i+1]['t']): t2 = int(ps[i+1]['t']) # 如果時間算出來比下一段長,採用下一段的時間
h2, tm = divmod(t2,(60*60*1000)) # 轉換取得小時、剩下的毫秒數
m2, ts = divmod(tm,(60*1000)) # 轉換取得分鐘、剩下的毫秒數
s2, ms2 = divmod(ts,1000) # 轉換取得秒數、毫秒
output = output + str(num) + '\n' # 產生輸出的檔案,\n 表示換行
output = output + f'{h:02d}:{m:02d}:{s:02d},{ms:03d} --> {h2:02d}:{m2:02d}:{s2:02d},{ms2:03d}' + '\n'
output = output + text + '\n'
output = output + '\n'
except:
pass
return output
#print(xml2srt(xml))
with open('oxxostudio.srt','w') as f1:
f1.write(xml2srt(xml)) # 儲存為 srt
print('ok!')
參考「pytube - Using Playlists」說明,使用 pytube 讀取 Youtube 清單網址後,就能將該影片清單的所有影片網址,輸出成為串列。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # 使用 Colab 要換路徑使用
from pytube import Playlist
playlist = Playlist('https://www.youtube.com/watch?v=mOPRaLPh-YU&list=PL9ACDjBMkp9wViVmgpYweGkNqh62pHspF')
# 讀取影片清單
print(playlist.video_urls) # 印出清單結果
'''
['https://www.youtube.com/watch?v=mOPRaLPh-YU',
'https://www.youtube.com/watch?v=wARhTJH1fJI',
'https://www.youtube.com/watch?v=WLjePGUCRqc']
'''
讀取到影片清單中所有影片網址後,透過 for 迴圈,就能將所有影片下載為 mp4。
import os
os.chdir('/content/drive/MyDrive/Colab Notebooks') # 使用 Colab 要換路徑使用
from pytube import Playlist, YouTube
playlist = Playlist('https://www.youtube.com/watch?v=mOPRaLPh-YU&list=PL9ACDjBMkp9wViVmgpYweGkNqh62pHspF')
print('download...')
for i in playlist.video_urls:
print(i)
yt = YouTube(i) # 讀取影片
yt.streams.filter().get_highest_resolution().download() # 下載為最高畫質影片
print('ok!')
大家好,我是 OXXO,是個即將邁入中年的斜槓青年,我已經寫了超過 400 篇 Python 的教學,有興趣可以參考下方連結呦~ ^_^