截至 4 天前,您可以向 https://video.google.com/timedtext?lang=en&v={youtubeVideoId} 发送 GET 请求或访问
并收到包含字幕轨道的 xml 响应给定 youtube 视频。有谁知道此支持是否已被删除,因为从今晚开始,它不再提供带有字幕的 xml 响应,每个视频的页面都是空的。有许多视频在 4 天前还有效,但现在不再有效。预先感谢默认语言的字幕(单一可用或似乎是英语):
要获取 YouTube 视频的字幕,只需使用此 Linux 命令(使用curl 和 base64):
curl -s 'https://www.youtube.com/youtubei/v1/get_transcript?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8' -H 'Content-Type: application/json' --data-raw "{\"context\":{\"client\":{\"clientName\":\"WEB\",\"clientVersion\":\"2.9999099\"}},\"params\":\"$(printf '\n\x0bVIDEO_ID' | base64)\"}"
将
VIDEO_ID
参数更改为您感兴趣的参数。
注意:该密钥不是 YouTube Data API v3 密钥,它是第一个公开的密钥(在不同国家/地区的某些计算机上进行了测试),如果您
curl https://www.youtube.com/ | grep AIzaSy
注意:如果对我如何逆向工程这个 YouTube 功能感兴趣,请在评论中说出,我会写一段话来解释
所需语言的字幕(如果有):
YouTube 让事情变得棘手,可能会在这一步失去你,所以跟着我:我们唯一需要改变的是
params
值,它是 base64 编码数据,除了奇怪的字符之外还包含 base64 数据,其中也包含奇怪的数据角色。获取语言首字母,例如俄语的
ru
将
\n\x00\x12\x02LANGUAGE_INITIALS\x1a\x00
编码为 base64,例如
A=$(printf '\n\x00\x12\x02LANGUAGE_INITIALS\x1a\x00' | base64)
(例如,不要忘记将
LANGUAGE_INITIALS
更改为您想要的语言首字母缩写
ru
)。
ru
的结果是
CgASAnJ1GgA=
将结果编码为 URL,例如将
=
替换为
%3D
,例如
B=$(printf %s $A | jq -sRr @uri)
。
ru
的结果是
CgASAnJ1GgA%3D
将单个
%
替换为两个
%
,例如
C=$(echo $B | sed 's/%/%%/')
。
ru
的结果是
CgASAnJ1GgA%%3D
对
\n\x0bVIDEO_ID\x12\x0e$C
进行编码(不要忘记将
VIDEO_ID
更改为您的视频 ID,其中
$C
是上一步的结果),例如
D=$(printf "\n\x0bVIDEO_ID\x12\x0e$C" | base64)
。
ru
和
lo0X2ZdElQ4
的结果是
CgtsbzBYMlpkRWxRNBIOQ2dBU0FuSjFHZ0ElM0Q=
使用默认语言的字幕部分中的
params
值:
curl -s 'https://www.youtube.com/youtubei/v1/get_transcript?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8' -H 'Content-Type: application/json' --data-raw "{\"context\":{\"client\":{\"clientName\":\"WEB\",\"clientVersion\":\"2.2021111\"}},\"params\":\"$D\"}"
这是一个单行版本(不要忘记更改
$VIDEO_ID
和
$LANGUAGE_INITIALS
):curl -s 'https://www.youtube.com/youtubei/v1/get_transcript?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8' -H 'Content-Type: application/json' --data-raw "{\"context\":{\"client\":{\"clientName\":\"WEB\",\"clientVersion\":\"2.2021111\"}},\"params\":\"`printf "\n\x0b$VIDEO_ID\x12\x0e\`printf "\n\x00\x12\x02$LANGUAGE_INITIALS\x1a\x00" | base64 -w 0 | jq -sRr @uri | sed 's/%/%%/g'\`" | base64`\"}"
围绕字幕的 YouTube API 更改给我带来了很多麻烦,我通过使用 youtube-dl 规避了这些麻烦,它已经赢得了 GitHub 法律支持
,现在再次可供下载/克隆。该软件可作为所有主要平台的源代码或二进制文件下载,详细信息请参见其 GitHub 页面,上面链接。
示例使用就是这么简单:
youtube-dl --write-sub --sub-lang en --skip-download --sub-format vtt https://www.youtube.com/watch?v=E-lZ8lCG7WY
我建议任何使用Python的人尝试一下youtube_transcript_api模块。我曾经向 https://video.google.com/timedtext?lang=en&v={videoId}
发送 GET 请求,但现在页面是空白的。以下是代码示例。另外,这个方法不需要api key。from youtube_transcript_api import YouTubeTranscriptApi
srt = YouTubeTranscriptApi.get_transcript("videoId",languages=['en'])
这是 Benjamin Loison 提供的 CURL 答案的 Python 实现。将
ZhT6BeHNmvo
替换为您的视频 ID。
import base64
import json
import requests
base64_string = base64.b64encode("\n\vZhT6BeHNmvo".encode("utf-8")).decode("utf-8")
headers = {
"Content-Type": "application/json",
}
body = json.dumps(
{
"context": {"client": {"clientName": "WEB", "clientVersion": "2.9999099"}},
"params": base64_string,
}
)
response = requests.post(
"https://www.youtube.com/youtubei/v1/get_transcript?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
headers=headers,
data=body,
)
print(response.text)
旧 API 目前对每个请求都会返回 404。 YouTube 现在使用此 API 的新版本:
这个API的主要问题是计算请求的
signature
字段。不幸的是我找不到它的算法。也许有人可以从 YouTube 播放器对其进行逆向工程。