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

Code before:
            'description': 'md5:665bb36ec2a12c5a7f598ee713fc2b54',
        },
        'playlist_mincount': 11,
    }, {
        'url': 'https://www3.nhk.or.jp/nhkworld/en/shows/10yearshayaomiyazaki/',
        'only_matching': True,
    }]

    @classmethod
    def suitable(cls, url):
        return False if NhkVodIE.suitable(url) else super().suitable(url)

    def _extract_meta_from_class_elements(self, class_values, html):
        for class_value in class_values:
            if value := clean_html(get_element_by_class(class_value, html)):
                return value

    def _real_extract(self, url):
        lang, m_type, program_id, episode_type = self._match_valid_url(url).group('lang', 'type', 'id', 'episode_type')
        episodes = self._call_api(
            program_id, lang, m_type != 'audio', False, episode_type == 'clip')

        def entries():
            for episode in episodes['items']:
                if episode_path := episode.get('url'):
                    yield self._extract_episode_info(urljoin(url, episode_path), episode)

        html = self._download_webpage(url, program_id)
        program_title = self._extract_meta_from_class_elements([
            'p-programDetail__title',  # /ondemand/program/
            'pProgramHero__logoText',  # /shows/
            'tAudioProgramMain__title',  # /shows/audio/programs/
            'p-program-name'], html)  # /tv/
        program_description = self._extract_meta_from_class_elements([
            'p-programDetail__text',  # /ondemand/program/
            'pProgramHero__description',  # /shows/
            'tAudioProgramMain__info',  # /shows/audio/programs/
            'p-program-description'], html)  # /tv/

        return self.playlist_result(entries(), program_id, program_title, program_description, series=program_title)


class NhkForSchoolBangumiIE(InfoExtractor):
    _VALID_URL = r'https?://www2\.nhk\.or\.jp/school/movie/(?P<type>bangumi|clip)\.cgi\?das_id=(?P<id>[a-zA-Z0-9_-]+)'
    _TESTS = [{
        'url': 'https://www2.nhk.or.jp/school/movie/bangumi.cgi?das_id=D0005150191_00000',
        'info_dict': {
            'id': 'D0005150191_00003',
            'title': 'にている かな',
            'duration': 599.999,
            'timestamp': 1396414800,

Review comment (refactor):
```suggestion
            for episode in traverse_obj(episodes, ('items', lambda _, v: v['url'])):
                yield self._extract_episode_info(urljoin(url, episode['url']), episode)
```

Code after:

    def _real_extract(self, url):
        lang, m_type, program_id, episode_type = self._match_valid_url(url).group('lang', 'type', 'id', 'episode_type')
        episodes = self._call_api(
            program_id, lang, m_type != 'audio', False, episode_type == 'clip')

        def entries():
            for episode in traverse_obj(episodes, ('items', lambda _, v: v['url'])):
                yield self._extract_episode_info(urljoin(url, episode['url']), episode)

        html = self._download_webpage(url, program_id)
        program_title = self._extract_meta_from_class_elements([
            'p-programDetail__title',  # /ondemand/program/
            'pProgramHero__logoText',  # /shows/
            'tAudioProgramMain__title',  # /shows/audio/programs/
            'p-program-name'], html)  # /tv/
        program_description = self._extract_meta_from_class_elements([
            'p-programDetail__text',  # /ondemand/program/
            'pProgramHero__description',  # /shows/
            'tAudioProgramMain__info',  # /shows/audio/programs/
            'p-program-description'], html)  # /tv/

        return self.playlist_result(entries(), program_id, program_title, program_description, series=program_title)


class NhkForSchoolBangumiIE(InfoExtractor):
    _VALID_URL = r'https?://www2\.nhk\.or\.jp/school/movie/(?P<type>bangumi|clip)\.cgi\?das_id=(?P<id>[a-zA-Z0-9_-]+)'
    _TESTS = [{
        'url': 'https://www2.nhk.or.jp/school/movie/bangumi.cgi?das_id=D0005150191_00000',
        'info_dict': {
            'id': 'D0005150191_00003',
            'title': 'にている かな',
            'duration': 599.999,
            'timestamp': 1396414800,

            'upload_date': '20140402',
            'ext': 'mp4',

            'chapters': 'count:12',
        },
        'params': {
            # m3u8 download
            'skip_download': True,
        },
    }]

    def _real_extract(self, url):
        program_type, video_id = self._match_valid_url(url).groups()

        webpage = self._download_webpage(
            f'https://www2.nhk.or.jp/school/movie/{program_type}.cgi?das_id={video_id}', video_id)