【问题标题】:Every time I try to download Official videos from PYTUBE it shows this error每次我尝试从 PYTUBE 下载官方视频时都会显示此错误
【发布时间】:2020-06-12 17:16:11
【问题描述】:

这是我尝试下载任何官方视频但使用某些在线下载应用程序下载相同视频时总是遇到的错误。

  KeyError    Traceback (most recent call last)
~\anaconda3\lib\site-packages\pytube\extract.py in apply_descrambler(stream_data, key)
--> 297                 for format_item in formats
~\anaconda3\lib\site-packages\pytube\extract.py in <listcomp>(.0)
    296                 }
--> 297                 for format_item in formats
    298             ]
KeyError: 'url'

During handling of the above exception, another exception occurred:

KeyError      Traceback (most recent call last)
<ipython-input-1-796467b30bec> in <module>
      7 import cv2
      8 
----> 9 video = YouTube('https://www.youtube.com/watch?v=tDq3fNew1rU')
~\anaconda3\lib\site-packages\pytube\__main__.py in __init__(self, url, defer_prefetch_init, on_progress_callback, on_complete_callback, proxies)
     90         if not defer_prefetch_init:
     91             self.prefetch()
---> 92             self.descramble()
     94     def descramble(self) -> None:
~\anaconda3\lib\site-packages\pytube\__main__.py in descramble(self)
    130             if not self.age_restricted and fmt in self.vid_info:
    131                 apply_descrambler(self.vid_info, fmt)
--> 132             apply_descrambler(self.player_config_args, fmt)
    134             if not self.js:

~\anaconda3\lib\site-packages\pytube\extract.py in apply_descrambler(stream_data, key)
    299         except KeyError:
    300             cipher_url = [
--> 301                 parse_qs(formats[i]["cipher"]) for i, data in enumerate(formats)
    302             ]
    303             stream_data[key] = [
~\anaconda3\lib\site-packages\pytube\extract.py in <listcomp>(.0)
    299         except KeyError:
    300             cipher_url = [
--> 301                 parse_qs(formats[i]["cipher"]) for i, data in enumerate(formats)
    302             ]
    303             stream_data[key] = [

KeyError: 'cipher'

谁能帮我解决这个错误

【问题讨论】:

  • 您可以添加您正在使用的代码示例吗?
  • from pytube import YouTube import os video = YouTube('https://www.youtube.com/watch?v=epwpvDCRhzw&amp;t=1s') print(video.title) print(video.thumbnail_url) video.streams.filter(adaptive = True).all() itag = int(input("Enter an itag here: ")) video.streams.get_by_itag(itag).download('C:/Users/test/')

标签: python pytube


【解决方案1】:

我也遇到了同样的问题。我通过这样做解决了它:

  1. 转到安装了pytubesite-packages/pytub/extract.py
  2. 找线:parse_qs(formats[i]["cipher"]) for i, data in enumerate(formats)
  3. ["cipher"] 替换为["signatureCipher"]
  4. 完成。

来源here

【讨论】:

  • 我试过但没有成功同样的错误与“signatureCipher”而不是“cipher”
【解决方案2】:
#TODO: Actually due to some sudden changes on youtube some changes have to made on this API too..
# ? just use this line before starting any pytube script:
# ! pytube.__main__.apply_descrambler = __pre__.apply_descrambler

# The below imports are required by the patch
import json
from urllib.parse import parse_qs, unquote

# This function is based off on the changes made in
# https://github.com/nficano/pytube/pull/643

    def apply_descrambler(stream_data, key):
        """Apply various in-place transforms to YouTube's media stream data.
        Creates a ``list`` of dictionaries by string splitting on commas, then
        taking each list item, parsing it as a query string, converting it to a
        ``dict`` and unquoting the value.
        :param dict stream_data:
            Dictionary containing query string encoded values.
        :param str key:
            Name of the key in dictionary.
        **Example**:
        >>> d = {'foo': 'bar=1&var=test,em=5&t=url%20encoded'}
        >>> apply_descrambler(d, 'foo')
        >>> print(d)
        {'foo': [{'bar': '1', 'var': 'test'}, {'em': '5', 't': 'url encoded'}]}
        """
        otf_type = "FORMAT_STREAM_TYPE_OTF"
    
        if key == "url_encoded_fmt_stream_map" and not stream_data.get(
            "url_encoded_fmt_stream_map"
        ):
            formats = json.loads(stream_data["player_response"])["streamingData"]["formats"]
            formats.extend(
                json.loads(stream_data["player_response"])["streamingData"][
                    "adaptiveFormats"
                ]
            )
            try:
                stream_data[key] = [
                    {
                        "url": format_item["url"],
                        "type": format_item["mimeType"],
                        "quality": format_item["quality"],
                        "itag": format_item["itag"],
                        "bitrate": format_item.get("bitrate"),
                        "is_otf": (format_item.get("type") == otf_type),
                    }
                    for format_item in formats
                ]
            except KeyError:
                cipher_url = []
                for data in formats:
                    cipher = data.get("cipher") or data["signatureCipher"]
                    cipher_url.append(parse_qs(cipher))
                stream_data[key] = [
                    {
                        "url": cipher_url[i]["url"][0],
                        "s": cipher_url[i]["s"][0],
                        "type": format_item["mimeType"],
                        "quality": format_item["quality"],
                        "itag": format_item["itag"],
                        "bitrate": format_item.get("bitrate"),
                        "is_otf": (format_item.get("type") == otf_type),
                    }
                    for i, format_item in enumerate(formats)
                ]
        else:
            stream_data[key] = [
                {k: unquote(v) for k, v in parse_qsl(i)}
                for i in stream_data[key].split(",")
            ]

此文件是在其中一个问题中发布的(在 pytube GitHub 中),只需每次将其导入您的主文件,然后 pytube.__main__.apply_descrambler = __pre__.apply_descrambler 在您的文件中使用该行。

这会检测密码或密码签名并进行一些必要的更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 2022-12-19
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多