用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使用MySQLdb for Python操作数据库教程
Oct 11 Python
深入理解python中的浅拷贝和深拷贝
May 30 Python
Python脚本实现12306火车票查询系统
Sep 30 Python
Python排序搜索基本算法之冒泡排序实例分析
Dec 09 Python
Python无损音乐搜索引擎实现代码
Feb 02 Python
Python 利用scrapy爬虫通过短短50行代码下载整站短视频
Oct 29 Python
详解pandas使用drop_duplicates去除DataFrame重复项参数
Aug 01 Python
Django用户认证系统 User对象解析
Aug 02 Python
Python 合并多个TXT文件并统计词频的实现
Aug 23 Python
Python中的相关分析correlation analysis的实现
Aug 29 Python
python-视频分帧&amp;多帧合成视频实例
Dec 10 Python
解决Jupyter-notebook不弹出默认浏览器的问题
Mar 30 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
WindowsXP中快速配置Apache+PHP5+Mysql
2008/06/05 PHP
PHP 获取MSN好友列表的代码(2009-05-14测试通过)
2009/09/09 PHP
php遍历解析xml字符串的方法
2016/05/05 PHP
简单的pgsql pdo php操作类实现代码
2016/08/25 PHP
PHP中的empty、isset、isnull的区别与使用实例
2019/03/22 PHP
IE下双击checkbox反应延迟问题的解决方法
2014/03/27 Javascript
JS实现向表格中动态添加行的方法
2015/03/30 Javascript
Bootstrap3使用typeahead插件实现自动补全功能
2016/07/07 Javascript
详解js中==与===的区别
2017/01/08 Javascript
微信通过页面(H5)直接打开本地app的解决方法
2017/09/09 Javascript
JS加密插件CryptoJS实现AES加密操作示例
2018/08/16 Javascript
小程序Request的另类用法详解
2019/08/09 Javascript
JS如何判断对象是否包含某个属性
2020/08/29 Javascript
JavaScript判断数据类型有几种方法及区别介绍
2020/09/02 Javascript
React 条件渲染最佳实践小结(7种)
2020/09/27 Javascript
[47:20]DAC2018 4.4 淘汰赛 Optic vs Mineski 第一场
2018/04/05 DOTA
Python字符遍历的艺术
2008/09/06 Python
Python读写Redis数据库操作示例
2014/03/18 Python
Python抓取京东图书评论数据
2014/08/31 Python
详解Python的Lambda函数与排序
2016/10/25 Python
Python的SimpleHTTPServer模块用处及使用方法简介
2018/01/22 Python
关于Tensorflow中的tf.train.batch函数的使用
2018/04/24 Python
Python实现按逗号分隔列表的方法
2018/10/23 Python
Python list列表中删除多个重复元素操作示例
2019/02/27 Python
python groupby 函数 as_index详解
2019/12/16 Python
在pytorch 中计算精度、回归率、F1 score等指标的实例
2020/01/18 Python
python mysql中in参数化说明
2020/06/05 Python
pycharm 实现调试窗口恢复
2021/02/05 Python
html5通过canvas实现刮刮卡效果示例分享
2014/01/27 HTML / CSS
Desigual德国官网:在线购买原创服装
2018/03/27 全球购物
元旦晚会邀请函
2014/02/01 职场文书
法学院毕业生求职信
2014/06/25 职场文书
辞职申请书范本
2019/05/20 职场文书
小程序后台PHP版本部署运行 LNMP+WNMP
2021/04/01 Servers
Java移除无效括号的方法实现
2021/08/07 Java/Android
vue 给数组添加新对象并赋值
2022/04/20 Vue.js