【kimol君的无聊小发明】—用python写视频下载器

本文介绍了如何使用Python爬虫搜索并下载好看视频的详细步骤,包括解析搜索请求、获取视频源地址和多线程下载视频。通过实例代码展示了从分析网络请求到实现功能的全过程。

【kimol君的无聊小发明】—用python写视频下载器

Tip:本文仅供学习与参考,且勿用作不法用途~

前言

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

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

一、爬虫分析

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

https://haokan.baidu.com

1.视频搜索

进入主页后,我们可以看到一个搜索框历历在目:
在这里插入图片描述
当我们点击搜索按钮之后,会出现与关键字(ps.这里要考,大家仔细看😋)相匹配的视频,我们需要做的便是抓包来分析其中的请求数据。

关于抓包工具,可以选择三方工具(如Fiddler或者Burpsuit等),当然也可以选择浏览器自带的调试工具(在浏览器中按F12即可打开)。
在这里我选择了后者,打开F12调试工具,选择网络:
在这里插入图片描述
在点击搜索按钮之后我们可以看到相应的网络请求出现在下面的工具框中:
在这里插入图片描述
通过简单的查找之后我们可以很容易地发现对应的搜索请求(红框标出部分),其对应的地址为:

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调试工具中点击右侧的响应便可以看到请求的响应:
在这里插入图片描述
很显然,这里返回的是一个HTML格式的数据,我们只需要通过re库或是bs4库等将我们需要的数据提取出来即可。至此,关于视频搜索的分析基本算是完成了。
然而!细心的小伙伴会发现,我们现在可以获得搜索结果,但是没办法选择页面呀。对嚯~那咋办呀?

同样,我们继续抓包分析不就可以了嘛~ 我倒要看看你是怎么翻页的。果然,下滑鼠标之后我们得到了新的请求:
在这里插入图片描述
其请求地址变为了:

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的参数来指向的相应视频。
在这里插入图片描述
右键视频播放页面查看源码(或者通过右键视频检查元素也可),我们可以找到视频播放的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))
    

运行代码,可以看到小频频全都来到我的碗里了😍~
在这里插入图片描述

写在最后

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

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

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

创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 (๑◕ܫ←๑)

评论 101
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值