无法抓取 YouTube 视频的隐藏式字幕

Posted

技术标签:

【中文标题】无法抓取 YouTube 视频的隐藏式字幕【英文标题】:Can't scrape YouTube video's closed captions 【发布时间】:2018-06-15 22:57:18 【问题描述】:

我正在尝试为字幕抓取 YouTube 页面。不幸的是,它并没有根据请求加载所有内容。我很想知道我哪里出错了。

查询字符串:

https://www.youtube.com/timedtext_editor?action_mde_edit_form=1&v=Nxb2s2Mv6Pw&lang=en&bl=vmp&forceedit=captions&tab=captions

所以我发现这是唯一的 Url-I.D ...Nxb2s2Mv6Pw,我可以相应地替换它。

如果我运行下面的代码,它不会捕获我需要它定位的标签<textarea yt-uix-form-input-textarea ...>

我极力避免使用 Selenium 来捕获这一点,因为我有很多链接需要遍历并重复该过程。从下面的代码可以看出,我尝试加入延迟时间来等待页面加载,但没有。

import os
import codecs
import sys
import requests
from bs4 import BeautifulSoup

channel = 'https://www.youtube.com/timedtext_editor?action_mde_edit_form=1&v=dto4koj5DTA&lang=en'
s = requests.Session()
time.sleep(5)
# s.headers['User-Agent'] = USER_AGENT
r = s.get(channel)
time.sleep(5)
html = r.text
soup = BeautifulSoup(html, 'lxml')

for i in soup.find_all('div'):
    print(i)

请指教。

【问题讨论】:

Session() 之后不需要睡觉。当客户端不使用 javascript(并且 User-Agent 不正确)时,服务器可能会发送不同的页面(具有不同的标签和类)。因此,您可以在 Web 浏览器中关闭 JavaScript 并加载页面以查看您可以在 BS 中获得什么。或者获取 r.text 并保存在文件中并在文本编辑器或网络浏览器中打开 - 看看你得到了什么。 @furas 嘿!谢谢您的意见。是的,这里是一个漫长的夜晚,因为现在是凌晨 3 点,我发现它太晚了。我正在使用 Jupyter 笔记本,并且一直在通过 r.text 监视所有内容,以查看进来的内容,但它没有获取我需要的内容。但我得到了答案。再次感谢您! 【参考方案1】:

我尝试使用requestslxml 抓取页面,但是在迭代脚本中的标签时,我在页面上找不到任何字幕(字幕所在的 textarea 标记没有显示在脚本中) 这可能是因为 YouTube 使用 javascript 来加载字幕。

Python 的请求库不支持 javascript。但是,您确实有几个选择:

使用 selenium 来抓取字幕(你说过你宁愿不这样做。)

通过浏览器查看 POST 和 GET 请求,并尝试将所需的请求参数发送到您跟踪 javascript 到的 url(如果身份验证或动态令牌用于参数,则可能并不总是有效)

使用youtube-dl下载字幕。

(这似乎是解决此问题的最简单/最可靠的方法。)

youtube-dl是一个命令行工具,但你也可以根据github上的文档导入。

有几种方法可以解决这个问题。我将使用您在帖子中指向的视频作为示例:

youtube-dl --write-sub --skip-download --sub-lang en https://www.youtube.com/watch?v=Nxb2s2Mv6Pw

话虽如此,您可以在python中创建一个函数来调用命令:

import os

def download_subs(video_url, lang="en"):
    cmd = [
        "youtube-dl",
        "--skip-download",
        "--write-sub",
        "--sub-lang",
        lang,
        video_url
    ]

    os.system(" ".join(cmd))


url = "https://www.youtube.com/watch?v=Nxb2s2Mv6Pw"

download_subs(url)

或者,您可以直接从 python 导入 youtube_dl 并从那里使用它:

import youtube_dl

def download_subs(url, lang="en"):
    opts = 
        "skip_download": True,
        "writesubtitles": "%(name)s.vtt",
        "subtitlelangs": lang
    

    with youtube_dl.YoutubeDL(opts) as yt:
        yt.download([url])

url = "https://www.youtube.com/watch?v=Nxb2s2Mv6Pw"
download_subs(url)

这会在工作目录中创建一个名为

的文件
CNN 'Exposed' In Controversial Secret Video and Anita Sarkeesian's 'Punishment'...-Nxb2s2Mv6Pw.en.vtt

文件的内容如下所示:

WEBVTT
Kind: captions
Language: en

00:00:00.000 --> 00:00:01.500
You beautiful bastards

00:00:01.500 --> 00:00:07.200
Hope you having a fantastic Tuesday welcome back to the Philip Defranco show and let's just jump into it the first thing

00:00:07.200 --> 00:00:11.519
I want to talk about today one of the most requested stories of the day today is an update on the

00:00:11.889 --> 00:00:13.650
Craziness out of Vidcon yesterday

00:00:13.650 --> 00:00:19.350
Specifically we're talking about creator and panelist Anita Sarkeesian being on a panel calling someone in the crowd

...

...

【讨论】:

不客气。 youtube-dl 是一个很棒的实用程序。我已经使用了一段时间了。如果与正确的命令行参数一起使用,它可以是一个非常强大的应用程序。您可以在命令行参数(以及一般模块的其余部分)上找到相当广泛的文档。HERE。编程愉快!

以上是关于无法抓取 YouTube 视频的隐藏式字幕的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Youtube API v3 中下载隐藏式字幕

通过 YouTube 数据 API [Python] 下载非自有视频的隐藏式字幕

如何抓取 YouTube 视频评论?

通过 URL 强制使用 YouTube 隐藏式字幕

YouTube API v3 中的隐藏式字幕

HTML5 的 Youtube 隐藏式字幕不起作用