Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/bilibili.py (Python)

Code before:

        def fetch_page(page_idx):
            return self._download_json(
                'https://api.bilibili.com/x/series/archives',
                playlist_id, note=f'Downloading page {page_idx}',
                query={'mid': mid, 'series_id': sid, 'pn': page_idx + 1, 'ps': 30})['data']

        def get_metadata(page_data):
            page_size = page_data['page']['size']
            entry_count = page_data['page']['total']
            return {
                'page_count': math.ceil(entry_count / page_size),
                'page_size': page_size,
                'uploader': self._get_uploader(mid, playlist_id),
                **playlist_meta
            }

        def get_entries(page_data):
            return self._get_entries(page_data, ('archives', ..., 'bvid', {str}))

        metadata, paged_list = self._extract_playlist(fetch_page, get_metadata, get_entries)
        return self.playlist_result(paged_list, playlist_id, **metadata)


class BilibiliFavoritesListIE(BilibiliSpaceListBaseIE):
    _VALID_URL = r'https?://(?:space.bilibili\.com/\d+/favlist/?\?fid=|(?:www\.)?bilibili\.com/medialist/detail/ml)(?P<id>\d+)'
    _TESTS = [{
        'url': 'https://space.bilibili.com/84912/favlist?fid=1103407912&ftype=create',
        'info_dict': {
            'id': '1103407912',
            'title': '【V2】（旧）',
            'description': '',
            'uploader': '晓月春日',
            'uploader_id': '84912',
            'timestamp': 1604905176,
            'upload_date': '20201109',
            'modified_timestamp': int,
            'modified_date': str,
            'thumbnail': r"re:http://i\d\.hdslb\.com/bfs/archive/14b83c62aa8871b79083df1e9ab4fbc699ad16fe\.jpg",
            'view_count': int,
            'like_count': int,
        },
        'playlist_mincount': 22,
    }, {
        'url': 'https://www.bilibili.com/medialist/detail/ml1103407912',
        'only_matching': True,
    }]

    def _real_extract(self, url):
        fid = self._match_id(url)


Review comment (suggestion):
```suggestion
    _VALID_URL = r'https?://(?:space\.bilibili\.com/\d+/favlist/?\?fid=|(?:www\.)?bilibili\.com/medialist/detail/ml)(?P<id>\d+)'
```
&nbsp;
or, the other `_VALID_URL` patterns do not match if there is no subdomain, so should we do this?
```suggestion
    _VALID_URL = r'https?://(?:space\.bilibili\.com/\d+/favlist/?\?fid=|www\.bilibili\.com/medialist/detail/ml)(?P<id>\d+)'
```

Code after:
                'uploader': self._get_uploader(mid, playlist_id),
                **traverse_obj(page_data, {
                    'title': ('meta', 'name', {str}),
                    'description': ('meta', 'description', {str}),
                    'uploader_id': ('meta', 'mid', {str_or_none}),
                    'timestamp': ('meta', 'ptime', {int_or_none}),
                    'thumbnail': ('meta', 'cover', {url_or_none}),
                })
            }

        def get_entries(page_data):
            return self._get_entries(page_data, 'archives')

        metadata, paged_list = self._extract_playlist(fetch_page, get_metadata, get_entries)
        return self.playlist_result(paged_list, playlist_id, **metadata)


class BilibiliSeriesListIE(BilibiliSpaceListBaseIE):
    _VALID_URL = r'https?://space\.bilibili\.com/(?P<mid>\d+)/channel/seriesdetail/?\?\bsid=(?P<sid>\d+)'
    _TESTS = [{
        'url': 'https://space.bilibili.com/1958703906/channel/seriesdetail?sid=547718&ctype=0',
        'info_dict': {
            'id': '1958703906_547718',
            'title': '直播回放',
            'description': '直播回放',
            'uploader': '靡烟miya',
            'uploader_id': '1958703906',
            'timestamp': 1637985853,
            'upload_date': '20211127',
            'modified_timestamp': int,
            'modified_date': str,
        },
        'playlist_mincount': 513,
    }]

    def _real_extract(self, url):
        mid, sid = self._match_valid_url(url).group('mid', 'sid')
        playlist_id = f'{mid}_{sid}'
        playlist_meta = traverse_obj(self._download_json(
            f'https://api.bilibili.com/x/series/series?series_id={sid}', playlist_id, fatal=False
        ), {
            'title': ('data', 'meta', 'name', {str}),
            'description': ('data', 'meta', 'description', {str}),
            'uploader_id': ('data', 'meta', 'mid', {str_or_none}),
            'timestamp': ('data', 'meta', 'ctime', {int_or_none}),
            'modified_timestamp': ('data', 'meta', 'mtime', {int_or_none}),
        })

        def fetch_page(page_idx):
            return self._download_json(
                'https://api.bilibili.com/x/series/archives',