|
|
@ -3314,7 +3314,7 @@ class YoutubeFeedsInfoExtractor(YoutubeBaseInfoExtractor):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
_LOGIN_REQUIRED = True
|
|
|
|
_LOGIN_REQUIRED = True
|
|
|
|
_FEED_DATA = r'window\[\"ytInitialData\"\]\W?=\W?({.*?});'
|
|
|
|
_FEED_DATA = r'window\[\"ytInitialData\"\]\W?=\W?({.*?});'
|
|
|
|
_YTCFG_DATA = r"ytcfg.set\(({.*?})\)"
|
|
|
|
_YTCFG_DATA = r"ytcfg.set\(({.*?})\)"
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@property
|
|
|
|
def IE_NAME(self):
|
|
|
|
def IE_NAME(self):
|
|
|
@ -3323,10 +3323,9 @@ class YoutubeFeedsInfoExtractor(YoutubeBaseInfoExtractor):
|
|
|
|
def _real_initialize(self):
|
|
|
|
def _real_initialize(self):
|
|
|
|
self._login()
|
|
|
|
self._login()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _find_videos_in_json(self, extracted):
|
|
|
|
def _find_videos_in_json(self, extracted):
|
|
|
|
videos = []
|
|
|
|
videos = []
|
|
|
|
continuation = None
|
|
|
|
continuation = None
|
|
|
|
|
|
|
|
|
|
|
|
def _real_find(obj):
|
|
|
|
def _real_find(obj):
|
|
|
|
if obj is None or isinstance(obj, str):
|
|
|
|
if obj is None or isinstance(obj, str):
|
|
|
@ -3340,19 +3339,19 @@ class YoutubeFeedsInfoExtractor(YoutubeBaseInfoExtractor):
|
|
|
|
if "videoId" in obj:
|
|
|
|
if "videoId" in obj:
|
|
|
|
videos.append(obj)
|
|
|
|
videos.append(obj)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
if "nextContinuationData" in obj:
|
|
|
|
if "nextContinuationData" in obj:
|
|
|
|
nonlocal continuation
|
|
|
|
nonlocal continuation
|
|
|
|
continuation = obj["nextContinuationData"]
|
|
|
|
continuation = obj["nextContinuationData"]
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
for _, o in obj.items():
|
|
|
|
for _, o in obj.items():
|
|
|
|
_real_find(o)
|
|
|
|
_real_find(o)
|
|
|
|
|
|
|
|
|
|
|
|
_real_find(extracted)
|
|
|
|
_real_find(extracted)
|
|
|
|
|
|
|
|
|
|
|
|
return videos, continuation
|
|
|
|
return videos, continuation
|
|
|
|
|
|
|
|
|
|
|
|
def _entries(self, page):
|
|
|
|
def _entries(self, page):
|
|
|
|
info = []
|
|
|
|
info = []
|
|
|
|
|
|
|
|
|
|
|
@ -3363,14 +3362,14 @@ class YoutubeFeedsInfoExtractor(YoutubeBaseInfoExtractor):
|
|
|
|
for page_num in itertools.count(1):
|
|
|
|
for page_num in itertools.count(1):
|
|
|
|
video_info, continuation = self._find_videos_in_json(search_response)
|
|
|
|
video_info, continuation = self._find_videos_in_json(search_response)
|
|
|
|
|
|
|
|
|
|
|
|
new_info = []
|
|
|
|
new_info = []
|
|
|
|
|
|
|
|
|
|
|
|
for v in video_info:
|
|
|
|
for v in video_info:
|
|
|
|
v_id = try_get(v, lambda x: x['videoId'])
|
|
|
|
v_id = try_get(v, lambda x: x['videoId'])
|
|
|
|
if not v_id:
|
|
|
|
if not v_id:
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
have_video = False
|
|
|
|
have_video = False
|
|
|
|
for old in info:
|
|
|
|
for old in info:
|
|
|
|
if old['videoId'] == v_id:
|
|
|
|
if old['videoId'] == v_id:
|
|
|
|
have_video = True
|
|
|
|
have_video = True
|
|
|
@ -3406,7 +3405,7 @@ class YoutubeFeedsInfoExtractor(YoutubeBaseInfoExtractor):
|
|
|
|
"X-YouTube-Device": try_get(yt_conf, lambda x: x["DEVICE"]),
|
|
|
|
"X-YouTube-Device": try_get(yt_conf, lambda x: x["DEVICE"]),
|
|
|
|
"X-YouTube-Page-CL": try_get(yt_conf, lambda x: x["PAGE_CL"]),
|
|
|
|
"X-YouTube-Page-CL": try_get(yt_conf, lambda x: x["PAGE_CL"]),
|
|
|
|
"X-YouTube-Page-Label": try_get(yt_conf, lambda x: x["PAGE_BUILD_LABEL"]),
|
|
|
|
"X-YouTube-Page-Label": try_get(yt_conf, lambda x: x["PAGE_BUILD_LABEL"]),
|
|
|
|
"X-YouTube-Variants-Checksum": try_get(yt_conf, lambda x: x["VARIANTS_CHECKSUM"]),
|
|
|
|
"X-YouTube-Variants-Checksum": try_get(yt_conf, lambda x: x["VARIANTS_CHECKSUM"]),
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
def _real_extract(self, url):
|
|
|
|
def _real_extract(self, url):
|
|
|
|