【问题标题】:Obtaining a channel id from a youtube.com/c/xxxx link?从 youtube.com/c/xxxx 链接获取频道 ID?
【发布时间】:2020-11-12 17:33:40
【问题描述】:

似乎 Youtube 已经摆脱了他们页面上的 /channel/XXXX 网址,现在是 /c/username?用户名不是真正的“用户名”。例如

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

通过以下方式运行查找

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

不返回任何结果。

我有一群非技术用户,他们经过培训可以查找 /channel/x 或 /user/x 并将正确的内容输入到我的应用程序中。现在 /channel 已经消失了,我(或他们)如何将 /c/x 转换为频道 ID?

我正在寻找 API 解决方案,而不是查看源代码和逆向工程代码解决方案。

【问题讨论】:

  • 这不适用。我上面包含的查找就是这样做的。
  • 是的,确实适用!试试看:wget -qO- --content-on-error "$URL"|grep UC3c8H4Tlnm5M6pXsVMGnmNgURL="https://www.googleapis.com/youtube/v3/search?key=$APP_KEY&q=lukemiani&type=channel"
  • 你在哪里运行它?因为 A,它甚至不会在 Ubuntu 或 OSX 上运行,而 B 来自 YouTube 的结果是一大堆频道的 10000 个搜索结果。我怎么知道哪个是正确的?
  • 如果你有一台 Windows 机器,那么试试这个:curl -S -s -o- "https://www.googleapis.com/youtube/v3/search?key=$APP_KEY&q=lukemiani&type=channel&maxResults=1",用你的 API 密钥替换 $APP_KEY。这应该也适用于 Ubuntu(如果没有,只需安装基本的 curl 包). 我很惊讶该命令在 Ubuntu 上失败:wget 是库存 GNU/Linux 机器上的标准。
  • UC3c8H4Tlnm5M6pXsVMGnmNg 是 lukemiani 的 YouTube 频道的 ID。

标签: youtube-api youtube-data-api


【解决方案1】:

根据official support staff,一个给定的频道可能已经关联了一个如下形式的URL:

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

在这种情况下,相应频道的customUrl 属性为CUSTOM_NAME

现在,您的问题可以重新表述如下:

鉴于上述 URL 指向现有频道的 CUSTOM_NAME,是否有程序能够通过使用 YouTube 数据 API 生成该频道的 ID,使得相应的程序符合DTOS-compliant(即该程序通过不抓取从相应的自定义 URL 获得的 HTML 文本来工作)?

上述问题的简短回答是不,没有。 (请看my answer and the attached comments我最近给了一个类似的问题)。

较长的答案如下:是的,可以想象一种算法可以解决问题,但只是部分解决(因为不能保证它总是会给出积极的结果)。

算法如下:

  1. 使用以下参数调用Search.list API 端点:
    • q=CUSTOM_NAME,
    • type=channel,和
    • maxResults=10
  2. 从结果集中提取通道ID(这些ID位于items[].id.channelId);
  3. 对于在第 2 步获得的列表中的每个频道 ID:
    1. 调用Channels.list API 端点以获取通道关联的customUrl 属性(如果有);
    2. 如果得到的customUrl等于CUSTOM_NAME,则停止算法产生当前频道ID;否则,继续执行当前循环;
  4. 通过产生channel ID not found来停止算法。

由于Search.list 端点提供的结果集的模糊性,我们不能排除这种算法实际上可能存在自定义 URL(即,指向现有频道的上述形式的 URL)的可能性无法生成关联频道的 ID。

最后一点:Channels.list 端点接受其id 参数作为以逗号分隔的频道 ID 列表。因此,可以很容易地修改上面的算法,使得Channels.list 端点的N 调用(N <= 10)只有一个。


使用 Google 的 Python API 客户端库以 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

上面使用的函数caseless_equal是由于this SO answer

我发布了 here 一个简单的 Python3 脚本,其中包含上面的函数 find_channel_by_custom_url 到一个独立的程序中。应用于此脚本的自定义 URL 会产生预期结果:

$ 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

请注意,您必须将您的应用程序密钥作为命令行选项--app-key 的参数传递给此脚本(使用--help 获取简要帮助信息)。

【讨论】:

  • 我想知道为什么这个答案还没有被标记为正确。我按照您的回答成功实现了我的脚本。非常感谢@stvar
  • 谢谢你,@aslamdoctor。我有很多基于我​​的这篇文章(和代码)的答案(只需在 SO 搜索框中输入两个术语中的任何一个:user:8327971 custom URLuser:8327971 forusername)。在我的 SO 经验中,用户很少接受和投票与他们的观点相矛盾的答案(即使各自的答案只是断言事实,比如引用官方文档和引入有效的反例)。
  • 同意你的观点。
【解决方案2】:

您可以在 python 或任何 http 请求库中通过请求链接并解析通道 ID 的响应来执行此操作。频道 ID 位于处理重定向的规范链接标签中:

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

【讨论】:

  • 很遗憾,您的答案是错误的,因为 OP 正在寻找 YouTube 数据 API 解决方案;也就是说,他故意要避免抓取相关频道的 HTML 页面(这违反了DTOS,第 III.E.6 节,抓取)。
猜你喜欢
  • 1970-01-01
  • 2015-05-14
  • 1970-01-01
  • 2013-06-09
  • 1970-01-01
  • 2022-12-12
  • 1970-01-01
相关资源
最近更新 更多