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

Code before:
                        'description': strip_or_none(item_desc),
                    })
            for resp in (initial_data.get('data') or {}).values():
                name = resp.get('name')
                if name == 'media-experience':
                    parse_media(try_get(resp, lambda x: x['data']['initialItem']['mediaItem'], dict))
                elif name == 'article':
                    for block in (try_get(resp,
                                          (lambda x: x['data']['blocks'],
                                           lambda x: x['data']['content']['model']['blocks'],),
                                          list) or []):
                        if block.get('type') not in ['media', 'video']:
                            continue
                        parse_media(block.get('model'))
            return self.playlist_result(
                entries, playlist_id, playlist_title, playlist_description)

        def extract_all(pattern):
            return list(filter(None, map(
                lambda s: self._parse_json(s, playlist_id, fatal=False),
                re.findall(pattern, webpage))))

        # US accessed article with single embedded video (e.g.
        # https://www.bbc.com/news/uk-68546268)
        video_id = self._match_id(url)
        next_data = self._search_nextjs_data(webpage, video_id)['props']['pageProps']['page']
        video_data = None
        timestamp = None
        for key in next_data:
            for item in (try_get(next_data, lambda x: x[key]['contents'], list) or []):
                if item.get('type') == 'video':
                    video_data = item
                elif item.get('type') == 'timestamp':
                    timestamp = item
        if video_data:
            for item in (try_get(video_data, lambda x: x['model']['blocks'], list) or []):
                if item.get('type') == 'media':
                    for subtype in (try_get(item, lambda x: x['model']['blocks'], list) or []):
                        if subtype.get('type') == 'mediaMetadata':
                            model = subtype.get('model')
                            if model:
                                item_id = try_get(model, lambda x: x['versions'][0]['versionId'])
                                item_thumbnail = model.get('imageUrl')
                                item_title = model.get('title')
                                formats, subtitles = self._download_media_selector(item_id)
                                synopses = model.get('synopses') or {}
            item_time = None
            if timestamp:
                item_time = try_get(timestamp, lambda x: x['model']['timestamp'])
            entries.append({
                'id': item_id,

Review comment (refactor):
this needs to be non-fatal -- use `traverse_obj`. as-is, this line will throw for UK users before the rest of the extraction code can be reached

Code after:
                    'duration': parse_duration(clip.get('duration')),
                    'formats': formats,
                    'subtitles': subtitles,
                }
            bbc3_playlist = try_get(
                payload, lambda x: x['content']['bbcMedia']['playlist'],
                dict)
            if bbc3_playlist:
                playlist_title = bbc3_playlist.get('title') or playlist_title
                thumbnail = bbc3_playlist.get('holdingImageURL')
                entries = []
                for bbc3_item in bbc3_playlist['items']:
                    programme_id = bbc3_item.get('versionID')
                    if not programme_id:
                        continue
                    formats, subtitles = self._download_media_selector(programme_id)
                    entries.append({
                        'id': programme_id,
                        'title': playlist_title,
                        'thumbnail': thumbnail,
                        'timestamp': timestamp,
                        'formats': formats,
                        'subtitles': subtitles,
                    })
                return self.playlist_result(
                    entries, playlist_id, playlist_title, playlist_description)

        def parse_model(model):
            """Extract single video from model structure"""
            item_id = traverse_obj(model, ('versions', 0, 'versionId', {str}))
            if not item_id:
                return
            formats, subtitles = self._download_media_selector(item_id)
            return {
                'id': item_id,
                'formats': formats,
                'subtitles': subtitles,
                **traverse_obj(model, {
                    'title': ('title', {str}),
                    'thumbnail': ('imageUrl', {lambda u: urljoin(url, u.replace('$recipe', 'raw'))}),
                    'description': ('synopses', ('long', 'medium', 'short'), {str}, {lambda x: x or None}, any),
                    'duration': ('versions', 0, 'duration', {int}),
                    'timestamp': ('versions', 0, 'availableFrom', {functools.partial(int_or_none, scale=1000)}),
                })
            }

        def is_type(*types):
            return lambda _, v: v['type'] in types

        initial_data = self._search_regex(
            r'window\.__INITIAL_DATA__\s*=\s*("{.+?}")\s*;', webpage,