mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-30 22:25:19 +00:00 
			
		
		
		
	Allow ampersand right after ? in youtube URLs (Closes #602)
This commit is contained in:
		| @@ -9,8 +9,8 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |||||||
| 
 | 
 | ||||||
| from youtube_dl.InfoExtractors import YoutubeIE, YoutubePlaylistIE | from youtube_dl.InfoExtractors import YoutubeIE, YoutubePlaylistIE | ||||||
| 
 | 
 | ||||||
| class TestYoutubePlaylistMatching(unittest.TestCase): | class TestAllURLsMatching(unittest.TestCase): | ||||||
|     def test_playlist_matching(self): |     def test_youtube_playlist_matching(self): | ||||||
|         self.assertTrue(YoutubePlaylistIE().suitable(u'ECUl4u3cNGP61MdtwGTqZA0MreSaDybji8')) |         self.assertTrue(YoutubePlaylistIE().suitable(u'ECUl4u3cNGP61MdtwGTqZA0MreSaDybji8')) | ||||||
|         self.assertTrue(YoutubePlaylistIE().suitable(u'PL63F0C78739B09958')) |         self.assertTrue(YoutubePlaylistIE().suitable(u'PL63F0C78739B09958')) | ||||||
|         self.assertFalse(YoutubePlaylistIE().suitable(u'PLtS2H6bU1M')) |         self.assertFalse(YoutubePlaylistIE().suitable(u'PLtS2H6bU1M')) | ||||||
| @@ -18,5 +18,10 @@ class TestYoutubePlaylistMatching(unittest.TestCase): | |||||||
|     def test_youtube_matching(self): |     def test_youtube_matching(self): | ||||||
|         self.assertTrue(YoutubeIE().suitable(u'PLtS2H6bU1M')) |         self.assertTrue(YoutubeIE().suitable(u'PLtS2H6bU1M')) | ||||||
| 
 | 
 | ||||||
|  |     def test_youtube_extract(self): | ||||||
|  |         self.assertEqual(YoutubeIE()._extract_id('http://www.youtube.com/watch?&v=BaW_jenozKc'), 'BaW_jenozKc') | ||||||
|  |         self.assertEqual(YoutubeIE()._extract_id('https://www.youtube.com/watch?&v=BaW_jenozKc'), 'BaW_jenozKc') | ||||||
|  |         self.assertEqual(YoutubeIE()._extract_id('https://www.youtube.com/watch?feature=player_embedded&v=BaW_jenozKc'), 'BaW_jenozKc') | ||||||
|  | 
 | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|     unittest.main() |     unittest.main() | ||||||
| @@ -120,7 +120,7 @@ class YoutubeIE(InfoExtractor): | |||||||
|                              |(?:                                             # or the v= param in all its forms |                              |(?:                                             # or the v= param in all its forms | ||||||
|                                  (?:watch(?:_popup)?(?:\.php)?)?              # preceding watch(_popup|.php) or nothing (like /?v=xxxx) |                                  (?:watch(?:_popup)?(?:\.php)?)?              # preceding watch(_popup|.php) or nothing (like /?v=xxxx) | ||||||
|                                  (?:\?|\#!?)                                  # the params delimiter ? or # or #! |                                  (?:\?|\#!?)                                  # the params delimiter ? or # or #! | ||||||
|                                  (?:.+&)?                                     # any other preceding param (like /?s=tuff&v=xxxx) |                                  (?:.*?&)?                                    # any other preceding param (like /?s=tuff&v=xxxx) | ||||||
|                                  v= |                                  v= | ||||||
|                              ) |                              ) | ||||||
|                          )?                                                   # optional -> youtube.com/xxxx is OK |                          )?                                                   # optional -> youtube.com/xxxx is OK | ||||||
| @@ -325,22 +325,25 @@ class YoutubeIE(InfoExtractor): | |||||||
|             self._downloader.trouble(u'ERROR: unable to confirm age: %s' % compat_str(err)) |             self._downloader.trouble(u'ERROR: unable to confirm age: %s' % compat_str(err)) | ||||||
|             return |             return | ||||||
|  |  | ||||||
|     def _real_extract(self, url): |     def _extract_id(self, url): | ||||||
|         # Extract original video URL from URL with redirection, like age verification, using next_url parameter |  | ||||||
|         mobj = re.search(self._NEXT_URL_RE, url) |  | ||||||
|         if mobj: |  | ||||||
|             url = 'http://www.youtube.com/' + compat_urllib_parse.unquote(mobj.group(1)).lstrip('/') |  | ||||||
|  |  | ||||||
|         # Extract video id from URL |  | ||||||
|         mobj = re.match(self._VALID_URL, url, re.VERBOSE) |         mobj = re.match(self._VALID_URL, url, re.VERBOSE) | ||||||
|         if mobj is None: |         if mobj is None: | ||||||
|             self._downloader.trouble(u'ERROR: invalid URL: %s' % url) |             self._downloader.trouble(u'ERROR: invalid URL: %s' % url) | ||||||
|             return |             return | ||||||
|         video_id = mobj.group(2) |         video_id = mobj.group(2) | ||||||
|  |         return video_id | ||||||
|  |  | ||||||
|  |     def _real_extract(self, url): | ||||||
|  |         # Extract original video URL from URL with redirection, like age verification, using next_url parameter | ||||||
|  |         mobj = re.search(self._NEXT_URL_RE, url) | ||||||
|  |         if mobj: | ||||||
|  |             url = 'http://www.youtube.com/' + compat_urllib_parse.unquote(mobj.group(1)).lstrip('/') | ||||||
|  |         video_id = self._extract_id(url) | ||||||
|  |  | ||||||
|         # Get video webpage |         # Get video webpage | ||||||
|         self.report_video_webpage_download(video_id) |         self.report_video_webpage_download(video_id) | ||||||
|         request = compat_urllib_request.Request('http://www.youtube.com/watch?v=%s&gl=US&hl=en&has_verified=1' % video_id) |         url = 'http://www.youtube.com/watch?v=%s&gl=US&hl=en&has_verified=1' % video_id | ||||||
|  |         request = compat_urllib_request.Request(url) | ||||||
|         try: |         try: | ||||||
|             video_webpage_bytes = compat_urllib_request.urlopen(request).read() |             video_webpage_bytes = compat_urllib_request.urlopen(request).read() | ||||||
|         except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: |         except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Philipp Hagemeister
					Philipp Hagemeister