]> jfr.im git - yt-dlp.git/blobdiff - yt_dlp/extractor/youtube.py
[youtube] Retry on incomplete `ytInitialData`
[yt-dlp.git] / yt_dlp / extractor / youtube.py
index 9eaa5c08d58ef3f4cbc81097e44ffc18522002d8..d30faf94ceaeb809220c4c4c2953884f225860dc 100644 (file)
@@ -2998,19 +2998,29 @@ def _real_extract(self, url):
                 return self.url_result(video_id, ie=YoutubeIE.ie_key(), video_id=video_id)
             self.to_screen('Downloading playlist %s - add --no-playlist to just download video %s' % (playlist_id, video_id))
 
-        webpage = self._download_webpage(url, item_id)
-        identity_token = self._extract_identity_token(webpage, item_id)
-        data = self._extract_yt_initial_data(item_id, webpage)
-        err_msg = None
-        for alert_type, alert_message in self._extract_alerts(data):
-            if alert_type.lower() == 'error':
-                if err_msg:
-                    self._downloader.report_warning('YouTube said: %s - %s' % ('ERROR', err_msg))
-                err_msg = alert_message
-            else:
-                self._downloader.report_warning('YouTube said: %s - %s' % (alert_type, alert_message))
-        if err_msg:
-            raise ExtractorError('YouTube said: %s' % err_msg, expected=True)
+        count = 0
+        retries = 3
+        while count < retries:
+            # Sometimes youtube returns a webpage with incomplete ytInitialData
+            webpage = self._download_webpage(url, item_id)
+            identity_token = self._extract_identity_token(webpage, item_id)
+            data = self._extract_yt_initial_data(item_id, webpage)
+            err_msg = None
+            for alert_type, alert_message in self._extract_alerts(data):
+                if alert_type.lower() == 'error':
+                    if err_msg:
+                        self._downloader.report_warning('YouTube said: %s - %s' % ('ERROR', err_msg))
+                    err_msg = alert_message
+                else:
+                    self._downloader.report_warning('YouTube said: %s - %s' % (alert_type, alert_message))
+            if err_msg:
+                raise ExtractorError('YouTube said: %s' % err_msg, expected=True)
+            if data.get('contents') or data.get('currentVideoEndpoint'):
+                break
+            count += 1
+            self.to_screen(
+                'Incomplete yt initial data recieved. Retrying (attempt %d of %d)...' % (count, retries))
+
         tabs = try_get(
             data, lambda x: x['contents']['twoColumnBrowseResultsRenderer']['tabs'], list)
         if tabs: