网页视频抓取脚本(学vue.js在线观看不能倍速播放播放播放)
优采云 发布时间: 2022-03-07 14:03网页视频抓取脚本(学vue.js在线观看不能倍速播放播放播放)
写在前面
最近在学习vue.js,在网站上看了很多视频教程,但是网上不能双速播放,所以想着用python爬虫下载到本地.
安装依赖
pip3 安装请求
测试示例
除序言外共有16个视频,我们使用python爬虫技术批量下载到本地。
#/?vid=0
获取直接链接
首先,我们需要获取视频的直接下载链接。右键查看,可以直接看到视频的直接链接。
再次查看页面源代码,发现视频的直接链接没有了,视频的直接链接原来的位置变成了js脚本。
如果我们直接使用requets库请求url,会得到源码,但是源码中并没有直接的视频链接,所以需要考虑另一种思路。为什么视频直连的位置被js代替了?
如果你有更多的爬虫,你就会知道这是网页的动态加载。必须有保存视频直接链接的js文件,然后每次网页加载时,通过js脚本中间将视频的直接链接动态加载到html中。
点击网络,过滤js文件,找到3个js文件。我们先看看第一个js文件中是否有视频直连。搜索视频的标题,直接找到视频的直接链接,发现视频的所有直接链接都保存到了一个名为lesson_list的变量中。
Lesson_list 存储所有视频名称和视频直接链接信息。为统一起见,序言改为第0节。
# course_list.py
课程列表 = [{
"name": "第0节vue.js介绍",
“网址”:“”,
“问”:“77367”
},{
"name": "第1节安装部署",
“网址”:“”,
“问”:“77369”
},{
"name": "第2节创建第一个vue应用",
“网址”:“”,
“问”:“77370”
},{
"name": "Section 3 Data and Methods",
“网址”:“”,
“问”:“77372”
},{
"name": "Section 4 Lifecycle",
“网址”:“”,
“问”:“77373”
},{
"name": "Section 5 Template Syntax - Interpolation",
“网址”:“”,
“问”:“77375”
},{
"name": "Section 6 Template Syntax - Directives",
“网址”:“”,
“问”:“77376”
},{
"name": "Section 7 类和样式绑定",
“网址”:“”,
“问”:“77377”
},{
"name": "Section 8 条件渲染",
“网址”:“”,
“问”:“77378”
},{
"name": "Section 9 列表渲染",
“网址”:“”,
“问”:“77380”
},{
"name": "Section 10 事件绑定",
“网址”:“”,
“问”:“77381”
},{
"name": "Section 11 表单输入绑定",
“网址”:“”,
“问”:“77382”
},{
"name": "Section 12 组件基础",
“网址”:“”,
“问”:“77383”
},{
"name": "Section 13 组件注册",
“网址”:“”,
“问”:“78520”
},{
"name": "Section 14 Single-File Components",
“网址”:“”,
“问”:“78521”
},{
"name": "第15节Vue应用的无终端开发",
“网址”:“”,
“问”:“81004”
}]
批量下载
这里使用for循环遍历每个下载链接,然后使用之前写的多线程下载器进行下载。
从 concurrent.futures 导入 ThreadPoolExecutor
从课程列表导入课程列表
from requests import get, head
*敏*感*词*时间
类下载器:
def __init__(self, url, num, name):
self.url=url
self.num = 数字
self.name = 名字
self.getsize = 0
r = head(self.url, allow_redirects=True)
self.size = int(r.headers['Content-Length'])
def down(self, start, end, chunk_size=10240):
headers = {'range': f'bytes={start}-{end}'}
r = get(self.url, headers=headers, stream=True)
with open(self.name, "rb+") as f:
f.seek(开始)
对于 r.iter_content(chunk_size) 中的块:
f.write(块)
self.getsize += chunk_size
定义主(自我):
start_time = time.time()
f = open(self.name, 'wb')
f.truncate(self.size)
f.close()
tp = ThreadPoolExecutor(max_workers=self.num)
期货 = []
开始 = 0
for i in range(self.num):
end = int((i+1)/self.num*self.size)
future = tp.submit(self.down, start, end)
futures.append(未来)
开始=结束+1
当真时:
进程 = self.getsize/self.size*100
last = self.getsize
时间.sleep(1)
curr = self.getsize
down = (curr-last)/1024
如果下降 > 1024:
速度 = f'{down/1024:6.2f}MB/s'
其他:
速度 = f'{down:6.2f}KB/s'
print(f'process: {process:6.2f}% | speed: {speed}', end='\r')
如果进程 >= 100:
print(f'进程: {100.00:6}% | 速度: 00.00KB/s', end=' | ')
休息
end_time = time.time()
total_time = end_time-start_time
平均速度 = self.size/total_time/1024/1024
print(f'总时间:{total_time:.0f}s | 平均速度:{average_speed:.2f}MB/s')
如果 __name__ == '__main__':
对于课程列表中的课程:
url = 课程['url']
name = 课程['name']
down = downloader(url, 8, name+'.mp4')
down.main()
结果打印
16个视频,共339MB,下载耗时56s。
进程:100.0% |速度:00.00KB/s |总时间:2s |平均速度:2.47MB/s
进程:100.0% |速度:00.00KB/s |总时间:3s |平均速度:6.62MB/s
进程:100.0% |速度:00.00KB/s |总时间:3s |平均速度:3.72MB/s
进程:100.0% |速度:00.00KB/s |总时间:4s |平均速度:7.72MB/s
进程:100.0% |速度:00.00KB/s |总时间:4s |平均速度:5.85MB/s
进程:100.0% |速度:00.00KB/s |总时间:7s |平均速度:7.01MB/s
进程:100.0% |速度:00.00KB/s |总时间:3s |平均速度:4.65MB/s
进程:100.0% |速度:00.00KB/s |总时间:4s |平均速度:6.69MB/s
进程:100.0% |速度:00.00KB/s |总时间:3s |平均速度:5.88MB/s
进程:100.0% |速度:00.00KB/s |总时间:4s |平均速度:5.01MB/s
进程:100.0% |速度:00.00KB/s |总时间:3s |平均速度:6.60MB/s
进程:100.0% |速度:00.00KB/s |总时间:4s |平均速度:6.20MB/s
进程:100.0% |速度:00.00KB/s |总时间:3s |平均速度:5.96MB/s
进程:100.0% |速度:00.00KB/s |总时间:2s |平均速度:4.64MB/s
进程:100.0% |速度:00.00KB/s |总时间:3s |平均速度:6.02MB/s
进程:100.0% |速度:00.00KB/s |总时间:4s |平均速度:6.80MB/s
总结与展望
有时视频或图片的直接链接不一定需要爬取,可能在网页加载的js文件中找到。既然可以直接找到,为什么还要爬呢?那么下载的时候一定要使用多线程,因为多线程可以占用全部带宽来实现全速下载。
引用参考文献
本文分享CSDN - Xavier Jiezou。