实践六:防盗链知识点——视频

一、打开li视频在抓包工具中可以找到对应的视频链接,但是页面源代码却不行

这是因为页面源代码是 "服务器返回的初始模板",抓包工具里的 "源代码" 是 "包含动态渲染 + 所有依赖资源" 的完整集合 。因为视频数据是JS 通过异步接口动态加载

过程是:

  1. 浏览器加载 视频页的 "页面源代码"(只有页面的 HTML 框架,没有具体视频数据);

  2. 页面中的 JS 执行,发送异步请求(比如 https://www.pearvideo.com/videoStatus.jspcontId=1802157&mrd=0.6347927921664064)到服务器;

  3. 服务器返回视频数据(JSON 格式);

  4. JS 把 JSON 数据解析后,插入到 DOM 结构中(Elements 面板能看到插入后的视频链接标签)。

二、通过抓包工具找到js异步接口

其中的video_image是视频的封面图片地址,而最后的strurl则是视频的链接地址,但是我们可以发现,这个地址是被修改过的,正确的地址应该是video.pearvideo.com/mp4/short/20250901/cont-1802157-16060480-hd.mp4,这是因为服务器接口返回的是 "不完整的视频 URL 片段",需要前端 JavaScript(JS)结合页面中的 "视频 ID"(contId)进行动态拼接,才能生成最终可播放的完整 URL------ 这是视频网站常见的 "反爬 + URL 动态生成" 机制,目的是防止直接通过接口抓取完整视频地址。

复制代码
import requests

#因为li视频的视频地址是动态的,需要根据contID来构造
url="https://www.pearvideo.com/video_1802157"
contID=url.split("_")[-1]

videourl=f"https://www.pearvideo.com/videoStatus.jsp?contId={contID}&mrd=0.6347927921664064"

三、通过js异步接口爬取视频链接的 "核心逻辑代码"

但因为缺少关键请求头(Referer),目前被服务器的防盗链机制拦截了。所以需要结合防盗链机制Referer 的验证作用来分析。

li视频的 videoStatus.jsp 接口(用于获取视频真实地址)设置了Referer 校验 ,属于 "防盗链" 的一种变形 ------防止外部爬虫 / 网站直接调用该接口,仅允许 "从li视频自身页面发起的请求" 访问。

  • 当你不添加 Referer 时,服务器会认为这个请求是 "外部非法调用"(比如来自爬虫脚本、其他网站的接口请求),于是返回 "该文章已经下线" 的虚假提示(实际是反爬拦截);

  • 当你添加 Referer 并设置为视频的原始页面(https://www.pearvideo.com/video_1802157)时,服务器会认为这个请求是 "用户从li视频页面正常点击发起的",从而返回真实的视频信息。

Referer 在这里的 "角色":

Referer 是请求头的核心字段之一,作用是告诉服务器 "当前请求是从哪个页面跳转 / 发起的"

在这个案例中,li视频通过 Referer 做了以下验证:

  • 服务器检查请求的 Referer 是否以 https://www.pearvideo.com/ 开头(即请求是否来自li视频自身的页面);

  • 只有通过这个校验,才会返回真实的视频数据;否则直接拦截(返回虚假的 "文章下线" 提示)。

这里的机制属于接口级别的防盗链(防止接口被外部盗用),和之前讲的 "资源防盗链"(防止图片 / 视频被外部引用)逻辑一致,只是保护的对象从 "静态资源" 变成了 "接口数据"。

  • 防盗链的目的:限制只有 "合法来源"(自己的页面 / 域名)才能访问资源 / 接口;

  • Referer 的作用 :作为 "合法来源" 的验证凭证,让服务器判断请求是否来自允许的页面。

这样修改后,服务器会认为请求是 "从li视频自身页面发起的",从而返回真实的视频信息,绕过接口的防盗链拦截。

四、添加referer请求头,告诉服务器 "当前请求是从哪个页面跳转 / 发起的",就可以爬取视频链接所在异步接口的内容

其中,Referer 大多数情况下确实是 "上一级链接的网址"(即发起当前请求的 "来源页面 URL")

五、替换 "不完整的视频 URL 片段",前端 JavaScript(JS)结合页面中的 "视频 ID"(contId)进行动态拼接,生成最终完整 URL

所以最后的video.pearvideo.com/mp4/short/20250901/cont-1802157-16060480-hd.mp4便是完整的URL

六、下载视频

最后也是爬取成功

七:总结

整体过程可以概况成下面步骤:

一、找到需要爬取的视频,发现是动态渲染,刷新页面,在抓包工具网络XHR中找到视频加载的js异步接口

二、通过这个异步工具的网址来爬取这个接口的源代码(还需添加referer来绕过防盗链拦截),在其中找到被替换的"虚假URL",使用contID来替换便是真正的URL

三、找到真正的视频URL后,便可以下载视频了

完整代码:

复制代码
import requests

#因为;li视频的视频地址是动态的,需要根据contID来构造
url="https://www.pearvideo.com/video_1802157"
contID=url.split("_")[-1]

videourl=f"https://www.pearvideo.com/videoStatus.jsp?contId={contID}&mrd=0.6347927921664064"  #js异步接口地址

headers={
    "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
    ,"Referer":url}   #添加referer来绕过防盗链拦截,告诉服务器 “当前请求是从哪个页面跳转 / 发起的”
resp=requests.get(videourl,headers=headers)   #发送get请求,获取异步接口的源代码

dic=resp.json()   #该异步接口的源代码
strurl=dic["videoInfo"]["videos"]["srcUrl"]  #因为返回的是json字符串,需要用json()方法解析
systemTime=dic["systemTime"]
strurl=strurl.replace(systemTime,f"cont-{contID}")

#下载视频
with open("video.mp4","wb") as f:  #wb表示二进制写入模式,因为视频是二进制数据,所以需要用二进制写入模式
    f.write(requests.get(strurl,headers=headers).content)  #content属性表示响应的二进制数据,需要用content属性来获取二进制数据
相关推荐
戴草帽的大z2 小时前
使用V4L2工具验证RK3588平台视频设备节点数据有效性
ffmpeg·音视频·rk3588·nv12·v4l2-ctl
音视频牛哥3 小时前
从 RTSP/RTP/RTCP 到系统级时间闭环:跨平台低延迟RTSP播放架构解析
计算机视觉·机器人·音视频·rtsp播放器·linux rtsp播放器·windows rtsp播放器·安卓播放rtsp流
电子科技圈3 小时前
XMOS与飞腾云联袂以模块化方案大幅加速音频产品落地
经验分享·嵌入式硬件·mcu·自然语言处理·音视频·腾讯会议·游戏机
美摄科技3 小时前
H5短视频SDK,赋能Web端视频创作革命
前端·音视频
Tracy9733 小时前
XMSRC4194_VC1:4通道192KHz ASRC音频采样率转换器产品介绍
嵌入式硬件·音视频·智能硬件·xmos模组固件
xinxinhenmeihao7 小时前
爬虫导致IP被封号了如何解封?
爬虫·网络协议·tcp/ip
EasyCVR16 小时前
智能守护校园:视频汇聚平台EasyCVR如何构建校园消防安全新防线
音视频
加油20191 天前
音视频处理(三):hls协议和m3u8详解和视频下载爬虫实战
爬虫·音视频·hls·m3u8·mpeg-2·mpeg2-ts·电视迷
音视频牛哥1 天前
从 SmartMediaKit 设计探讨音视频工程师的面试与能力评估框架
程序人生·职场和发展·音视频·rtsp播放器·rtmp播放器·音视频工程师面试·音视频程序员面试题