如果频道有自定义url,如何使用Youtube数据API获取Youtube频道的详细信息



我想获取一个有自定义URL的YouTube频道的详细信息,比如https://www.youtube.com/c/pratiksinhchudasamaisawesome.

自定义频道URL遵循以下格式:https://www.youtube.com/c/{custom_channel_name}

我可以通过频道ID和用户名获取YouTube频道的详细信息,而不会出现任何问题。不幸的是,我需要使用自定义频道URL,这是我唯一一次遇到这个问题。

我几个月前开发了我的应用程序,直到几天前,自定义频道URL还在运行。现在,如果我尝试使用YouTube自定义频道的名称获取详细信息,则YouTube数据API不会返回YouTube自定义频道URL的任何内容。

要获取此频道的详细信息,请执行以下操作:https://www.youtube.com/user/thenewboston例如,请求是:

GET https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=thenewboston&key={YOUR_API_KEY}

响应

200
- SHOW HEADERS -
{
 "kind": "youtube#channelListResponse",
 "etag": ""zekp1FB4kTkkM-rWc1qIAAt-BWc/8Dz6-vPu69KX3yZxVCT3-M9YWQA"",
 "pageInfo": {
  "totalResults": 1,
  "resultsPerPage": 5
 },
 "items": [
  {
   "kind": "youtube#channel",
   "etag": ""zekp1FB4kTkkM-rWc1qIAAt-BWc/KlQLDlUPRAmACwKt9V8V2yrOfEg"",
   "id": "UCJbPGzawDH1njbqV-D5HqKw",
   "snippet": {
    "title": "thenewboston",
    "description": "Tons of sweet computer related tutorials and some other awesome videos too!",
    "publishedAt": "2008-02-04T16:09:31.000Z",
    "thumbnails": {
     "default": {
      "url": "https://yt3.ggpht.com/--n5ELY2uT-U/AAAAAAAAAAI/AAAAAAAAAAA/d9JvaIEpstw/s88-c-k-no-rj-c0xffffff/photo.jpg"
     },
     "medium": {
      "url": "https://yt3.ggpht.com/--n5ELY2uT-U/AAAAAAAAAAI/AAAAAAAAAAA/d9JvaIEpstw/s240-c-k-no-rj-c0xffffff/photo.jpg"
     },
     "high": {
      "url": "https://yt3.ggpht.com/--n5ELY2uT-U/AAAAAAAAAAI/AAAAAAAAAAA/d9JvaIEpstw/s240-c-k-no-rj-c0xffffff/photo.jpg"
     }
    },
    "localized": {
     "title": "thenewboston",
     "description": "Tons of sweet computer related tutorials and some other awesome videos too!"
    }
   }
  }
 ]
}

它工作得很好。

现在我们必须获得这些通道的详细信息:

  • https://www.youtube.com/c/eretteretlenek
  • https://www.youtube.com/c/annacavalli

然后我们得到:

GET https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=annacavalli&key={YOUR_API_KEY}

响应

200
- SHOW HEADERS -
{
 "kind": "youtube#channelListResponse",
 "etag": ""zekp1FB4kTkkM-rWc1qIAAt-BWc/TAiG4jjJ-NTZu7gPKn7WGmuaZb8"",
 "pageInfo": {
  "totalResults": 0,
  "resultsPerPage": 5
 },
 "items": [
 ]
}

这可以使用API资源管理器轻松复制。

仅使用API的最简单的解决方案是仅使用YouTube Data API的搜索:列表方法。据我所知(请注意,这是我自己的研究,官方文档对这个主题只字未提!),如果你使用自定义URL组件进行搜索,并使用"通道"结果类型过滤器和"相关性"(默认)排序,第一个结果应该是你想要的结果。

因此,下面的查询得到16个结果,其中第一个是您要查找的结果。我测试的所有其他自定义频道URL也是如此,所以我认为这是最可靠的方法。

GET https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&q=annacavalli&type=channel&key={YOUR_API_KEY}

另一个想法是在自定义URL上抓取YouTube页面,在那里你可以在HTML代码中的一个元标签中找到ChannelID。但这是无效的、不可靠的,而且AFAIK违反了YouTube的使用条款。

编辑:嗯,对于较小的频道,它不会返回任何结果,所以它根本不可靠。

解决方案

在@jkondratowicz答案的基础上展开,将search.listchannels.list结合使用,大多数情况下您可以从自定义url值解析通道。

通道资源具有属性customUrl,因此,如果我们从search.list结果中获取通道,并从channels.list中获取有关它们的额外详细信息,则可以尝试将自定义url值与customUrl属性进行匹配。

这里是一个有效的JavaScript方法,只需将api密钥替换为您自己的。尽管它仍然不完美,但这尝试了返回的前50个通道。使用分页和pageTokens可以做更多的工作。

function getChannel(customValue, callback) {
    const API_KEY = "your_api_key"
    $.ajax({
        dataType: "json",
        type: "GET",
        url: "https://www.googleapis.com/youtube/v3/search",
        data: {
            key: API_KEY,
            part: "snippet",
            q: customValue,
            maxResults: 50,
            order: 'relevance',
            type: 'channel'
        }
    }).done(function (res) {
        const channelIds = [];
        for (let i=0; i<res.items.length; i++) {
            channelIds.push(res.items[i].id.channelId);
        }
        $.ajax({
            dataType: "json",
            type: "GET",
            url: "https://www.googleapis.com/youtube/v3/channels",
            data: {
                key: API_KEY,
                part: "snippet",
                id: channelIds.join(","),
                maxResults: 50
            }
        }).done(function (res) {
            if (res.items) {
                for (let i=0; i<res.items.length; i++) {
                    const item = res.items[i];
                    if (item.snippet.hasOwnProperty("customUrl") && customValue.toLowerCase() === item.snippet.customUrl.toLowerCase()) {
                        callback(item);
                    }
                }
            }
        }).fail(function (err) {
            logger.err(err);
        });
    }).fail(function (err) {
        logger.err(err);
    });
}

使用它的一个很好的例子https://www.youtube.com/c/creatoracademy.

getChannel('creatoracademy', function (channel) {
    console.log(channel);
});

然而,它仍然是不可靠的,因为它取决于信道是否在原始search.list查询中返回。如果自定义通道url过于通用,那么实际通道可能不会返回到search.list结果中。尽管这种方法比依赖search.list的第一个条目更可靠,因为搜索结果并不总是以相同的顺序返回。

问题

在过去的一年里,谷歌至少收到了三个功能请求,要求为这个自定义url值添加一个额外的参数,但都被拒绝了,因为这是不可行的。显然,实施起来太难了。也有人提到它不在他们的路线图上。

  • https://issuetracker.google.com/issues/174903934(2020年12月)
  • https://issuetracker.google.com/issues/165676622(2020年8月)
  • https://issuetracker.google.com/issues/161718177(2020年7月)

资源

  • 谷歌:了解您的频道URL
  • 搜索:列表| YouTube数据API
  • 频道:列表| YouTube数据API

另一种方法是使用解析器(PHP Simple HTLM DOM解析器,例如:PHP Simple HTML DOM解析器):

<?php
$media_url = 'https://www.youtube.com/c/[Channel name]';
$dom = new simple_html_dom();
$html = $dom->load(curl_get($media_url));
if (null !== ($html->find('meta[itemprop=channelId]',0))) {
    $channelId = $html->find('meta[itemprop=channelId]',0)->content;
}
?>

(使用Youtube api的"搜索"方法的配额成本为100)

通过视频ID获取频道ID是可能的,这取决于您的应用程序的需要。

下面是一个例子:

        $queryParams = [
            'id' => 'UcDjWCEvZLM'
        ];
        $response = $service->videos->listVideos('snippet', $queryParams)->getItems();
        $channelId = $response[0]->snippet['channelId'];
        $channelTitle = $response[0]->snippet['channelTitle'];

我假设只有频道所有者上传了视频的频道才会感兴趣。这是意外的方便,因为我的方法无论如何都不适用于0个视频频道。

给定一个频道的url,我的方法将获得该频道视频选项卡的beautuloup HTML对象,并抓取HTML以找到唯一的频道id。然后它将重建所有内容,并返回具有唯一频道id的频道url。

your_channel_url = 'Enter your channel url here'
channel_url = your_channel_url.strip("https://").strip("featured")
https = "https://"
channel_vids_tab = https + channel_url + '/videos'
import requests
from bs4 import BeautifulSoup
source = requests.get(channel_vids_tab).text
soup = BeautifulSoup(source, "html.parser")
a = soup.find('body').find('link')['href']
channel_id = a.split('/')[-1]
print(a)
print(channel_id)

该方法绕过了具有不同/user/curl(例如/user/vechz和/c/vechz与/c/coreyms和/user/schafer5导致相同页面)的一个通道的头痛。尽管一开始你需要手动输入url,但它可以很容易地自动化。

我也很有信心,如果一个频道有0个视频,这种思路也适用于频道所有者创建的播放列表,只需要稍作调整。但如果频道创建了0个视频或播放列表。。。谁知道

正如@jkondratowicz所指出的,没有办法从API可靠地获得这一点,因为小通道不会返回到搜索结果的顶部。

因此,这里有一个JS示例,说明如何通过从HTML频道页面中提取频道id(h/t@Feign'):

export const getChannelIdForCustomUrl = async (customUrl: string) => {
  const page = await axios.get(`https://www.youtube.com/c/${customUrl}`)
  const chanId = page.data.match(/channelId":"(.*?)"/)[1]
  return chanId
}

这是。NET方法,使用已接受的答案中提到的搜索API将自定义频道名称/URL转换为ChannelId。

        // https://www.youtube.com/c/TheQ_original/videos
        // they call custom URL ?
        // https://stackoverflow.com/questions/37267324/how-to-get-youtube-channel-details-using-youtube-data-api-if-channel-has-custom
        // https://developers.google.com/youtube/v3/docs/channels#snippet.customUrl
        // GET https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&q=annacavalli&type=channel&key={YOUR_API_KEY}
        // 
        /// <summary>
        /// Returns ChannelID from old "Custom Channel Name/URL"
        /// Support the following URLs format
        /// https://www.youtube.com/c/MakeYourOWNCreation
        /// </summary>
        /// <param name="ChannelName"></param>
        /// <returns></returns>
        // 20220701
        public async Task<string> CustomChannelNameToChannelId(String ChannelName)
        {
            var YoutubeService = YouTubeService();
            //
            List<YouTubeInfo> VideoInfos = new List<YouTubeInfo>();
            // 
            // -) Step1: Retrieve 1st page of channels info
            var SearchListRequest = YoutubeService.Search.List("snippet");
            SearchListRequest.Q = ChannelName;
            SearchListRequest.Type = "channel";
            //
            SearchListRequest.MaxResults = 50;
            // Call the search.list method to retrieve results matching the specified query term.
            var SearchListResponse = await SearchListRequest.ExecuteAsync();
            // According to the SO post the custom channel will be the first one
            var searchResult = SearchListResponse.Items[0];
            //
            // Return Channel Information, we care to obtain ChannelID
            return searchResult.Id.ChannelId;
        }

相关内容

  • 没有找到相关文章

最新更新