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

Code before:
            },
        },
        {
            # premium
            'url': 'https://www.ruutu.fi/video/3618715',
            'only_matching': True,
        },
    ]
    _API_BASE = 'https://gatling.nelonenmedia.fi'

    @classmethod
    def _extract_urls(cls, webpage):
        # nelonen.fi
        settings = try_call(
            lambda: json.loads(re.search(
                r'jQuery\.extend\(Drupal\.settings, ({.+?})\);', webpage).group(1), strict=False))
        if settings:
            video_id = traverse_obj(settings, (
                'mediaCrossbowSettings', 'file', 'field_crossbow_video_id', 'und', 0, 'value'))
            if video_id:
                return [f'http://www.ruutu.fi/video/{video_id}']
        # hs.fi
        settings = try_call(
            lambda: json.loads(re.search(
                r'<script id="__NEXT_DATA__" type="application/json">\s*({.+?})\s*</script>',
                webpage).group(1), strict=False))
        if settings:
            video_ids = list(filter(
                bool, (traverse_obj(d, ('video', 'sourceId')) for d in traverse_obj(settings,
                       ('props', 'pageProps', 'page', 'assetData', 'splitBody')))))
            if video_ids:
                return list(f'http://www.ruutu.fi/video/{v}' for v in video_ids)

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

        video_xml = self._download_xml(
            '%s/media-xml-cache' % self._API_BASE, video_id,
            query={'id': video_id})

        formats = []
        processed_urls = []

        def extract_formats(node):
            for child in node:
                if child.tag.endswith('Files'):
                    extract_formats(child)
                elif child.tag.endswith('File'):
                    video_url = child.text
                    if (not video_url or video_url in processed_urls
                            or any(p in video_url for p in ('NOT_USED', 'NOT-USED'))):

Review comment (suggestion):
```suggestion
            lambda: json.loads(re.search(
                '(?s)<script[^>]+id=[\'"]__NEXT_DATA__[\'"][^>]*>([^<]+)</script>',
                webpage).group(1), strict=False))
```

Code after:
                'age_limit': 12,
                'upload_date': '20190508',
                'series': 'Temptation Island Suomi',
                'season_number': 5,
                'episode_number': 17,
                'categories': ['Reality ja tositapahtumat', 'Kotimaiset suosikit', 'Romantiikka ja parisuhde'],
            },
            'params': {
                'skip_download': True,
            },
        },
        {
            # premium
            'url': 'https://www.ruutu.fi/video/3618715',
            'only_matching': True,
        },
    ]
    _API_BASE = 'https://gatling.nelonenmedia.fi'

    @classmethod
    def _extract_urls(cls, webpage):
        # nelonen.fi
        settings = try_call(
            lambda: json.loads(re.search(
                r'jQuery\.extend\(Drupal\.settings, ({.+?})\);', webpage).group(1), strict=False))
        if settings:
            video_id = traverse_obj(settings, (
                'mediaCrossbowSettings', 'file', 'field_crossbow_video_id', 'und', 0, 'value'))
            if video_id:
                return [f'http://www.ruutu.fi/video/{video_id}']
        # hs.fi and is.fi
        settings = try_call(
            lambda: json.loads(re.search(
                '(?s)<script[^>]+id=[\'"]__NEXT_DATA__[\'"][^>]*>([^<]+)</script>',
                webpage).group(1), strict=False))
        if settings:
            video_ids = set(traverse_obj(settings, (
                'props', 'pageProps', 'page', 'assetData', 'splitBody', ..., 'video', 'sourceId')) or [])
            if video_ids:
                return [f'http://www.ruutu.fi/video/{v}' for v in video_ids]
            video_id = traverse_obj(settings, (
                'props', 'pageProps', 'page', 'assetData', 'mainVideo', 'sourceId'))
            if video_id:
                return [f'http://www.ruutu.fi/video/{video_id}']

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

        video_xml = self._download_xml(
            '%s/media-xml-cache' % self._API_BASE, video_id,
            query={'id': video_id})