我想获取一个有自定义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.list
与channels.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
和/c
url(例如/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;
}