YouTube影片下載(六):改用PyTube程式庫解決執行錯誤

最近透過PyTube3程式庫下載YouTube影片,會出現KeyError: ‘assets’錯誤:

KeyError: 'assets'錯誤

把PyTube3更新到目前最新的3.7.4.1版,仍舊會出現相同錯誤。到pypi.org網站搜尋pytube關鍵字,可找到21個相關專案,其中包含10月31日才更新的pytube 9.7.0版。另外還可以看到一個新的下載YouTube影片的專案程式“mhyt”,還有PyTubeX和PyTube4。

到pypi.org網站搜尋pytube關鍵字

所以,我在CLI視窗輸入底下的命令刪除之前安裝的PyTube3

pip uninstall pytube3 -y

然後分別安裝PyTubeX和PyTube4測試,結果下載影片時出現和PyTube3相同的錯誤訊息。

後來執行安裝PyTube

pip install pytube

在Python 3解譯器測試下載影片沒問題:

在Python 3解譯器測試下載影片

執行書本裡的範例程式tube.py,下載影片也沒問題。

執行書本裡的範例程式tube.py

Posts created 470

19 thoughts on “YouTube影片下載(六):改用PyTube程式庫解決執行錯誤

  1. 老師好,最近我在實作此單元時,發生了以下的錯誤
    Traceback (most recent call last):
    File “C:\\Cooding\python\youtube.py”, line 163, in
    main()
    File “C:\Cooding\python\youtube.py”, line 159, in main
    download_media(args)
    File “C:\Cooding\python\youtube.py”, line 51, in download_media
    filter = yt.streams.filter
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\__main__.py”, line 292, in streams
    return StreamQuery(self.fmt_streams)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\__main__.py”, line 177, in fmt_streams
    extract.apply_signature(stream_manifest, self.vid_info, self.js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\extract.py”, line 409, in apply_signature
    cipher = Cipher(js=js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\cipher.py”, line 43, in __init__
    self.throttling_plan = get_throttling_plan(js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\cipher.py”, line 387, in get_throttling_plan
    raw_code = get_throttling_function_code(js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\cipher.py”, line 301, in get_throttling_function_code
    code_lines_list = find_object_from_startpoint(js, match.span()[1]).split(‘\n’)
    AttributeError: ‘NoneType’ object has no attribute ‘span’
    請問是什麼樣的問題呢(因為我才國一看不太懂),以及要如何解決呢?

    1. 根據pytube的這個錯誤回報頁面,網友提到,要把cipher.py裡面的這個列表元素:

      function_patterns = [
        # https://github.com/ytdl-org/youtube-dl/issues/29326#issuecomment-865985377
        # a.C&&(b=a.get("n"))&&(b=Dea(b),a.set("n",b))}};
        # In above case, `Dea` is the relevant function name
        r'a\.[A-Z]&&\(b=a\.get\("n"\)\)&&\(b=([^(]+)\(b\)',
      ]。
      

      改成:

      function_patterns = [
        # https://github.com/ytdl-org/youtube-dl/issues/29326#issuecomment-865985377
        # a.C&&(b=a.get("n"))&&(b=Dea(b),a.set("n",b))}};
        # In above case, `Dea` is the relevant function name
        r'([A-Za-z]{3})=function\(a\){var b=a\.split\(""\)\,',
      ]
      

      剛剛測試OK。

      cipher.py檔案的位置,從錯誤訊息可以看出,以你的電腦為例:

      C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\cipher.py

  2. 我嘗試修改了程式,在執行後又出現了以下錯誤
    Traceback (most recent call last):
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\__main__.py”, line 177, in fmt_streams
    extract.apply_signature(stream_manifest, self.vid_info, self.js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\extract.py”, line 409, in apply_signature
    cipher = Cipher(js=js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\cipher.py”, line 29, in __init__
    self.transform_plan: List[str] = get_transform_plan(js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\cipher.py”, line 189, in get_transform_plan
    return regex_search(pattern, js, group=1).split(“;”)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\helpers.py”, line 129, in regex_search
    raise RegexMatchError(caller=”regex_search”, pattern=pattern)
    pytube.exceptions.RegexMatchError: regex_search: could not find match for sha=function\(\w\){[a-z=\.\(\”\)]*;(.*);(?:.+)}

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File “C:\Cooding\python\youtube.py”, line 161, in
    main()
    File “C:\Cooding\python\youtube.py”, line 158, in main
    download_media(args)
    File “C:\Cooding\python\youtube.py”, line 51, in download_media
    filter = yt.streams.filter
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\__main__.py”, line 292, in streams
    return StreamQuery(self.fmt_streams)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\__main__.py”, line 184, in fmt_streams
    extract.apply_signature(stream_manifest, self.vid_info, self.js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\extract.py”, line 409, in apply_signature
    cipher = Cipher(js=js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\cipher.py”, line 29, in __init__
    self.transform_plan: List[str] = get_transform_plan(js)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\cipher.py”, line 189, in get_transform_plan
    return regex_search(pattern, js, group=1).split(“;”)
    File “C:\Users\User\AppData\Roaming\Python\Python310\site-packages\pytube\helpers.py”, line 129, in regex_search
    raise RegexMatchError(caller=”regex_search”, pattern=pattern)
    pytube.exceptions.RegexMatchError: regex_search: could not find match for sha=function\(\w\){[a-z=\.\(\”\)]*;(.*);(?:.+)}
    另外,我使用VScode的偵錯系統,還發現另一個錯誤
    發生例外狀況: SystemExit
    2
    File “C:\Cooding\python\youtube.py”, line 157, in main
    args = parser.parse_args()
    File “C:\Cooding\python\youtube.py”, line 161, in
    main()

  3. 老師好,我本來安裝的是Pytube 11.0.1,透過pip3更新好像沒辦法順利更新,索性先移除再重新安裝一次後,版本就成了11.0.2,接著用老師提供的範例下載仍然出現錯誤,後來又照著老師提供關於cipher.py內文的建議修改後就正常了,不過影片網址的參數似乎必須放在雙引號內才能正常識別(我的平台是Mac),有個問題請教就是下載進度的數字得過了幾秒後才會更新一次,跟想像中的即時更新不太一樣請問是正常的嗎?感謝

  4. 老師你好,不好意思,我是使用python3 執行完pip install pytube後還是無法正常下載影片,請問問題是出在哪裡
    ——————————-CODE—————————————-
    from pytube import YouTube

    yt = YouTube(‘https://www.youtube.com/watch?v=gvDPqvOYz7c’)
    print(“開始下載影片”)
    yt.streams.first().download()

    print(“影片下載完成”)

    ———————————Error Message——————————————
    HTTPError Traceback (most recent call last)
    in
    1 from pytube import YouTube
    2
    —-> 3 yt = YouTube(‘https://www.youtube.com/watch?v=gvDPqvOYz7c’)
    4 print(“開始下載影片”)
    5 yt.streams.get_highest_resolution().download(‘./videos’)

    ~\Anaconda3\lib\site-packages\pytube\__main__.py in __init__(self, url, defer_prefetch_init, on_progress_callback, on_complete_callback, proxies)
    89 self.allow_oauth_cache = allow_oauth_cache

    1. 你的Python執行環境是Anaconda3,建議改用python.org下載的Python 3試試。我剛剛在Android手機上,把pytube更新到最新版本,測試下載同樣的影片沒問題。

  5. 老師你好,不好意思,我是使用python3 執行完pip install pytube後還是無法正常下載影片,
    pip install pytube upgrade,請問問題是出在哪裡?
    ——————————-CODE—————————————-
    from pytube import YouTube

    yt = YouTube(‘https://www.youtube.com/watch?v=gvDPqvOYz7c’)
    print(“開始下載影片”)
    yt.streams.first().download()
    ———————————Error Message——————————————
    Traceback (most recent call last):

    File “C:\Users\09379\.spyder-py3\youtube\untitled0.py”, line 10, in
    yt = YouTube(‘https://www.youtube.com/watch?v=gvDPqvOYz7c’)

    File “C:\Phython\lib\site-packages\pytube\__main__.py”, line 91, in __init__
    self.prefetch()

    File “C:\Phython\lib\site-packages\pytube\__main__.py”, line 181, in prefetch
    self.vid_info_raw = request.get(self.vid_info_url)

    File “C:\Phython\lib\site-packages\pytube\request.py”, line 36, in get
    return _execute_request(url).read().decode(“utf-8”)

    File “C:\Phython\lib\site-packages\pytube\request.py”, line 24, in _execute_request
    return urlopen(request) # nosec

    File “C:\Phython\lib\urllib\request.py”, line 214, in urlopen
    return opener.open(url, data, timeout)

    File “C:\Phython\lib\urllib\request.py”, line 523, in open
    response = meth(req, response)

    File “C:\Phython\lib\urllib\request.py”, line 632, in http_response
    response = self.parent.error(

    File “C:\Phython\lib\urllib\request.py”, line 555, in error
    result = self._call_chain(*args)

    File “C:\Phython\lib\urllib\request.py”, line 494, in _call_chain
    result = func(*args)

    File “C:\Phython\lib\urllib\request.py”, line 747, in http_error_302
    return self.parent.open(new, timeout=req.timeout)

    File “C:\Phython\lib\urllib\request.py”, line 523, in open
    response = meth(req, response)

    File “C:\Phython\lib\urllib\request.py”, line 632, in http_response
    response = self.parent.error(

    File “C:\Phython\lib\urllib\request.py”, line 561, in error
    return self._call_chain(*args)

    File “C:\Phython\lib\urllib\request.py”, line 494, in _call_chain
    result = func(*args)

    File “C:\Phython\lib\urllib\request.py”, line 641, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)

    HTTPError: Gone

    print(“影片下載完成”)

  6. 老師你好,不好意思,我是使用python3 執行完pip install pytube變成這樣
    pip install pytube
    File “”, line 1
    pip install pytube
    ^^^^^^^
    SyntaxError: invalid syntax

  7. >>> yt.streams.frist().download()
    Traceback (most recent call last):
    File “/home/vito0319tw/anaconda3/lib/python3.10/site-packages/pytube/__main__.py”, line 181, in fmt_streams
    extract.apply_signature(stream_manifest, self.vid_info, self.js)
    File “/home/vito0319tw/anaconda3/lib/python3.10/site-packages/pytube/extract.py”, line 409, in apply_signature
    cipher = Cipher(js=js)
    File “/home/vito0319tw/anaconda3/lib/python3.10/site-packages/pytube/cipher.py”, line 37, in __init__
    self.transform_map = get_transform_map(js, var)
    File “/home/vito0319tw/anaconda3/lib/python3.10/site-packages/pytube/cipher.py”, line 245, in get_transform_map
    transform_object = get_transform_object(js, var)
    File “/home/vito0319tw/anaconda3/lib/python3.10/site-packages/pytube/cipher.py”, line 227, in get_transform_object
    raise RegexMatchError(caller=”get_transform_object”, pattern=pattern)
    pytube.exceptions.RegexMatchError: get_transform_object: could not find match for var for={(.*?)};

    老師您好,在下載時一直出現這問題,怎麼辦?

    1. 根據stackoverflow.com的這篇貼文,請修改cipher.py檔案裡的get_transform_object()函式,改成:

      def get_transform_object(js: str, var: str) -> List[str]:
          pattern = r"var %s={(.*?)};" % re.escape(var)
          logger. Debug("getting transform object")
          regex = re.compile(pattern, flags=re.DOTALL)
          transform_match = regex.search(js)
          
          if not transform_match:
              # i commented out the line raising the error
              # raise RegexMatchError(caller="get_transform_object", pattern=pattern)
              logger. Error(f"No match found for pattern: {pattern}")
              return []  # Return an empty list if no match is found
      
          return transform_match.group(1).replace("\n", " ").split(", ")
      

      根據你的錯誤訊息,這個檔案在你的電腦上的路徑是:/home/vito0319tw/anaconda3/lib/python3.10/site-packages/pytube/cipher.py

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top