Obtaining a channel id from a youtube.com/c/xxxx link?
Asked Answered
G

2

2

It seems Youtube has gotten rid of /channel/XXXX urls on their page, its now /c/username? with username NOT really being a "username". For example

https://www.youtube.com/c/lukemiani

Running a lookup via

https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=lukemiani&key=...

returns no results.

I've got a bunch of non-technical users who've been trained to look for /channel/x or /user/x and input the correct thing into my app. Now that /channel is gone how do I (or they) translate /c/x to a channel id?

I'm looking for an API solution, not a view source and reverse engineer code solution.

Gipsy answered 23/7, 2020 at 3:57 Comment(9)
That doesn't apply. The lookup I included above does that.Gipsy
Yes, it does apply! Just try: wget -qO- --content-on-error "$URL"|grep UC3c8H4Tlnm5M6pXsVMGnmNg, where URL="https://www.googleapis.com/youtube/v3/search?key=$APP_KEY&q=lukemiani&type=channel".Robson
Where are you running that? Because A, it won't even run on Ubuntu or OSX and B the result from YouTube is 10000 search results of a whole bunch of channels. How am I supposed to know which is the correct one?Gipsy
If you have a Windows machine then try this: curl -S -s -o- "https://www.googleapis.com/youtube/v3/search?key=$APP_KEY&q=lukemiani&type=channel&maxResults=1", replacing $APP_KEY with your API key. This should work also on Ubuntu (if not, just install the basic curl package). I'm suprised that that command failed on Ubuntu: wget is standard on stock GNU/Linux machines.Robson
UC3c8H4Tlnm5M6pXsVMGnmNg is the ID of lukemiani's YouTube channel.Robson
Indeed wget is installed by default on Ubuntu. For example, for Focal Fossa, see its manifest file. Other releases at releases.ubuntu.com.Robson
# lsb_release -d Description: Ubuntu 18.04.1 LTS # wget -qO- --content-on-error "$URL"|grep UC3c8H4Tlnm5M6pXsVMGnmNg, where URL="https://www.googleapis.com/youtube/v3/search?key=xxx&q=lukemiani&type=channel" grep: where: No such file or directory grep: URL=https://www.googleapis.com/youtube/v3/search?key=xxx&q=lukemiani&type=channel: No such file or directoryGipsy
and I know UC3c8H4Tlnm5M6pXsVMGnmNg is the channel id BUT that is the value I need. So how can I grep for something that I dont know yet?Gipsy
For those who come across this after the latest Data API revision (31st January, 2024), they provided the forHandle query parameter to get data of a handle/username. You can refer to this answer for details here: https://mcmap.net/q/102620/-youtube-listchannels-with-username-forusername-is-not-workingAmphetamine
R
8

According to the official support staff, a given channel may have associated an URL of form:

https://www.youtube.com/c/CUSTOM_NAME.

In such a case, the respective channel's customUrl property is CUSTOM_NAME.

Now, your problem may be reformulated as follows:

Given a CUSTOM_NAME for which the URL above points to an existing channel, is there a procedure that is able to produce -- by making use of YouTube Data API -- that channel's ID, such that the respective procedure to be DTOS-compliant (i.e. the procedure works by not scraping the HTML text obtained from the respective custom URL)?

The short answer to the above question is no, there's none. (Please have a look at my answer and the attached comments I gave recently to a similar question).

The longer answer would be the following: yes, it can be imagined an algorithm that solves the problem, but only partially (since there's no guarantee that it'll always give positive results).

Here is the algorithm:

  1. Call the Search.list API endpoint with the following parameters:
    • q=CUSTOM_NAME,
    • type=channel, and
    • maxResults=10.
  2. Extract from the result set obtained the channel IDs (these IDs are located at items[].id.channelId);
  3. For each channel ID in the list obtained at step 2:
    1. Invoke Channels.list API endpoint for to obtain the channel's associated customUrl property (if any);
    2. If the obtained customUrl is equal with CUSTOM_NAME, then stop the algorithm yielding the current channel ID; otherwise, continue executing the current loop;
  4. Stop the algorithm by yielding channel ID not found.

Due to the fuzzy nature of the result sets provided by the Search.list endpoint, one cannot exclude the possibility that there could actually exist custom URLs (i.e. URLs of the form above that are pointing to existing channels) for which this algorithm is not able to yield the ID of the associated channel.

A final note: the Channels.list endpoint accepts its id parameter to be a comma-separated list of channel IDs. Therefore, one may easily modify the algorithm above such that instead of N invocations (N <= 10) of Channels.list endpoint to have only one.


An implementation of the algorithm above in Python language, using Google's APIs Client Library for Python:

def find_channel_by_custom_url(
        youtube, custom_url, max_results = 10):
    resp = youtube.search().list(
        q = custom_url,
        part = 'id',
        type = 'channel',
        fields = 'items(id(kind,channelId))',
        maxResults = max_results
    ).execute()
    assert len(resp['items']) <= max_results

    ch = []
    for item in resp['items']:
        assert item['id']['kind'] == 'youtube#channel'
        ch.append(item['id']['channelId'])

    if not len(ch):
        return None

    resp = youtube.channels().list(
        id = ','.join(ch),
        part = 'id,snippet',
        fields = 'items(id,snippet(customUrl))',
        maxResults = len(ch)
    ).execute()
    assert len(resp['items']) <= len(ch)
    
    for item in resp['items']:
        url = item['snippet'].get('customUrl')
        if url is not None and \
            caseless_equal(url, custom_url):
            assert item['id'] is not None
            return item['id']

    return None

where the function caseless_equal used above is due to this SO answer.

I posted here a simple Python3 script that encompasses the function find_channel_by_custom_url above into a standalone program. Your custom URL applied to this script yields the expected result:

$ python3 youtube-search.py \
--custom-url lukemiani \
--app-key ...
UC3c8H4Tlnm5M6pXsVMGnmNg

$ python3 youtube-search.py \
--user-name lukemiani \
--app-key ...
youtube-search.py: error: user name "lukemiani": no associated channel found

Note that you have to pass to this script your application key as argument to the command line option --app-key (use --help for brief help info).

Robson answered 24/7, 2020 at 20:40 Comment(4)
I wonder why this answer is not yet marked as correct. I successfully implemented my script by following your answer. Thank you very much @RobsonSanction
Thank you, @aslamdoctor. I have quite a series of answers that are based on this very post (and code) of mine (just enter any of the two terms in SO search box: user:8327971 custom URL or user:8327971 forusername). In my SO experience, users rarely accept and vote answers that contradict their opinions (even if the respective answers only assert factual things, like quoting official docs and bringing in valid counter-examples).Robson
Agree with you on this.Sanction
And still this is weird. You can get username for 1 cost, but channel for 100? wat?Vow
R
1

You can do that in python, or with any http request library, by requesting the link and parsing the response for the channel ID. The channel id is in the canonical link tag that handles the redirection:

import requests
import re

url = "https://www.youtube.com/shroud"
r = requests.get(url, allow_redirects=True)
print(re.search(r'(?<=<link rel="canonical" href="https:\/\/www\.youtube\.com\/channel\/)(-?\w+)*(?=">)', r.text).group(0)) 

# Returns UCoz3Kpu5lv-ALhR4h9bDvcw
Rahal answered 18/4, 2021 at 13:7 Comment(1)
Unfortunately, your answer is misdirected, since the OP was looking for an YouTube Data API solution; that is he deliberately wants to avoid scraping the HTML page of the channel(s) in question (which is against DTOS, section III.E.6, Scraping).Robson

© 2022 - 2024 — McMap. All rights reserved.