diff --git a/yt_dlp/extractor/_extractors.py b/yt_dlp/extractor/_extractors.py index 117843523..bb31fbb88 100644 --- a/yt_dlp/extractor/_extractors.py +++ b/yt_dlp/extractor/_extractors.py @@ -254,6 +254,7 @@ from .bilibili import ( BiliBiliIE, BiliBiliPlayerIE, BilibiliPlaylistIE, + BiliBiliSearchAllIE, BiliBiliSearchIE, BiliBiliSearchPageIE, BilibiliSeriesListIE, diff --git a/yt_dlp/extractor/bilibili.py b/yt_dlp/extractor/bilibili.py index 36aab7c1b..62d62edb4 100644 --- a/yt_dlp/extractor/bilibili.py +++ b/yt_dlp/extractor/bilibili.py @@ -1489,6 +1489,82 @@ class BilibiliCategoryIE(InfoExtractor): return self.playlist_result(self._entries(category, subcategory, query), query, query) +class BiliBiliSearchAllIE(SearchInfoExtractor): + IE_DESC = 'Bilibili all search' + _MAX_RESULTS = 100000 + _SEARCH_KEY = 'bilisearchall' + _TESTS = [{ + 'url': 'bilisearchall3:靡烟 出道一年,我怎么还在等你单推的女人睡觉后开播啊', + 'playlist_count': 3, + 'info_dict': { + 'id': '靡烟 出道一年,我怎么还在等你单推的女人睡觉后开播啊', + 'title': '靡烟 出道一年,我怎么还在等你单推的女人睡觉后开播啊', + }, + 'playlist': [{ + 'info_dict': { + 'id': 'BV1n44y1Q7sc', + 'ext': 'mp4', + 'title': '“出道一年,我怎么还在等你单推的女人睡觉后开播啊?”【一分钟了解靡烟miya】', + 'timestamp': 1669889987, + 'upload_date': '20221201', + 'description': 'md5:43343c0973defff527b5a4b403b4abf9', + 'tags': list, + 'uploader': '靡烟miya', + 'duration': 123.156, + 'uploader_id': '1958703906', + 'comment_count': int, + 'view_count': int, + 'like_count': int, + 'thumbnail': r're:^https?://.*\.(jpg|jpeg|png)$', + '_old_archive_ids': ['bilibili 988222410_part1'], + }, + }], + }, { + 'url': 'bilisearchall:LOL', + 'playlist_count': 1, + 'info_dict': { + 'id': 'LOL', + 'title': 'LOL', + }, + }] + + def _search_results(self, query): + headers = self.geo_verification_headers() + live_room_prefix = 'https://live.bilibili.com/' + bili_user_prefix = 'https://space.bilibili.com/' + if not self._get_cookies('https://api.bilibili.com').get('buvid3'): + self._set_cookie('.bilibili.com', 'buvid3', f'{uuid.uuid4()}infoc') + for page_num in itertools.count(1): + try: + search_all_result = self._download_json( + r'https://api.bilibili.com/x/web-interface/search/all/v2', + video_id=query, query={ + 'keyword': query, + 'page': page_num, + }, headers=headers) + except ExtractorError as e: + if isinstance(e.cause, HTTPError) and e.cause.status == 412: + raise ExtractorError('Request is blocked by server (-412).', expected=True) + status_code = search_all_result['code'] + if status_code == -400: + raise ExtractorError('Invalid request (-400).', expected=True) + result_list = search_all_result['data'].get('result') + if result_list is None: + self.write_debug(f'Response: {search_all_result}') + raise ExtractorError(f'Result not found in the response ({status_code}).', + expected=True) + for result_type_dict in result_list: + for result_data in result_type_dict['data']: + if result_data['type'] == 'video': + yield self.url_result(result_data['arcurl']) + elif result_data['type'] == 'live_room': + yield self.url_result(live_room_prefix + str(result_data['roomid'])) + elif result_data['type'] in ['media_ft', 'media_bangumi']: + yield self.url_result(result_data['url']) + elif result_data['type'] == 'bili_user': + yield self.url_result(bili_user_prefix + str(result_data['mid'])) + + class BiliBiliSearchIE(SearchInfoExtractor): IE_DESC = 'Bilibili video search' _MAX_RESULTS = 100000