首页 > 其他分享 >爬虫案例之 xxx 视频网站

爬虫案例之 xxx 视频网站

时间:2023-05-11 19:24:05浏览次数:67  
标签:视频 m3u8 url self xxx 爬虫 ts 文件 response

爬虫案例之视频爬取与合成

案例网址:https://v6.dious.cc

下载视频的网址:https://www.99meijutt.com/play/97071-0-0.html

  • 用到的知识点
    • asynic,协程异步操作。
    • ffmpeg,合成视频指令
    • aiohttp,在协程里面发送异步请求

【一】分析

(1)分析网站

  • 打开网站首页

  • 打开开发者模式进行抓包

    • 思路:我们已经知道每个视频都是由一个个ts文件片段组成
      • 而这些ts片段的地址就存在m3u8文件中
      • 所以我们现在的主要目标放在m3u8文件中
  • 这里我们找到了第一个m3u8文件,查看其响应内容

  • 我们可以发现,其响应内容中存在类似链接的地址
    • 我们继续往下看到第二个m3u8文件,打开,查看其响应内容

  • 我们可以清楚的看到,其响应内容中存在的就是我们一个个ts文件的链接

(2)准备爬取工作

  • 本次案例使用的是asynic模块
    • 不为别的,就是单纯的下载批量文件图一块!嘎嘎快!

【二】分析完就动手!

(1)导入模块

# 请求头中的headers中的User-Agent模拟
from fake_useragent import UserAgent
# os 系统模块
import os
# 正则表达式模块
import re
# 涉及到加密动作,需要解密模块(本次涉及到的是AES加密)
from Crypto.Cipher import AES
# asynic 异步协程模块
import asyncio
# 协程中的请求模块
import aiohttp

(2)初识化需要用到的全局变量

# 初始化模块
    def __init__(self):
        # 初始化请求头 headers
        self.headers = {
            'User-Agent': UserAgent().random
        }
        # 初始化文件夹名字(存储ts文件)
        self.file_name = 'video'
        # 判断文件夹是否存在(做判断)
        if not os.path.exists(self.file_name):
            os.mkdir(self.file_name)

(3)获取到所有的ts文件的链接

# 这里是请求第一个m3u8文件操作
    async def get_page_url(self):
        # 这是找到的第一个m3u8的网址
        index1_url = 'https://v6.dious.cc/20220428/X2mBsQ9X/index.m3u8'
        # 对上述链接发起请求
        async with aiohttp.ClientSession() as session:
            async with session.get(url=index1_url, headers=self.headers) as response:
                # 拿到第一个m3u8文件里的内容,将下一个m3u8文件地址解析
                page_text = await response.text()  # 这里是文本文件,所以用response.text()
                # 从获取到的文件中解析获得第二个m3u8地址
                index2_url = 'https://v6.dious.cc' + page_text.split('\n')[-2]  # 做字符串拼接成完整的下一个链接
                # 对上述链接发起请求
                async with aiohttp.ClientSession() as session:
                    async with session.get(url=index2_url, headers=self.headers) as response:
                        # 拿到第二个m3u8文件,这里面存的就是所有ts文件的链接地址
                        page_text = await response.text()  # 这里是文本文件,所以用response.text()
                        # 将带有ts地址的m3u8文件写入到本地 - 为下一步的合并做准备
                        # 定义文件路径
                        file_path = f'{self.file_name}' + '\\' + 'index.m3u8'
                        # 打开文件夹
                        with open(file_path, 'w') as f:
                            # 循环获取取到的第二个m3u8文件中的每一个ts文件
                            for line in page_text.split('\n'):
                                # 如果文件中不存在以 .ts 文件为结尾的文件
                                if not line.endswith('.ts'):
                                    # 则直接写入
                                    # 目的是为了合并做准备,ffmpeg合并文件,其中m3u8文件必须带头部,否则会报错
                                    f.write(line + '\n')
                                # 如果文件中存在 .key 结尾的文件,将其头部补充完整
                                elif line.endswith('.key'):
                                    # 拼接成完整的url
                                    f.write('http://v6.dious.cc' + line + '\n')
                                # 如果存在 .ts 为结尾的文件
                                else:
                                    # 将字符串进行分隔,取最后一部分,因为文件名不能存在 / \ 等特殊字符
                                    line = line.split('/')[-1]
                                    f.write(line + '\n')

                        # 将所有的ts文件链接提取出来
                        tss_urls = re.findall(r'(.*.ts)', page_text)
        # 将所有ts文件链接提取出来返回,留待下一部分使用
        return tss_urls

(4)下载所有ts文件

    # 这个部分是下载文件的部分
    async def download_file(self, i, sem):
        '''
        
        :param i: 每一个ts链接
        :param sem: 信号量
        :return: 打印每一个文件的下载情况
        '''
        # 设置并发量  --- 防止异步协程太快,造成timeout
        async with sem:
            # 将每一个ts链接拼接完整
            ts_url = 'https://v6.dious.cc' + i
            # 对每一个ts链接发起请求
            async with aiohttp.ClientSession() as session:
                async with session.get(url=ts_url, headers=self.headers) as response:
                    # 这里请求到的数据是被加密的ts文件数据(视频文件)
                    response_data = await response.read()  # 这里返回的是二进制文件,所以用response.read()
                    # 这里是将每个ts文件的后缀名字取出来,当做每一个文件的名字
                    ts_name = os.path.basename(ts_url)
                    # 通过观察m3u8文件,发现其存在AES加密,这是cbc加密模式所需要的key的链接(在m3u8文件的上方,可以看到有一个key.key的文件,其中存的就是key)
                    key_url = 'https://v6.dious.cc/20220428/X2mBsQ9X/1500kb/hls/key.key'
                    # 对链接发起请求
                    async with aiohttp.ClientSession() as session:
                        async with session.get(url=key_url, headers=self.headers) as response:
                            # 拿到key并存储为二进制数据
                            key = await response.read()  # 这里返回的是二进制文件,所以用response.read()
                            # 这是cbc模式所需要的iv偏移量(文件中没有声明,默认设置为16位的 0 )
                            iv = b'0000000000000000'  # 需要将格式转为二进制模式,才能传到aes参数里面
                            # 创建aes对象
                            aes = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)
                            # 声明文件路径
                            file_path = f'{self.file_name}' + '\\' f'{ts_name}'
                            # 打开文件
                            with open(file_path, 'wb') as f:
                                # 如果需要解密ts视频文件
                                # data = aes.decrypt(response_data)
                                # f.write(data)
                                # 这里采取不解密ts文件
                                f.write(response_data)
                                print(f'{ts_name}已经下载完成')

(5)ffmpeg视频合并命令

# 这里的部分是用来合并ts片段
    async def merge_video(self, filename='video'):
        '''
        
        :param filename: 合成文件的文件名
        :return: 
        '''
        # ffmpeg -i ts文件夹下的m3u8格式文件 -c copy 合成后的视频名字
        # ffmpeg -i index.m3u8 -c copy apple.mp4
        # 切换到ts文件列表
        os.chdir(f'{self.file_name}')
        # 合成文件
        os.system(f'ffmpeg -protocol_whitelist "file,http,crypto,tcp" -i index.m3u8 -c copy {filename}.mp4')

(6)设置协程的主程序入口

    async def main(self):
        # 声明任务列表
        global tasks
        # 创建任务列表
        tasks = []
        # 信号量:控制协程下载的并发量
        sem = asyncio.Semaphore(50)
        # 获取到所有ts链接
        tss_urls = await self.get_page_url()
        # 循环获取到每一个ts链接
        for i in tss_urls:
            # 创建任务,并传入参数,传给下一个函数调用下载
            task = asyncio.create_task(self.download_file(i, sem))
            # 将每一个任务添加到所有的任务中
            tasks.append(task)
        # 收集任务
        await asyncio.wait(tasks)
        # 待所有文件下载完成后进行ts文件合并
        await self.merge_video()

(7)设置文件的主程序入口

if __name__ == '__main__':
    # 实例化类对象
    s = Spider()
    # 调用类对象中的main方法
    # 执行协程启动run函数
    asyncio.run(s.main())

标签:视频,m3u8,url,self,xxx,爬虫,ts,文件,response
From: https://www.cnblogs.com/dream-ze/p/17391972.html

相关文章

  • 【爬虫】记一次某视频网站的加密解密
    1、起因  由于女友想看某网站付money视频,咱又不想充money,所以咱去网络上找在线解析的那种网站,下载下来,让其不用卡顿,不用手动复制黏贴,畅快的看视频 2、首先我们抓取电视剧的所有剧集链接https://so.iqiyi.com/so/ 反正输入视频链接搜索就完了,然后拿到页面的url 然后......
  • 基于python爬虫技术对于淘宝的数据分析的设计与实现
    本篇仅在于交流学习本文主要介绍通过selenium模块和requests模块,同时让机器模拟人在浏览器上的行为,登录指定的网站,通过网站内部的搜索引擎来搜索自己相应的信息,从而获取相应关键字的商品信息,并进而获取数据,然后通过csv模块将数据存储到本地库中,接着在通过pandas、jieba、m......
  • 工业园区的智慧安监方案:AI视频边缘计算技术的应用场景剖析
    一、方案背景 针对工业园区化工企业多且安全及环保等方面存在风险高、隐患多、精细化管控复杂的情况,需要全面整合并优化园区现有基础设施、系统平台等信息化资源,建立园区的智能化风险预警管理平台,利用信息化手段,增强园区安全状态监测预警、风险防控能力,实现园区辅助决策,为园区安......
  • EasyCVR视频融合平台设备管理增加面包屑导航设计
    EasyCVR视频融合平台基于云边端一体化架构,具有强大的数据接入、处理及分发能力,平台支持海量视频汇聚管理,能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频直播、云端录像、云存储、检索回看、智能告警、平台级联、服务器集群、云台控制与语音对讲、......
  • 音频转文字/视频转文字的方法【免费】
    摘自:https://zhuanlan.zhihu.com/p/396228243如果想把音频(mp3)文件一键转成文字或视频文件一键转成文字的话就看看这篇文章,我整理了一下手头的方法,比较简单,而且适合新手。一.录音转文字助手(免费版,最大10M)可以配合mp3分割工具https://www.xunjiepdf.com/audio-to-text这是......
  • ffmpeg合并视频
    先下载个ffmpeg命令行:ffmpeg-fconcat-ifilelist.txt-ccopyout\new.mp4filelis.txt与ffmpeg.exe同一目录, 内容如下:file'F:\Download\【日剧_11集全】\1.EP01-1_Av438702220_P1_.mp4'file'F:\Download\【日剧_11集全】\2.EP01-2_Av438702220_P2_.mp4'file�......
  • Basler相机视频录制
    【安装】先安装Basler_pylon_7.2.1.25747再安装补充包pylon_Supplementary_Package_for_MPEG-4_1.0.1.118可录制mp4格式。【设置】pylonViewer界面——窗口——录制设置录制间隔与播放速度需匹配,否则有慢放或快放效果:录制速度>播放速度,慢放,适合观察高速对象录制速度<播放速......
  • System.InvalidOperationException:“The entity type 'XXXXX' has multiple properti
    一、前言当我使用efcorecodefirst成功生成实体类,然后编写好功能,运行的时候报了这个错误System.InvalidOperationException:“Theentitytype'Student'hasmultiplepropertieswiththe[Key]attribute.Compositeprimarykeyscanonlybesetusing'HasKey'in'OnMo......
  • 视频加字幕怎么制作?视频加字幕软件全分享!​
    视频加字幕怎么制作?视频加字幕是指在视频中添加文字说明或翻译的操作,以便于观众理解和沟通。通过视频加字幕,可以为听障人士、非母语使用者等人群提供更好的观看体验,并且方便用户在不方便听声音的场合下了解视频内容,很多小伙伴想给自己的视频加上一个字幕,却不知道该用什么软件进行,下......
  • MarkDown语法基础详解附带视频链接
    MarkDown语法基础大家如果喜欢的话就收藏或者分享给你的小伙伴把!以下总结的为常见语法,我使用的是Typora破解版,里面有快捷键,讲语法是为了让大家更好的理解大家也可以去看详细视频讲解基础篇视频讲解链接画图篇视频讲解链接标题标题使用方法:#+空格+标题(回车得到标题)标题分为......