这是我每次尝试下载任何官方视频时总是会收到的错误,但是使用某些在线下载应用程序会下载相同的视频。
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'
任何人都可以帮助我解决这个错误
答案 0 :(得分:0)
我也有同样的问题。我通过以下方法解决了这个问题:
site-packages/pytub/extract.py
,其中安装了pytube
。parse_qs(formats[i]["cipher"]) for i, data in enumerate(formats)
["cipher"]
替换为["signatureCipher"]
来源here。
答案 1 :(得分:0)
#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
在文件上使用该行。
这将检测密码或密码签名并进行一些必要的更改。