]> jfr.im git - yt-dlp.git/blobdiff - yt_dlp/extractor/reddit.py
[reddit] Fix 429 by generating a random `reddit_session`
[yt-dlp.git] / yt_dlp / extractor / reddit.py
index 638f2b6a84bb8b488b1d9ba3e9113c1baf24f4c0..e5a1f692052113b387e88987febc34dae3b33ea9 100644 (file)
@@ -1,5 +1,4 @@
-from __future__ import unicode_literals
-
+import random
 
 from .common import InfoExtractor
 from ..utils import (
@@ -49,7 +48,7 @@ def _real_extract(self, url):
 
 
 class RedditRIE(InfoExtractor):
-    _VALID_URL = r'(?P<url>https?://(?:[^/]+\.)?reddit\.com/r/[^/]+/comments/(?P<id>[^/?#&]+))'
+    _VALID_URL = r'https?://(?P<subdomain>[^/]+\.)?reddit(?:media)?\.com/r/(?P<slug>[^/]+/comments/(?P<id>[^/?#&]+))'
     _TESTS = [{
         'url': 'https://www.reddit.com/r/videos/comments/6rrwyj/that_small_heart_attack/',
         'info_dict': {
@@ -94,19 +93,27 @@ class RedditRIE(InfoExtractor):
         # reddit video @ nm reddit
         'url': 'https://nm.reddit.com/r/Cricket/comments/8idvby/lousy_cameraman_finds_himself_in_cairns_line_of/',
         'only_matching': True,
+    }, {
+        'url': 'https://www.redditmedia.com/r/serbia/comments/pu9wbx/ako_vu%C4%8Di%C4%87_izgubi_izbore_ja_%C4%87u_da_crknem/',
+        'only_matching': True,
     }]
 
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        url, video_id = mobj.group('url', 'id')
-
-        video_id = self._match_id(url)
-
-        self._set_cookie('reddit.com', '_options', '%7B%22pref_quarantine_optin%22%3A%20true%7D')
-
-        data = self._download_json(
-            url + '/.json', video_id)[0]['data']['children'][0]['data']
+    @staticmethod
+    def _gen_session_id():
+        id_length = 16
+        rand_max = 1 << (id_length * 4)
+        return '%0.*x' % (id_length, random.randrange(rand_max))
 
+    def _real_extract(self, url):
+        subdomain, slug, video_id = self._match_valid_url(url).group('subdomain', 'slug', 'id')
+
+        self._set_cookie('.reddit.com', 'reddit_session', self._gen_session_id())
+        self._set_cookie('.reddit.com', '_options', '%7B%22pref_quarantine_optin%22%3A%20true%7D')
+        data = self._download_json(f'https://{subdomain}.reddit.com/r/{slug}/.json', video_id, fatal=False)
+        if not data:
+            # Fall back to old.reddit.com in case the requested subdomain fails
+            data = self._download_json(f'https://old.reddit.com/r/{slug}/.json', video_id)
+        data = data[0]['data']['children'][0]['data']
         video_url = data['url']
 
         # Avoid recursing into the same reddit URL