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

Code before:

        initial_data_video = traverse_obj(
            initial_data, ('contents', 'twoColumnWatchNextResults', 'results', 'results', 'contents', ..., 'videoPrimaryInfoRenderer'),
            expected_type=dict, get_all=False, default={})

        video_details = traverse_obj(
            player_response, 'videoDetails', expected_type=dict, get_all=False, default={})

        microformats = traverse_obj(
            player_response, ('microformat', 'playerMicroformatRenderer'), expected_type=dict, get_all=False, default={})

        video_title = (
            video_details.get('title')
            or YoutubeBaseInfoExtractor._get_text(microformats, 'title')
            or YoutubeBaseInfoExtractor._get_text(initial_data_video, 'title')
            or traverse_obj(player_config, ('args', 'title'))
            or self._extract_webpage_title(webpage)
            or search_meta(['og:title', 'twitter:title', 'title']))

        def id_from_url(url, type_):
            return self._search_regex(
                rf'(?:{type_})/([^/#&?]+)', url or '', f'{type_} id', default=None)

        # XXX: would the get_elements_by_... functions be better suited here?
        # Uploader ID and URL
        _CHANNEL_URL_HREF_RE = r'href=\"[^\"]*(?P<url>https?://www\.youtube\.com/(?:user|channel)/[^\"]+)\"'
        upch_url = self._search_regex(
            [fr'<(?:link\s*itemprop=\"url\"|a\s*id=\"watch-username\").*?\b{_CHANNEL_URL_HREF_RE}>',  # @fd05024
             fr'<div\s*id=\"(?:watch-channel-stats|watch-headline-user-info)\"[^>]*>\s*<a[^>]*\b{_CHANNEL_URL_HREF_RE}'],  # ~ May 2009, ~June 2012
            webpage, 'uploader or channel url', default=None)

        owner_profile_url = url_or_none(microformats.get('ownerProfileUrl'))  # @a6211d2

        # Uploader refers to the /user/ id ONLY
        uploader_id = (
            id_from_url(owner_profile_url, 'user')
            or id_from_url(upch_url, 'user')
            or ytcfg.get('VIDEO_USERNAME'))
        uploader_url = f'https://www.youtube.com/user/{uploader_id}' if uploader_id else None

        # TODO: sort out what uploader means
        uploader = (
            self._search_regex(
                [r'<a\s*id=\"watch-username\".*\">\s*<strong[^>]?>([^<]+)</strong>',
                 r'var\s*watchUsername\s*=\s*\'(.+)\';',  # ~May 2009
                 r'<div\s*\bid=\"watch-channel-stats\"[^>]*>\s*<a[^>]*>\s*(.+?)\s*</a',  # ~May 2009
                 r'<a\s*id=\"watch-userbanner\"[^>]*title=\"\s*(.+?)\s*\"'],  # ~June 2012
                webpage, 'uploader', default=None)
            or self._html_search_regex(
                [r'(?s)<div\s*class=\"yt-user-info\".*?<a[^>]*[^>]*>\s*(.*?)\s*<\/a',  # March 2016
                 r'(?s)<a[^>]*yt-user-name[^>]*>\s*(.*?)\s*<\/a'],  # july 2013

Review comment (suggestion):
```suggestion
        _CHANNEL_URL_HREF_RE = r'href="[^"]*(?P<url>https?://www\.youtube\.com/(?:user|channel)/[^"]+)"'
```

Code after:

        initial_data_video = traverse_obj(
            initial_data, ('contents', 'twoColumnWatchNextResults', 'results', 'results', 'contents', ..., 'videoPrimaryInfoRenderer'),
            expected_type=dict, get_all=False, default={})

        video_details = traverse_obj(
            player_response, 'videoDetails', expected_type=dict, get_all=False, default={})

        microformats = traverse_obj(
            player_response, ('microformat', 'playerMicroformatRenderer'), expected_type=dict, get_all=False, default={})

        video_title = (
            video_details.get('title')
            or YoutubeBaseInfoExtractor._get_text(microformats, 'title')
            or YoutubeBaseInfoExtractor._get_text(initial_data_video, 'title')
            or traverse_obj(player_config, ('args', 'title'))
            or self._extract_webpage_title(webpage)
            or search_meta(['og:title', 'twitter:title', 'title']))

        def id_from_url(url, type_):
            return self._search_regex(
                rf'(?:{type_})/([^/#&?]+)', url or '', f'{type_} id', default=None)

        # XXX: would the get_elements_by_... functions be better suited here?
        _CHANNEL_URL_HREF_RE = r'href="[^"]*(?P<url>https?://www\.youtube\.com/(?:user|channel)/[^"]+)"'
        uploader_or_channel_url = self._search_regex(
            [fr'<(?:link\s*itemprop=\"url\"|a\s*id=\"watch-username\").*?\b{_CHANNEL_URL_HREF_RE}>',  # @fd05024
             fr'<div\s*id=\"(?:watch-channel-stats|watch-headline-user-info)\"[^>]*>\s*<a[^>]*\b{_CHANNEL_URL_HREF_RE}'],  # ~ May 2009, ~June 2012
            webpage, 'uploader or channel url', default=None)

        owner_profile_url = url_or_none(microformats.get('ownerProfileUrl'))  # @a6211d2

        # Uploader refers to the /user/ id ONLY
        uploader_id = (
            id_from_url(owner_profile_url, 'user')
            or id_from_url(uploader_or_channel_url, 'user')
            or ytcfg.get('VIDEO_USERNAME'))
        uploader_url = f'https://www.youtube.com/user/{uploader_id}' if uploader_id else None

        # XXX: do we want to differentiate uploader and channel?
        uploader = (
            self._search_regex(
                [r'<a\s*id="watch-username"[^>]*>\s*<strong>([^<]+)</strong>',  # June 2010
                 r'var\s*watchUsername\s*=\s*\'(.+?)\';',  # ~May 2009
                 r'<div\s*\bid=\"watch-channel-stats"[^>]*>\s*<a[^>]*>\s*(.+?)\s*</a',  # ~May 2009
                 r'<a\s*id="watch-userbanner"[^>]*title="\s*(.+?)\s*"'],  # ~June 2012
                webpage, 'uploader', default=None)
            or self._html_search_regex(
                [r'(?s)<div\s*class="yt-user-info".*?<a[^>]*[^>]*>\s*(.*?)\s*</a',  # March 2016
                 r'(?s)<a[^>]*yt-user-name[^>]*>\s*(.*?)\s*</a'],  # july 2013
                get_element_by_id('watch7-user-header', webpage), 'uploader', default=None)