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

Code before:
            'title': 'Norðmenn tala ekki um annað en prinsessuna',
            'categories': ['frettir'],
            'description': 'md5:53e2623ae79e1355778c14f5b557a0cd',
            'display_id': 'nordmenn-tala-ekki-um-annad-en-prinsessuna',
            'duration': 138,
            'thumbnail': r're:https?://www\.visir\.is/.+',
            'upload_date': '20260202',
            'view_count': int,
        },
    }]

    def _real_extract(self, url):
        video_type, video_id, display_id = self._match_valid_url(url).group('type', 'id', 'slug')
        webpage = self._download_webpage(url, video_id)
        if video_type == 'player':
            real_url = self._og_search_url(webpage)
            if not self.suitable(real_url) or self._match_valid_url(real_url).group('type') == 'player':
                raise UnsupportedError(real_url)
            return self.url_result(real_url, self.ie_key())

        upload_date = None
        if date_str := traverse_obj(webpage, (
            {find_element(cls='article-item__date')}, {clean_html}, filter,
        )):
            day, month, year = date_str.replace('.', '').split()
            day = int_or_none(day)
            month = month_by_name(month, 'is')
            if day and month and re.fullmatch(r'[0-9]{4}', year):
                upload_date = f'{year}{month:02d}{day:02d}'

        player = self._search_json(
            r'App\.Player\.Init\(', webpage, video_id, 'player', transform_source=js_to_json)
        m3u8_url = traverse_obj(player, ('File', {urljoin('https://vod.visir.is/')}))

        return {
            'id': video_id,
            'display_id': display_id,
            'formats': self._extract_m3u8_formats(m3u8_url, video_id, 'mp4'),
            'upload_date': upload_date,
            **traverse_obj(webpage, ({find_element(cls='article-item press-ads')}, {
                'description': ({find_element(cls='-large')}, {clean_html}, filter),
                'view_count': ({find_element(cls='article-item__viewcount')}, {clean_html}, {int_or_none}),
            })),
            **traverse_obj(player, {
                'title': ('Title', {clean_html}),
                'categories': ('Categoryname', {clean_html}, filter, all, filter),
                'duration': ('MediaDuration', {int_or_none}),
                'thumbnail': ('Image', {url_or_none}),
            }),
        }


Review comment (suggestion):
Hmm, this is still fatal if `date_str` splits into a list with a length != 3

We could do this:
```suggestion
        # date string is in the format of "21. janúar 2026"
        date_elements = traverse_obj(webpage, (
            {find_element(cls='article-item__date')}, {clean_html}, filter, {str.split}))
        if date_elements and len(date_elements) == 3:
            day, month, year = date_elements
            day = int_or_none(day.rstrip('.'))
```

Code after:
            'title': 'Norðmenn tala ekki um annað en prinsessuna',
            'categories': ['frettir'],
            'description': 'md5:53e2623ae79e1355778c14f5b557a0cd',
            'display_id': 'nordmenn-tala-ekki-um-annad-en-prinsessuna',
            'duration': 138,
            'thumbnail': r're:https?://www\.visir\.is/.+',
            'upload_date': '20260202',
            'view_count': int,
        },
    }]

    def _real_extract(self, url):
        video_type, video_id, display_id = self._match_valid_url(url).group('type', 'id', 'slug')
        webpage = self._download_webpage(url, video_id)
        if video_type == 'player':
            real_url = self._og_search_url(webpage)
            if not self.suitable(real_url) or self._match_valid_url(real_url).group('type') == 'player':
                raise UnsupportedError(real_url)
            return self.url_result(real_url, self.ie_key())

        upload_date = None
        date_elements = traverse_obj(webpage, (
            {find_element(cls='article-item__date')}, {clean_html}, filter, {str.split}))
        if date_elements and len(date_elements) == 3:
            day, month, year = date_elements
            day = int_or_none(day.rstrip('.'))
            month = month_by_name(month, 'is')
            if day and month and re.fullmatch(r'[0-9]{4}', year):
                upload_date = f'{year}{month:02d}{day:02d}'

        player = self._search_json(
            r'App\.Player\.Init\(', webpage, video_id, 'player', transform_source=js_to_json)
        m3u8_url = traverse_obj(player, ('File', {urljoin('https://vod.visir.is/')}))

        return {
            'id': video_id,
            'display_id': display_id,
            'formats': self._extract_m3u8_formats(m3u8_url, video_id, 'mp4'),
            'upload_date': upload_date,
            **traverse_obj(webpage, ({find_element(cls='article-item press-ads')}, {
                'description': ({find_element(cls='-large')}, {clean_html}, filter),
                'view_count': ({find_element(cls='article-item__viewcount')}, {clean_html}, {int_or_none}),
            })),
            **traverse_obj(player, {
                'title': ('Title', {clean_html}),
                'categories': ('Categoryname', {clean_html}, filter, all, filter),
                'duration': ('MediaDuration', {int_or_none}),
                'thumbnail': ('Image', {url_or_none}),
            }),
        }