用python制作个视频下载器


Posted in Python onFebruary 01, 2021

前言

某个夜深人静的夜晚,夜微凉风微扬,月光照进我的书房~
当我打开文件夹以回顾往事之余,惊现许多看似杂乱的无聊代码。我拍腿正坐,一个想法油然而生:“生活已然很无聊,不如再无聊些叭”。
于是,我决定开一个专题,便称之为kimol君的无聊小发明。
妙…啊~~~

众所周知,视频是一个学习新姿势知识的良好媒介。那么,如何利用爬虫更加方便快捷地下载视频呢?本文将从数据包分析到代码实现来进行一个相对完整的讲解。

一、爬虫分析

本次选取的目标视频网站为某度旗下的好看视频:

https://haokan.baidu.com

1.视频搜索

进入主页后,我们可以看到一个搜索框历历在目:

用python制作个视频下载器

当我们点击搜索按钮之后,会出现与关键字(ps.这里要考,大家仔细看?)相匹配的视频,我们需要做的便是抓包来分析其中的请求数据。

关于抓包工具,可以选择三方工具(如Fiddler或者Burpsuit等),当然也可以选择浏览器自带的调试工具(在浏览器中按F12即可打开)。
在这里我选择了后者,打开F12调试工具,选择网络:

用python制作个视频下载器

在点击搜索按钮之后我们可以看到相应的网络请求出现在下面的工具框中:

用python制作个视频下载器

通过简单的查找之后我们可以很容易地发现对应的搜索请求(红框标出部分),其对应的地址为:

https://haokan.baidu.com/videoui/page/search?query=kimol君666

那么,我们通过requests库来模拟该请求,便可实现搜索视频的功能:

import requests
res = requests.get('https://haokan.baidu.com/videoui/page/search?query=xxxxx')# xxxxx表示你需要搜索的关键字

注:这里不需要用到请求头headers,但是不能一概而论。是否需要请求头要根据具体网站分析哦~

你没有看错,我只用了2行代码便实现了视频网站的搜索功能。有时候,爬虫就是这么简单?!
在得到请求后,接下来我们要对这个请求返回的数据进行分析,同样是在F12调试工具中点击右侧的响应便可以看到请求的响应:

用python制作个视频下载器

很显然,这里返回的是一个HTML格式的数据,我们只需要通过re库或是bs4库等将我们需要的数据提取出来即可。至此,关于视频搜索的分析基本算是完成了。
然而!细心的小伙伴会发现,我们现在可以获得搜索结果,但是没办法选择页面呀。对嚯~那咋办呀?

同样,我们继续抓包分析不就可以了嘛~ 我倒要看看你是怎么翻页的。果然,下滑鼠标之后我们得到了新的请求:

用python制作个视频下载器

其请求地址变为了:

https://haokan.baidu.com/videoui/page/search?pn=2&rn=10&_format=json&tab=video&query=kimol君666

请求多了pn、rn、_format、tab等参数,而且请求返回的格式也变为了JSON格式(岂不美哉?更方便提取想要的数据了)。通过简单测试可以知道,这些参数分别代表:

参数 说明
pn 请求的页码
rn 每次请求返回的数据量
_format 请求返回的数据格式
tab 请求的标签类型

那么,相应的代码可以改为:

import requests
page = 1
keyword = 'xxxxx' # xxxxx为搜索的关键字
url = 'https://haokan.baidu.com/videoui/page/search?pn=%d&rn=10&_format=json&tab=video&query=%s'%(page,keyword)
res = requests.get(url)
data = res.json()

至此,视频搜索部分的分析算是告于段落了。

2.视频下载

视频下载的思路也很清晰,只需进入播放视频的界面找到相应的视频原文件地址即可。
小手一点,我们便进到了一个视频的播放界面,我们可以发现其URL很有规律:它通过一个vid的参数来指向的相应视频。

用python制作个视频下载器

右键视频播放页面查看源码(或者通过右键视频检查元素也可),我们可以找到视频播放的src,其对应的正则表达式为:

p = '<video class="video" src=(.*?)>'

那么,我们可以定义一个函数来解析视频的原文件地址:

def get_videoUrl(vid):
 '''
 提取视频信息中的视频源地址
 '''
 res = requests.get('https://haokan.baidu.com/v?vid=%s'%vid)
 html = res.text
 videoUrl = re.findall('<video class="video" src=(.*?)>',html)[0]
 return videoUrl

输入视频的id参数,将返回视频的真正文件地址。有了视频的地址,要下载视频便是信手拈来:

def download_video(vid):
 '''
 下载视频文件
 '''
 savePath = 'xxxxx.mp4' # 定义存储的文件名
 videoUrl = get_videoUrl(vid) # 获取视频下载地址 
 res = requests.get(videoUrl)
 with open(savePath,'wb') as f:
 f.write(res.content)

至此,我们已经可以根据关键字搜索相关的视频,并且可以把视频下载到本地了。这也意味着:关于本次视频下载爬虫的介绍也就结束了,剩下的就是根据自己实际需求对代码进行包装即可。

二、我的代码

这里提供一个我自己的代码,仅供参考:

# =============================================================================
# 好看视频_v0.1
# =============================================================================
import re
import os
import time
import queue
import requests
import threading
import pandas as pd

class Haokan:
 def __init__(self):
 self.url = 'https://haokan.baidu.com/videoui/page/search?pn=%d&rn=20&_format=json&tab=video&query=%s'
 self.headers = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0',
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
  'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
  'Connection': 'keep-alive',
  'Upgrade-Insecure-Requests': '1',
  'TE': 'Trailers',
 }
 self.savaPath = './videos' # 视频存储路径
 
 def get_info(self,keywords,page):
 '''
 搜索关键字,获取相关视频信息
 '''
 self.result = [] # 相关视频信息
 for p in range(1,page+1):
  res = requests.get(self.url%(p,keywords),headers=self.headers)
  data = res.json()['data']['response']
  videos = data['list']
  self.result.extend(videos)
  print('"第%d页"爬取完成!'%(p+1))
 self.result = pd.DataFrame(self.result)
 self.result.to_excel('%s.xlsx'%keywords,index=False)
 # 定义队列,用于多线程下载视频
 self.url_queue = queue.Queue() 
 for vid,url in zip(self.result['vid'],self.result['url']):
  self.url_queue.put((vid,url))
 
 def get_videoUrl(self,url):
 '''
 提取视频信息中的视频源地址
 '''
 res = requests.get(url,headers=self.headers)
 html = res.text
 videoUrl = re.findall('<video class="video" src=(.*?)>',html)[0]
 return videoUrl
 
 def download_video(self,videoId,videoUrl):
 '''
 下载视频文件
 '''
 # 如果视频存储目录不存在则创建
 if not os.path.exists(self.savaPath):
  os.mkdir(self.savaPath)
 res = requests.get(videoUrl,headers=self.headers)
 with open('%s/%s.mp4'%(self.savaPath,videoId),'wb') as f:
  f.write(res.content)
  
 def run(self):
 while not self.url_queue.empty():
  t_s = time.time()
  vid,url = self.url_queue.get()
  try:
  video_url = self.get_videoUrl(url)
  self.download_video(vid,video_url)
  except:
  print('"%s.mp4"下载失败!'%vid)
  continue
  t_e = time.time()
  print('"%s.mp4"下载完成!(用时%.2fs)'%(vid,t_e-t_s))
  
if __name__ == "__main__":
 keywords = '多啦A梦'
 page = 1 # 爬取页数,每页20条信息
 t_s = time.time()
 haokan = Haokan()
 haokan.get_info(keywords,page)
 N_thread = 3 # 线程数
 thread_list = []
 for i in range(N_thread):
 thread_list.append(threading.Thread(target=haokan.run))
 for t in thread_list:
 t.start()
 for t in thread_list:
 t.join()
 t_e = time.time()
 print('任务完成!(用时%.2fs)'%(t_e-t_s))

运行代码,可以看到小频频全都来到我的碗里了?~

用python制作个视频下载器

写在最后

今天分享的视频下载算是最基础的了,它宛如一位慈祥的老奶奶,慈眉善目,面带笑容。它没有各种繁琐的反爬机制(甚至连headers都不进行验证),而且数据返回的格式也是极其友好的,就连视频格式也显得如此的温柔。

我相信在“她”的陪伴下,我们可以走好学习爬虫的第一步。纵使日后我们还将面临IP验证、参数验证、验证码、行为检测、瑞数系统等等诸多反爬考验,也许还需应对视频格式转换等挑战。
但是,请记住kimol君将始终陪伴在你们身边~

最后,感谢各位大大的耐心阅读,咋们下次再会~

以上就是用python制作个视频下载器的详细内容,更多关于python 制作视频下载器的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
基于Python os模块常用命令介绍
Nov 03 Python
python实现对求解最长回文子串的动态规划算法
Jun 02 Python
详解用Python实现自动化监控远程服务器
May 18 Python
Pycharm保存不能自动同步到远程服务器的解决方法
Jun 27 Python
Django单元测试工具test client使用详解
Aug 02 Python
Python实现元素等待代码实例
Nov 11 Python
python实现二分类的卡方分箱示例
Nov 22 Python
opencv python如何实现图像二值化
Feb 03 Python
Python unittest装饰器实现原理及代码
Sep 08 Python
Python实现石头剪刀布游戏
Jan 20 Python
python 实现的车牌识别项目
Jan 25 Python
Python下opencv库的安装过程及问题汇总
Jun 11 Python
python基于pexpect库自动获取日志信息
Feb 01 #Python
Python入门基础之数字字符串与列表
Feb 01 #Python
Pyecharts 中Geo函数常用参数的用法说明
Feb 01 #Python
Python+MySQL随机试卷及答案生成程序的示例代码
Feb 01 #Python
python实现代码审查自动回复消息
Feb 01 #Python
anaconda安装pytorch1.7.1和torchvision0.8.2的方法(亲测可用)
Feb 01 #Python
python 列表推导和生成器表达式的使用
Feb 01 #Python
You might like
PHP_Flame(Version:Progress)的原代码
2006/10/09 PHP
PHP中fwrite与file_put_contents性能测试代码
2013/08/02 PHP
Ubuntu中搭建Nginx、PHP环境最简单的方法
2015/03/05 PHP
PHP实现中文圆形印章特效
2015/06/19 PHP
php 获取文件行数的方法总结
2016/10/11 PHP
thinkPHP5.0框架事务处理操作简单示例
2018/09/07 PHP
PHP CURL实现模拟登陆并上传文件操作示例
2020/01/02 PHP
phpcmsv9.0任意文件上传漏洞解析
2020/10/20 PHP
ExtJS 简介 让你知道extjs是什么
2008/12/29 Javascript
img onload事件绑定各浏览器均可执行
2012/12/19 Javascript
js 判断文件类型并控制表单提交示例代码
2013/11/14 Javascript
jQuery form插件的使用之处理server返回的JSON, XML,HTML数据
2016/01/26 Javascript
基于JS实现横线提示输入验证码随验证码输入消失(js验证码的实现)
2016/10/27 Javascript
基于BootStrap与jQuery.validate实现表单提交校验功能
2016/12/22 Javascript
基于JS实现仿百度百家主页的轮播图效果
2017/03/06 Javascript
从0到1构建vueSSR项目之路由的构建
2019/03/07 Javascript
详解在React-Native中持久化redux数据
2019/05/22 Javascript
layUI实现列表查询功能
2019/07/27 Javascript
vue 中url 链接左边的小图标更改问题
2019/12/30 Javascript
解决VUEX的mapState/...mapState等取值问题
2020/07/24 Javascript
[01:35]2018年度CS GO最佳战队-完美盛典
2018/12/17 DOTA
Python简单实现子网掩码转换的方法
2016/04/13 Python
PyQt5利用QPainter绘制各种图形的实例
2017/10/19 Python
用Python实现大文本文件切割的方法
2019/01/12 Python
Pytorch抽取网络层的Feature Map(Vgg)实例
2019/08/20 Python
TensorFlow学习之分布式的TensorFlow运行环境
2020/02/05 Python
Python中qutip用法示例详解
2020/10/02 Python
Python+OpenCV图像处理——实现直线检测
2020/10/23 Python
Python 多进程、多线程效率对比
2020/11/19 Python
css3实现input输入框颜色渐变发光效果代码
2014/04/02 HTML / CSS
英国领先的办公用品供应商:Viking
2016/08/01 全球购物
巴西购物网站:Onofre Agora
2020/06/08 全球购物
授权委托书范本
2014/04/03 职场文书
食品安全承诺书范文
2014/08/29 职场文书
写给老师的保证书
2015/05/09 职场文书
2015年度内部审计工作总结
2015/05/20 职场文书