ETH官方钱包

前往
大廳
主題

【python】 使用 pytube 會遇到的一些問題

d86123 | 2022-01-18 16:17:26 | 巴幣 2 | 人氣 2025

如果貼上全部的程式碼一個一個講,閱讀性太差了
這是我找別人資料參考時的想法
三百多行的程式,自己寫的就還好,看別人的真的催眠,一眼就想睡
不過有可能有人想看,整個程式碼可能會再發一篇就是了

所以我把我遇到的問題貼一些上來
希望可以幫助後面也想用pytube這個模組的同好解決一些找不到的問題
不過我已經完成了程式,無法(懶得)再現問題點,可能還是會有些遺漏

2022/02/07
錯誤訊息
NoneType' object has no attribute 'span'
沒意外又是YouTube改版
解決辦法




YouTube 2022/01/20 改版,pytube 抓不到影音資料
錯誤訊息如下
During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "d:\ytdownload\test.py", line 12, in <module>
    yt.streams.all()
  File "C:\Users\teacher\AppData\Local\Programs\Python\Python310\lib\site-packages\pytube\__main__.py", line 292, in streams
    return StreamQuery(self.fmt_streams)
  File "C:\Users\teacher\AppData\Local\Programs\Python\Python310\lib\site-packages\pytube\__main__.py", line 184, in fmt_streams
    extract.apply_signature(stream_manifest, self.vid_info, self.js)
  File "C:\Users\teacher\AppData\Local\Programs\Python\Python310\lib\site-packages\pytube\extract.py", line 409, in apply_signature
    cipher = Cipher(js=js)
  File "C:\Users\teacher\AppData\Local\Programs\Python\Python310\lib\site-packages\pytube\cipher.py", line 33, in __init__
    raise RegexMatchError(
pytube.exceptions.RegexMatchError: __init__: could not find match for ^\w+\W

cipher.py 中的 ^\w+\W 有問題
有人已經提出問題,並且有人解決
找到 cipher.py 將原本的 ^\w+\W
改成 ^\$*\w+\W 存檔解決


caption 抓字幕問題
使用模組時還是要確認型態,不然蝦測會浪費很多時間
下圖例子 caption 出來的型態是<class 'pytube.query.CaptionQuery'>
到pytube.io 看他原始碼
往上看他的caption.py
有name跟code可以用,name 是字幕語言,code 是語系代碼
人看的是 name,程式看的是 code,怎麼利用看個人



caption download出錯
比如程式碼如下
yt = pytube.YouTube("網址")
yt.captions["zh"].download()
會出現錯誤KeyError: 'start',具體錯誤我懶得還原了,好像是他模組內 xml轉 srt的方法有錯(或是YOUTUBE有更新)
解決方法我直接抄網路答案拉
找到 caption.py覆蓋過去搞定


分辨下載影片有沒有聲音
網路上教學都是使用subprocess,Popen控制臺檢查影片有沒有聲音
不過 pytube中已經有檢查下載的影片有沒有聲音的方法
或是檢查是不是漸進式下載也可以


下載影片時整個程式無回應的問題
按下載按鈕時,整個程式會卡住,直到下載完成時才會釋放資源
這樣不好,因為我還有 text的 box要顯示下載進度,如果下載時就卡在那
那使用體驗很差,這時候就要使用多執行緒
使用 threading模組
原理每一行 threading.Thread(target = 啟動函數, args = (啟動函式的輸入變數)) 使用一個執行緒
但是在下載按鈕 command的地方不能直接接執行緒啟動
所以要再寫一個函式,從函式中啟動,如果發現還是無法改善
嘗試把 tkinter設定的 StringVar變數都再丟進全域變數中
讓下載的函式都調用全域變數就好
拿我的程式來說

downloadbutton = Button(window, text = "下載影片", width = 15, command = threadstart)


def subthreadstart():
    global caption, captionbox
    downloadbutton["state"] = DISABLED
    analysisbutton["state"] = DISABLED
    filepathbutton["state"] = DISABLED
    downloadsubbutton["state"] = DISABLED
    caption = captionbox.get()
    threading.Thread(target = downloadYTsub).start()

通過 threadstart去啟動下載函式
雖然略顯麻煩但可以在這個函式中插入按鈕狀態設定什麼的,一些全域變數的設定也可以在這裡
當作一個啟動階段

創作回應

更多創作