用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函数式编程
Jun 09 Python
Python多线程编程(五):死锁的形成
Apr 05 Python
python 爬取微信文章
Jan 30 Python
Python实现二叉树结构与进行二叉树遍历的方法详解
May 24 Python
django2用iframe标签完成网页内嵌播放b站视频功能
Jun 20 Python
python中比较两个列表的实例方法
Jul 04 Python
Python字符串大小写转换拼接删除空白
Sep 19 Python
python给图像加上mask,并提取mask区域实例
Jan 19 Python
TensorFlow自定义损失函数来预测商品销售量
Feb 05 Python
Python3自定义http/https请求拦截mitmproxy脚本实例
May 11 Python
如何在python中实现ECDSA你知道吗
Nov 23 Python
浅析Python OpenCV三种滤镜效果
Apr 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+mysql分页代码详解
2008/03/27 PHP
php获取服务器信息的实现代码
2013/02/04 PHP
如何让搜索引擎抓取AJAX内容解决方案
2014/08/25 PHP
探究Laravel使用env函数读取环境变量为null的问题
2016/12/06 PHP
PHP未登录自动跳转到登录页面
2016/12/21 PHP
php获取当前url地址的方法小结
2017/01/10 PHP
Laravel框架中Blade模板的用法示例
2017/08/30 PHP
thinkphp5 migrate数据库迁移工具
2018/02/20 PHP
Laravel框架集合用法实例浅析
2020/05/14 PHP
向fckeditor编辑器插入指定代码的方法
2007/05/25 Javascript
超酷的网页音乐播放器DewPlayer使用方法
2010/12/18 Javascript
EasyUI的treegrid组件动态加载数据问题的解决办法
2011/12/11 Javascript
js实现jquery的offset()方法实例
2015/01/10 Javascript
jquery实现简单的无缝滚动
2015/04/15 Javascript
JS实时弹出新消息提示框并有提示音响起的实现代码
2016/04/20 Javascript
JavaScript制作简易计算器(不用eval)
2017/02/05 Javascript
JavaScript函数表达式详解及实例
2017/05/05 Javascript
浅谈Node Inspector 代理实现
2017/10/19 Javascript
分析JS中this引发的bug
2017/12/12 Javascript
Vue项目引进ElementUI组件的方法
2018/11/11 Javascript
微信小程序中的店铺评分组件及vue中用svg实现的评分显示组件
2018/11/16 Javascript
Javascript之高级数组API的使用实例
2019/03/08 Javascript
微信小程序封装分享与分销功能过程解析
2019/08/13 Javascript
Django forms表单 select下拉框的传值实例
2019/07/19 Python
Python协程 yield与协程greenlet简单用法示例
2019/11/22 Python
增大python字体的方法步骤
2020/07/05 Python
css3.0 图形构成实例练习一
2013/03/19 HTML / CSS
纯css3制作的火影忍者写轮眼开眼至轮回眼及进化过程实例
2014/11/11 HTML / CSS
介绍一些UNIX常用简单命令
2014/11/11 面试题
Servlet如何得到服务器的信息
2015/12/22 面试题
餐厅总经理岗位职责
2013/12/31 职场文书
高中政治教学反思
2014/01/18 职场文书
2014年新农村建设工作总结
2014/12/01 职场文书
幼儿园食品安全责任书
2015/05/08 职场文书
聊一聊python常用的编程模块
2021/05/14 Python
Win11查看设备管理器
2022/04/19 数码科技