用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的面向对象编程方式学习笔记
Jul 12 Python
Python实现删除时保留特定文件夹和文件的示例
Apr 27 Python
python散点图实例之随机漫步
Aug 27 Python
对python pandas读取剪贴板内容的方法详解
Jan 24 Python
python3+PyQt5 自定义窗口部件--使用窗口部件样式表的方法
Jun 26 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
Aug 26 Python
Python函数参数类型及排序原理总结
Dec 19 Python
Django Path转换器自定义及正则代码实例
May 29 Python
python 利用Pyinstaller打包Web项目
Oct 23 Python
Python调用JavaScript代码的方法
Oct 27 Python
python 逐步回归算法
Apr 06 Python
python中对列表的删除和添加方法详解
Feb 24 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执行速度全攻略
2006/10/09 PHP
smarty 原来也不过如此~~呵呵
2006/11/25 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(九)
2014/06/24 PHP
CMSPRESS 10行代码搞定 PHP无限级分类2
2018/03/30 PHP
PHP中检查isset()和!empty()函数的必要性
2019/02/13 PHP
jQuery实现ichat在线客服插件
2014/12/29 Javascript
NodeJS中Buffer模块详解
2015/01/07 NodeJs
浅谈被jQuery抛弃的函数及替代函数
2015/05/03 Javascript
JS实现字符串转日期并比较大小实例分析
2015/12/09 Javascript
Bootstrap开发实战之第一次接触Bootstrap
2016/06/02 Javascript
Vue表单实例代码
2016/09/05 Javascript
AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】
2016/11/02 Javascript
js中创建对象的几种方式
2017/02/05 Javascript
搭建element-ui的Vue前端工程操作实例
2018/02/23 Javascript
JavaScript同源策略和跨域访问实例详解
2018/04/03 Javascript
jQuery实现百度图片移入移出内容提示框上下左右移动的效果
2018/06/05 jQuery
浅谈js闭包理解
2019/03/28 Javascript
JS实现动态添加外部js、css到head标签的方法
2019/06/05 Javascript
Bootstrap FileInput实现图片上传功能
2021/01/28 Javascript
Python牛刀小试密码爆破
2011/02/03 Python
使用Python的Flask框架来搭建第一个Web应用程序
2016/06/04 Python
Python安装Numpy和matplotlib的方法(推荐)
2017/11/02 Python
python实现操作文件(文件夹)
2019/10/31 Python
python3 实现函数写文件路径的正确方法
2019/11/27 Python
基于Python中random.sample()的替代方案
2020/05/23 Python
CSS3实现缺角矩形,折角矩形以及缺角边框
2019/12/20 HTML / CSS
html5配合css3实现带提示文字的输入框(摆脱js)
2013/03/08 HTML / CSS
英国最大的宠物食品和宠物用品网上零售商: Zooplus
2016/08/01 全球购物
Made in Design德国:设计师家具、灯具和装饰
2019/10/31 全球购物
加拿大拼图大师:Puzzle Master
2020/12/28 全球购物
2014村务公开实施方案
2014/02/25 职场文书
婚宴邀请函
2015/01/30 职场文书
病人慰问信范文
2015/02/15 职场文书
幼儿教师辞职信
2015/02/27 职场文书
实习证明模板
2015/06/16 职场文书
2019年鼓励无偿献血倡议书
2019/09/17 职场文书