diff --git a/yt_dlp/extractor/youtube.py b/yt_dlp/extractor/youtube.py index cf8f6ef39..4dc80fe28 100644 --- a/yt_dlp/extractor/youtube.py +++ b/yt_dlp/extractor/youtube.py @@ -857,6 +857,18 @@ class YoutubeBaseInfoExtractor(InfoExtractor): } return filter_dict(headers) + def _download_webpage_with_retries(self, *args, retry_fatal=False, retry_on_status=None, **kwargs): + for retry in self.RetryManager(fatal=retry_fatal): + try: + return self._download_webpage(*args, **kwargs) + except ExtractorError as e: + if isinstance(e.cause, network_exceptions): + if not isinstance(e.cause, HTTPError) or e.cause.status not in (retry_on_status or (403, 429)): + retry.error = e + continue + self._error_or_warning(e, fatal=retry_fatal) + break + def _download_ytcfg(self, client, video_id): url = { 'web': 'https://www.youtube.com', @@ -866,8 +878,8 @@ class YoutubeBaseInfoExtractor(InfoExtractor): }.get(client) if not url: return {} - webpage = self._download_webpage( - url, video_id, fatal=False, note=f'Downloading {client.replace("_", " ").strip()} client config', + webpage = self._download_webpage_with_retries( + url, video_id, note=f'Downloading {client.replace("_", " ").strip()} client config', headers=traverse_obj(self._get_default_ytcfg(client), { 'User-Agent': ('INNERTUBE_CONTEXT', 'client', 'userAgent', {str}), })) @@ -3143,12 +3155,14 @@ class YoutubeIE(YoutubeBaseInfoExtractor): return urljoin('https://www.youtube.com', player_url) def _download_player_url(self, video_id, fatal=False): - res = self._download_webpage( + iframe_webpage = self._download_webpage_with_retries( 'https://www.youtube.com/iframe_api', - note='Downloading iframe API JS', video_id=video_id, fatal=fatal) - if res: + note='Downloading iframe API JS', + video_id=video_id, retry_fatal=fatal) + + if iframe_webpage: player_version = self._search_regex( - r'player\\?/([0-9a-fA-F]{8})\\?/', res, 'player version', fatal=fatal) + r'player\\?/([0-9a-fA-F]{8})\\?/', iframe_webpage, 'player version', fatal=fatal) if player_version: return f'https://www.youtube.com/s/player/{player_version}/player_ias.vflset/en_US/base.js' @@ -4561,8 +4575,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): pp = self._configuration_arg('player_params', [None], casesense=True)[0] if pp: query['pp'] = pp - webpage = self._download_webpage( - webpage_url, video_id, fatal=False, query=query) + webpage = self._download_webpage_with_retries(webpage_url, video_id, query=query) master_ytcfg = self.extract_ytcfg(video_id, webpage) or self._get_default_ytcfg()