爬虫案例七Python协程爬取视频

news2025/3/10 9:06:15

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、Python协程爬取视频


前言

提示:这里可以添加本文要记录的大概内容:

爬虫案例七协程爬取视频


提示:以下是本篇文章正文内容,下面案例可供参考

一、Python协程爬取视频

"""
网址:https://www.tpua.vip/play/84942-1-1.html
目标:爬取视频
"""
import requests
import re
from urllib.parse import urljoin
import aiohttp
import aiofiles
import asyncio
import os
import subprocess
head = {
	"":""#自行添加自己的头
}
def get_m3u8_url():
    url = "https://www.tpua.vip/play/84942-1-1.html"
    session = requests.session()
    session.headers = {
		"":""#自行添加自己的头
    }
    resp = session.get(url)
    obj = re.compile(r'"player":"\\/public\\/","url":"(?P<url>.*?)"')
    m3u8_url = obj.search(resp.text).group("url").replace("\\","")
    print(m3u8_url)
    return m3u8_url

def download_m3u8(url):
    session = requests.session()
    session.headers =  {
		"":""#自行添加自己的头
    }

    m3u8_resp = session.get(url)
    # # 保存m3u8
    with open('index.m3u8',mode="w",encoding='utf-8') as f:
        f.write(m3u8_resp.text)
def has_next_m3u8():
    with open("index.m3u8",mode="r",encoding="utf-8") as f:
        for line in f:
            if line.startswith("#EXT-X-STREAM-INF"):
                return f.readline().strip()
    return False

async def download_one(ts_url,file_name,sem):
    print(f"{file_name},开始下载")
    # 设置并发量
    async with sem:
        # 下载
        # 设置超时时间

        async with aiohttp.ClientSession(headers=head) as sess:
            async with sess.get(ts_url) as resp:
                content = await resp.content.read()
                async with aiofiles.open(f"./source/{file_name}", mode="wb") as f:
                    await f.write(content)
    print(f"{file_name},下载完毕")
async def download_all_ts(m3u8_url_2):
    # 信号量,控制并发量
    sem = asyncio.Semaphore(10)
    tasks = []
    i = 1
    with open("index.m3u8",mode='r',encoding='utf-') as f:
        for line in f:
            if i == 10:
                break
            line = line.strip()
            if line.startswith("#"):
                continue
            if not line.startswith("https"):
                line = urljoin(m3u8_url_2, line)
            print(line)
            # 去下载一个ts
            t = asyncio.create_task(download_one(line,f"{i}.ts",sem))
            tasks.append(t)
            i += 1

        await asyncio.wait(tasks)

def create_list():
    input_folder = './source'  # 替换为你的 .ts 文件文件夹路径
    # merge_ts_files(input_folder, output_file)
    # 获取所有 .ts 文件并排序
    ts_files = sorted([os.path.join(input_folder, f) for f in os.listdir(input_folder) if f.endswith('.ts')])

    if not ts_files:
        print("未找到 .ts 文件!")
    # 创建一个临时文件,列出所有 .ts 文件的路径
    file_list_path = os.path.join(input_folder, 'file_list.txt')

    with open(file_list_path, 'w') as f:
        for ts_file in ts_files:
            ts_name = ts_file.split("\\")[-1]
            # print(ts_name)
            f.write("file " + ts_name+"\n")
def main():
    # 提取m3u8的url
    m3u8_url = get_m3u8_url()
    print("提取的m3u8_url",m3u8_url)
    # 下载m3u8文件
    download_m3u8(m3u8_url)
    print("下载m3u8_url文件",m3u8_url)
    # 是否有下一层m3u8
    m3u8_url_2 = has_next_m3u8()
    print("是否有下一层next_m3u8_url",m3u8_url_2)
    while m3u8_url_2:
        # 有下一层拼接url
        m3u8_url = urljoin(m3u8_url,m3u8_url_2)
        # 下载文件
        download_m3u8(m3u8_url)
        print("下载m3u8",m3u8_url)
        # 判断是否还要下一层
        m3u8_url_2 = has_next_m3u8()
        print("是否还有下一层",m3u8_url_2)

    # 异步下载ts
    loop = asyncio.get_event_loop()
    loop.run_until_complete(download_all_ts(m3u8_url))
    
if __name__ == '__main__':
    main()
    create_list()
    # cmd 上输入命令合并视频 ffmpeg -f concat -i file_list.txt -c copy output.mp4 
    # ffmpeg需要自行去下载,并将其bin路径添加到path的环境变量中

流程是在源代码里要找到并用re提取出m3u8的url,并异步去.ts文件,当然有的可能不是.ts,可能是其他的结尾形式如:.jpeg,最后使用ffmpeg合并.ts文件,我并没有全部对.ts文件全部爬取,只是爬取了前10个.ts文件,并进行了视频合并。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2312606.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智慧城市智慧社区项目建设方案

一、项目背景 在全球化进程加速的今天&#xff0c;城市化问题日益凸显&#xff0c;传统的城市管理模式已难以满足现代社会对高效、智能化管理的需求。智慧城市和智慧社区的概念应运而生&#xff0c;其核心目标是通过信息技术手段&#xff0c;提升城市资源的利用效率&#xff0…

RabbitMQ高级特性--消息确认机制

目录 一、消息确认 1.消息确认机制 2.手动确认方法 二、代码示例 1. AcknowledgeMode.NONE 1.1 配置文件 1.2 生产者 1.3 消费者 1.4 运行程序 2.AcknowledgeMode.AUTO 3.AcknowledgeMode.MANUAL 一、消息确认 1.消息确认机制 生产者发送消息之后&#xff0c;到达消…

Java EE 进阶:Spring IoCDI

IOC的简单介绍 什么是Spring&#xff1f;Spring是一个开源的框架&#xff0c;让我们的开发更加的简单&#xff0c;我们可以用一句更加具体的话来概括Spring&#xff0c;就是Spring是一个包含众多工具方法的IOC容器。 简单介绍一下IOC&#xff0c;我们之前说过通过ReqestContr…

Java数据结构第二十期:解构排序算法的艺术与科学(二)

专栏&#xff1a;Java数据结构秘籍 个人主页&#xff1a;手握风云 目录 一、常见排序算法的实现 1.1. 直接选择排序 1.2. 堆排序 1.3. 冒泡排序 1.4. 快速排序 一、常见排序算法的实现 1.1. 直接选择排序 每⼀次从待排序的数据元素中选出最小的⼀个元素&#xff0c;存放在…

【算法day5】最长回文子串——马拉车算法

最长回文子串 给你一个字符串 s&#xff0c;找到 s 中最长的 回文 子串。 https://leetcode.cn/problems/longest-palindromic-substring/description/ 算法思路&#xff1a; class Solution { public:string longestPalindrome(string s) {int s_len s.size();string tmp …

《如何排查Linux系统平均负载过高》

【系统平均负载导读】何为系统平均负载&#xff1f;假设一台云服务主机&#xff0c;突然之间响应用户请求的时间变长了&#xff0c;那么这个时候应该如何去排查&#xff1f;带着这个问题&#xff0c;我们对“平均负载”展开深入的探讨和研究。 何为Linux系统的平均负载&#xf…

基于DeepSeek实现PDF嵌入SVG图片无损放大

1. PDF中效果图 2. 询问Deepseek进行代码书写&#xff0c;不断优化后结果 /*** SVG工具类&#xff0c;用于生成价格趋势的SVG图表*/ public class SvgUtils {// SVG画布尺寸private static final int WIDTH 800;private static final int HEIGHT 500;private static final i…

整型的不同类型和溢出

一、整数的不同类型 不同编程语言中的整数类型主要通过以下两个维度区分&#xff1a; 1. 存储大小 字节数&#xff1a;决定整数能表示的范围&#xff08;如 1字节8位&#xff09;。 常见类型&#xff1a; byte&#xff08;1字节&#xff09;、short&#xff08;2字节&#x…

使用express创建服务器保存数据到mysql

创建数据库和表结构 CREATE DATABASE collect;USE collect;CREATE TABLE info (id int(11) NOT NULL AUTO_INCREMENT,create_date bigint(20) DEFAULT NULL COMMENT 时间,type varchar(20) DEFAULT NULL COMMENT 数据分类,text_value text COMMENT 内容,PRIMARY KEY (id) ) EN…

小程序 wxml 语法 —— 41列表渲染 - 进阶用法

这一节讲解列表渲染的两个进阶用法&#xff1a; 如果需要对默认的变量名和下标进行修改&#xff0c;可以使用 wx:for-item 和 wx:for-item&#xff1a; 使用 wx:for-item 可以指定数组当前元素的变量名使用 wx:for-index 可以指定数组当前下标的变量名 将 wx:for 用在 标签上&…

python语言总结(持续更新)

本文主要是总结各函数&#xff0c;简单的函数不会给予示例&#xff0c;如果在平日遇到一些新类型将会添加 基础知识 输入与输出 print([要输出的内容])输出函数 input([提示内容]如果输入提示内容会在交互界面显示&#xff0c;用以提示用户)输入函数 注释 # 单行注释符&…

FPGA学习篇——Verilog学习5(reg,wire区分及模块例化)

1 何时用reg&#xff0c;何时用wire&#xff1f; 这个我找了一些网上的各种资料&#xff0c;大概说一下自己的理解&#xff0c;可能还不太到位... wire相当于一根线&#xff0c;是实时传输的那种&#xff0c;而reg是一个寄存器&#xff0c;是可以存储数据的&#xff0c;需要立…

Redis 数据持久化之AOF

AOF&#xff08;Append Only File&#xff09; 以日志的形式来记录每个写操作&#xff0c;将Redis执行过的所有写指令记录下来&#xff08;读操作不记录&#xff09;&#xff0c;只许追加文件但不可以改写文件&#xff0c;redis启动之初会读取该文件重新构建数据&#xff0c;换…

【芯片验证】verificationguide上的74道SystemVerilog面试题

诧异啊,像我这种没事在网上各处捡东西吃的人为什么之前一直没有用过verificationguide这个网站呢?总不能是大家都已经看过就留下我不知道吧。前几天在论坛上和朋友谈论验证面试题时才搜到这个网站的,感觉挺有意思: .: Verification Guide :.​verificationguide.com/https…

Java后端高频面经——计算机网络

TCP/IP四层模型&#xff1f;输入一个网址后发生了什么&#xff0c;以百度为例&#xff1f;&#xff08;美团&#xff09; &#xff08;1&#xff09;四层模型 应用层&#xff1a;支持 HTTP、SMTP 等最终用户进程传输层&#xff1a;处理主机到主机的通信&#xff08;TCP、UDP&am…

面试题(二)--Object中的常见方法

Object Java的Object是所有Java类的父类&#xff0c;所有的Java类直接或者间接的继承了Object类&#xff0c;Object类位于java.lang包中&#xff08;编译时自动导入&#xff09;&#xff0c;主要提供了11种方法。 /*** native 方法&#xff0c;用于返回当前运行时对象的 Class…

运行OpenManus项目(使用Conda)

部署本项目需要具备一定的基础&#xff1a;Linux基础、需要安装好Anaconda/Miniforge&#xff08;Python可以不装好&#xff0c;直接新建虚拟环境的时候装好即可&#xff09;&#xff0c;如果不装Anaconda或者Miniforge&#xff0c;只装过Python&#xff0c;需要确保Python是3.…

设备管理系统功能与.NET+VUE(IVIEW)技术实现

在现代工业和商业环境中&#xff0c;设备管理系统&#xff08;Equipment Management System&#xff0c;简称EMS&#xff09;是确保设备高效运行和维护的关键工具。本文采用多租户设计的设备管理系统&#xff0c;基于.NET后端和VUE前端&#xff08;使用IVIEW UI框架&#xff09…

数据类设计_图片类设计之2_无规则图类设计(前端架构基础)

前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 接续上一篇数据类设计_图片类设计之1_矩阵类设计(前端架构基础)-CSDN博客,讨论非规则图类型的设计 无规则图的简单定义 前面的矩阵类,有明显的特征:长,宽,行和…

aws(学习笔记第三十二课) 深入使用cdk(API Gateway + event bridge)

文章目录 aws(学习笔记第三十二课) 深入使用cdk学习内容&#xff1a;1. 使用aws API Gatewaylambda1.1. 以前的练习1.2. 使用cdk创建API Gateway lambda1.3. 确认cdk创建API Gateway lambda 2. 使用event bridge练习producer和consumer2.1. 代码链接2.2. 开始练习2.3. 代码部…