如何编写通用Python脚本抓取任意网站的嵌入YouTube视频?
通用化抓取网页中嵌入YouTube视频链接的思路
我编写了一段Python脚本,使用requests_html、re和webbrowser库,抓取指定网页中的嵌入YouTube视频链接并在浏览器打开,仅用于学习。脚本如下:
from requests_html import HTML, HTMLSession import re import webbrowser url = input("website url to launch all embeded videos") if url == '': url = 'https://coreyms.com/' sess = HTMLSession() r = sess.get(url) whole_file = r.text pattern = re.compile(r'https:\/\/www\.youtube\.com\/embed\/(.+)[\?"]') video_ids = pattern.findall(whole_file)
该脚本仅适配部分网站(如coreyms.com、udiscovermusic的某页面),在musicgrotto的页面无法运行。因当前正则匹配规则基于特定网站的HTML结构,我缺乏HTML与Web开发知识,想了解如何将脚本通用化,使其适配任意网站,是否有通用的适配思路?
通用适配思路
1. 基于HTML标签属性定位,替代纯文本正则匹配
不要直接对整个HTML文本做模糊正则匹配,而是依托HTML的结构特征精准定位:
- 嵌入的YouTube视频基本都用
<iframe>标签,其src属性必然包含youtube.com/embed/特征串 - 用
requests_html的CSS选择器或XPath提取目标标签,示例代码:
这种方法遵循HTML规范,不会被页面中无关的文本内容干扰,稳定性远高于纯正则。# 用CSS选择器筛选所有含YouTube embed链接的iframe iframes = r.html.find('iframe[src*="youtube.com/embed/"]') video_links = [iframe.attrs['src'] for iframe in iframes]
2. 处理动态加载的视频内容
很多网站会通过JavaScript动态渲染视频iframe,直接用get请求只能拿到初始静态HTML,看不到动态加载的内容。此时可以用requests_html的render()方法模拟浏览器渲染:
# 触发页面渲染,等待JavaScript加载完成 r.html.render() # 再提取iframe iframes = r.html.find('iframe[src*="youtube.com/embed/"]')
注意:首次调用render()会自动下载Chromium,也可以手动指定本地浏览器路径。
3. 扩展匹配规则,覆盖多类嵌入形式
除了标准的youtube.com/embed/格式,还要兼容其他常见嵌入形式:
- 短链接格式:
youtu.be/xxx - 带参数的播放链接:
youtube.com/watch?v=xxx - 可以用基于视频ID的精准正则,YouTube视频ID固定为11位字符,示例:
# 匹配所有主流的YouTube视频ID格式 pattern = re.compile(r'(?:youtube\.com\/(?:embed\/|watch\?v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})') # 提取ID后拼接成标准embed链接 video_ids = pattern.findall(r.html.html) video_links = [f'https://www.youtube.com/embed/{vid}' for vid in video_ids]
4. 过滤无效与重复链接
提取完成后做简单校验与去重:
- 检查视频ID长度是否为11位,过滤无效值
- 用集合去重,避免重复打开同一视频:
unique_video_links = list(set(video_links))
内容的提问来源于stack exchange,提问作者Antoine Grand
相关产品推荐
相关产品推荐

