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

Code before:

    def _extract_video(self, video_id, x_ua):
        data = self._download_json(
            'https://www.taptap.cn/webapiv2/video-resource/v1/multi-get', video_id,
            query={'video_ids': video_id, 'X-UA': x_ua})

        video = traverse_obj(data, ('data', 'list', 0, {
            'id': ('video_id', {str_or_none}),
            'url': ('play_url', ('url', 'url_h265'), {url_or_none}),
            'duration': ('info', 'duration', {int_or_none}),
            'thumbnail': ('thumbnail', ('original_url', 'url'), {url_or_none}),
        }), get_all=False)
        if '.m3u8' in video['url']:
            video['formats'] = self._extract_m3u8_formats(video.pop('url'), video_id)
        return video

    def _real_extract(self, url):
        section, list_id = self._match_valid_url(url).groups()
        list_id = f'{section}_{list_id}'

        webpage = self._download_webpage(url, list_id)
        nuxt_data = self._deserialize_nuxt_data(self._search_json(
            r'<script[^>]+\bid=["\']__NUXT_DATA__["\'][^>]*>', webpage,
            'nuxt data', list_id, contains_pattern=r'\[(?s:.+)\]'))[1]
        x_ua = traverse_obj(nuxt_data, (
            'state', '$sbff', ..., {lambda x: parse_qs(x)['X-UA']}, ...), get_all=False)

        if section == 'moment':
            moment_data = traverse_obj(nuxt_data, ('data', ..., 'moment'), get_all=False)
            video_ids = traverse_obj(moment_data, ('topic', (('videos', ...), 'pin_video'), 'video_id'))
            metainfo = traverse_obj(moment_data, {
                'timestamp': ('created_time', {int_or_none}),
                'uploader': ('author', 'user', 'name', {str}),
                'title': ('topic', 'title', {str}),
                'description': ('topic', 'summary', {str}),
            })
        elif section == 'app':
            video_ids = traverse_obj(nuxt_data, ('data', ..., ('app_videos', 'videos'), ..., 'video_id'))
            metainfo = traverse_obj(nuxt_data, ('data', ..., {
                'title': ('title', {str}),
                'description': ('description', 'text', {str}, {clean_html}),
            }), get_all=False)

        entries = [self._extract_video(video_id, x_ua) for video_id in set(video_ids)]

        return self.playlist_result([{**metainfo, **e} for e in entries], **metainfo, id=list_id)


Review comment (refactor):
I think instead of parsing the hydration data it would be better to call the API directly
`https://www.taptap.cn/webapiv2/app/v4/detail`
`https://www.taptap.cn/webapiv2/moment/v3/detail`
I haven't looked too much in to the structure of the returned data, but it could make sense to put the `_extract_video` in to a base class and have separate extractors for moment/app content.

Code after:
            }
        }],
        'params': {'skip_download': 'm3u8'},
    }, {
        'url': 'https://www.taptap.cn/moment/521630629209573493',
        'info_dict': {
            'id': '521630629209573493',
            'title': '《崩坏：星穹铁道》黄泉角色PV——「你的颜色」',
            'description': 'md5:2c81245da864428c904d53ae4ad2182b',
            'timestamp': 1711425600,
            'upload_date': '20240326',
            'modified_timestamp': 1711425600,
            'modified_date': '20240326',
            'uploader': '崩坏：星穹铁道',
            'uploader_id': '414732580',
        },
        'playlist_count': 1,
        'playlist': [{
            'info_dict': {
                'id': '4006511',
                'ext': 'mp4',
                'title': '《崩坏：星穹铁道》黄泉角色PV——「你的颜色」',
                'description': 'md5:2c81245da864428c904d53ae4ad2182b',
                'duration': 173,
                'timestamp': 1711425600,
                'upload_date': '20240326',
                'modified_timestamp': 1711425600,
                'modified_date': '20240326',
                'uploader': '崩坏：星穹铁道',
                'uploader_id': '414732580',
                'thumbnail': r're:^https?://.*\.(png|jpg)',
            }
        }],
        'params': {'skip_download': 'm3u8'},
    }, {
        'url': 'https://www.taptap.cn/moment/540493587511511299',
        'playlist_count': 2,
        'info_dict': {
            'id': '540493587511511299',
            'title': '中式民俗解谜《纸嫁衣7》、新系列《纸不语》公布！',
            'description': 'md5:d60842350e686ddb242291ddfb8e39c9',
            'timestamp': 1715920200,
            'upload_date': '20240517',
            'modified_timestamp': 1715942225,
            'modified_date': '20240517',
            'uploader': 'TapTap 编辑',
            'uploader_id': '7159244',
        },
        'params': {'skip_download': 'm3u8'},
    }]