注:本人小白一枚,爬虫也是刚接触,写的不好请多指点

这里给出后半部分,转换m3u8视频的方法

上一节讲到我们能获取到m3u8文件所在的url地址,这一节的思路是将m3u8文件进行下载,并将其转化为MP4格式

目录

m3u8文件的下载

下载ts文件

处理ts文件

合并工作

删除

完整代码

运行结果

注意


m3u8文件的下载

这里用到了urllib库中request方法中的urlretrieve函数

代码如下:

from urllib import requestdef download_m3u8(url,name):"""下载要解析的m3u8文件:param url: 我们获得到的m3u8文件的url:param name: 名字就是m3u8文件的文件名:return: 下载m3u8文件"""request.urlretrieve(url, f'{name}.m3u8')

这样我们就能将文件从网页中下载下来,运行完后会在当前目录下多出一个m3u8文件

当我们打开这个m3u8文件时:

就会发现每个url后面的都是.png后缀,和平常的.ts不太一样

直接在网页中打开的图像是这样的

我们将这个png下载,在Hexeditor中打开会发现前面头部信息是png(有的是有的不是),所以说有的并不能通过直接修改后缀名来将这个文件转化为ts类型,为了保险起见,我们将这些数据的头部都进行修改,首先我们要将这个网站上的这个文件以字节流的形式下载下来

下载ts文件

将这个网站上的文件以字节流的形式下载下来

其实也就是为了去获取这个网站的这个文件,然后再将它转换成ts文件

def download_ts(name):"""以字节流形式下载ts文件:param name: 我们下载过来的m3u8文件:return: 将尚未处理的ts文件,存入inlib文件夹下,在运行中返回的是一共多少个ts文件"""web_list=[]with open(f"{name}.m3u8","r") as files:lines_list=files.readlines()for https in lines_list:web=re.search("https://.+",https)if web:web_list.append(web.group())files.close()headers={"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71"}#remove_or_set(r"D:\pythonProject\pythonlearn\anime\outlib")#remove_or_set(r"D:\pythonProject\pythonlearn\anime\inlib")for url,num in zip(web_list,range(1,len(web_list)+1)):resp=requests.get(url,headers=headers)with open(f"inlib/{num}.ts","wb") as codes:codes.write(resp.content)codes.close()return len(web_list)

下载之后如图:

处理ts文件

修改ts文件的头部信息,然后在这个函数中向filelist.txt文件中写入之后要合并的ts文件的信息

代码如下:

def change(num):"""由于这个m3u8文件比较特殊,里面头部信息为png,我们要将它修改成ts:param num: 这个就是总共的ts数:return: 返回修改过后的ts文件"""print("正在加载....")with open("filelist.txt","a+") as file:file.write("\n")for i in range(1,num+1):#num+1file.write(f"file  'D:\\pythonProject\\pythonlearn\\anime\\outlib\\{i}.ts'\n")with open(f"inlib/{str(i)}.ts","rb") as infile:out_ts = f"outlib/{str(i)}.ts"outfile = open(out_ts, "wb")data = infile.read()outfile.write(data)outfile.seek(0x00)outfile.write(b'\xff\xff\xff\xff')outfile.flush()outfile.close()infile.close()file.close()

filelist.txt文件内容如下:

合并工作

这里用到了ffmpy这个库中的FFmpeg函数,代码如下:

from ffmpy import FFmpegdef together(name):"""合并outlib列表中的所有ts文件:param name: 爬取视频的名字:return: 返回一个MP4文件"""ff=FFmpeg(inputs={"D:\\pythonProject\\pythonlearn\\anime\\filelist.txt":"-f concat -safe 0"},outputs={f"{name}.mp4":"-c copy"})# print(ff.cmd)ff.run()

删除

清空文件夹中的所有文件,如果没有文件就进行创建

import re
import shutildef remove_or_set(filepath):"""删除多余的文件防止下一次爬取的时候合并出问题"""if not os.path.exists(filepath):os.mkdir(filepath)else:shutil.rmtree(filepath)os.mkdir(filepath)

完整代码

这里把上一次的代码一并附上

import os
import re
import shutil
import requests
import time
import sys
from ffmpy3 import FFmpeg
from urllib import requestdef parse_search_url(url):"""用于提取搜索网页的内容也就是http://159.75.0.62:11234/ssszz.php?top=10&q={}网页中的内容,{}中为搜索值:param url: http://159.75.0.62:11234/ssszz.php?top=10&q={}:return: detail_url返回解析后的url后缀,格式是/acq/74378类似的形式,movies_name返回影片名字"""headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71","Cookie":"PHPSESSID=8jnc6i33n2lablu2arfqev17l7"}resp = requests.get(url, headers=headers)html = resp.content.decode("utf-8")# print(html)detail_url = re.findall(".+(/.+/\d+/)", html)movies_name = re.findall(r"""title.+"(.+?)",""", html)return detail_url, movies_namedef episodes(url):"""用于显示视频更新到哪一集:param url: http://yhdm81.com/+后面的后缀,如:/tv/74378/:return: 没有返回值,只是告知使用者该动画更新到第几集了"""headers = {"User-Agent":"Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 103.0.5060.134Safari / 537.36Edg / 103.0.1264.71"}resp = requests.get(url, headers=headers)html = resp.content.decode("utf-8")episodes_num = re.findall(r"""<span style="font-size:12px;margin-left:10px;">(\D.+)</span><span.+""", html)return f"目前{episodes_num[0]}"def true_video_web(video_num, episode_num):"""获取视频的网络位置:param video_num:视频的编号,如:/tv/74378/中的74378:param episode_num: 选择的集数:return: 返回获取到的m3u8地址"""headers = {"User-Agent":"Mozilla / 5.0(Windows NT 10.0;Win64;x64) AppleWebKit / 537.36(KHTML, likeGecko) Chrome / 103.0.5060.134Safari / 537.36Edg / 103.0.1264.71"}playarr_url = f"http://d.gqyy8.com:8077/ne2/s{video_num}.js"resp = requests.get(playarr_url, headers=headers)html = resp.content.decode("utf-8")video_m3u8 = re.findall(r"""playarr_.{1,3}\[\d\]="https://.+/.+/[a-zA-Z]+?\d{2}\.m3u8.+""", html)# video_url=f"https://yun.66dm.net/SBDM/{video_m3u8[0][:-1]}{episode_num}.m3u8"# 以上两行代码是基于爬取的视频是漫画的前提下写的#print(video_m3u8)m3u8_url_list = video_m3u8[0].split(";")#print(m3u8_url_list)for i in range(len(m3u8_url_list)):m3u8_url_episode = m3u8_url_list[i]# print(m3u8_url_episode)m3u8_name = re.findall("playarr_.{1,3}\[\d\]=.https://.+/.+/\D{1,20}\d{1,3}\.m3u8.+,\d", m3u8_url_episode)# print(m3u8_name)if m3u8_name:comp_num=m3u8_name[0][-1]#print(comp_num)if str(episode_num)==comp_num:m3u8 = re.findall(f"https://.+\.m3u8", m3u8_url_episode)m3u8_name=re.findall(".+/(.+)\.m3u8",m3u8[0])#print(m3u8,m3u8_name)return m3u8[0], m3u8_name[0]def get_m3u8_url():"""根据自己的需要筛选的程序:return: 返回利用true_video_web函数返回m3u8文件所在的url以及m3u8文件名称"""search_url = "http://159.75.0.62:11234/ssszz.php?top=10&q={}".format(input("请输入你要搜索的内容:"))urls, names = parse_search_url(search_url)print(f"一共找到以下{len(names)}项内容:")for name, num in zip(names, range(1, len(names) + 1)):print(f"第{num}项:", "\t", f"{name}")try:choice = int(input("请选择你要找的影视片(输入数字即可):")) - 1except:print("输入有误!")return Nonemovies_url = "http://yhdm81.com/" + urls[choice]print("注意:出现正片,备用或空白,直接选择1即可")print(episodes(movies_url))episode_num = input("请选择你要的集数(输入数字即可):")try:episode_list=episode_num.split("-")episode_list=[i for i in range(1,int(episode_list[1])+1)]#print(episode_list)except:try:episode_list=episode_num.split(",")except:try:episode_list=list(episode_num)except:return Nonevideo_num = re.findall("/(acg|zongyi|tv|mov)/(\d.+)/", urls[choice])videoname=names[choice]return video_num[0][1],videoname,episode_listdef download_m3u8(url, name):"""下载要解析的m3u8文件:param url: 我们获得到的m3u8文件的url:param name: 名字就是m3u8文件的文件名:return: 下载m3u8文件"""request.urlretrieve(url, fr'D:\PythonProject\anime\{name}.m3u8')def download_ts(name):"""以字节流形式下载ts文件:param name: 我们下载过来的m3u8文件:return: 返回尚未处理的ts文件"""web_list = []with open(fr"D:\PythonProject\anime\{name}.m3u8", "r") as files:lines_list = files.readlines()for https in lines_list:web = re.search("https://.+", https)if web:web_list.append(web.group())files.close()headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.71"}remove_or_set(r"D:\PythonProject\anime\outlib")remove_or_set(r"D:\PythonProject\anime\inlib")print("正在下载ts文件......")print("ts视频加载进度:")length=len(web_list)start = time.perf_counter()for url, num in zip(web_list, range(1, length + 1)):a = "▋" * int(num/length*35)c = (num / length) * 100dur = time.perf_counter() - startprint("\r{:^3.0f}% | 用时: {:.2f}s {}".format(c,dur,a), end="")resp = requests.get(url, headers=headers)with open(fr"D:\PythonProject\anime\inlib\{num}.ts", "wb") as codes:codes.write(resp.content)codes.close()return len(web_list)def change(num):"""由于这个m3u8文件比较特殊,里面头部信息为png,我们要将它修改成ts:param num: 这个就是总共的ts数:return: 返回修改过后的ts文件"""with open(r"D:\PythonProject\anime\filelist.txt", "a+") as file:file.write("\n")time.sleep(1)print("\n\n正在转化ts文件......")print("ts视频转化进度:")start = time.perf_counter()for i in range(1, num + 1):  # num+1a = "▋" * int(i/num*30)c = (i / num) * 100dur = time.perf_counter() - startprint("\r{:^3.0f}% | 用时: {:.2f}s {}".format(c, dur, a), end="")file.write(f"file  'D:\\PythonProject\\anime\\outlib\\{i}.ts'\n")with open(f"D:\\PythonProject\\anime\\inlib\\{str(i)}.ts", "rb") as infile:out_ts = f"D:\\PythonProject\\anime\\outlib\\{str(i)}.ts"outfile = open(out_ts, "wb")data = infile.read()outfile.write(data)outfile.seek(0x00)outfile.write(b'\xff\xff\xff\xff')outfile.flush()outfile.close()infile.close()file.close()def together(directory,name):"""合并outlib列表中的所有ts文件:param name: 爬取视频的名字:return: 返回一个MP4文件"""ff = FFmpeg(inputs={r"D:\PythonProject\anime\filelist.txt": "-f concat -safe 0"},outputs={fr"C:\Users\14040\Desktop\{directory}\{name}.mp4": "-c copy"})# print(ff.cmd)ff.run()def remove_or_set(filepath):"""删除多余的文件防止下一次爬取的时候合并出问题"""if not os.path.exists(filepath):os.mkdir(filepath)else:shutil.rmtree(filepath)os.mkdir(filepath)def main():"""这里的文件位置根据自己不同需要进行修改:return:"""video_num,videoname,episode_list = get_m3u8_url()remove_or_set(fr"C:\Users\14040\Desktop\{videoname}")for num in episode_list:try:episode_num=int(num)except:episode_num=numurl,name=true_video_web(video_num,episode_num)print(f"\n\n\n\n▋▋▋▋▋▋▋▋▋开始下载《{videoname}-第{num}集》▋▋▋▋▋▋▋▋▋")#print(name)download_m3u8(url, name)change(download_ts(name))together(f"{videoname}",f"{videoname}-第{num}集")remove_or_set(r"D:\PythonProject\anime\outlib")remove_or_set(r"D:\PythonProject\anime\inlib")os.remove(fr"D:\PythonProject\anime\{name}.m3u8")os.remove(fr"D:\PythonProject\anime\filelist.txt")print(f"▋▋▋▋▋▋▋▋▋{videoname}第{num}集下载完成▋▋▋▋▋▋▋▋▋")if __name__ == '__main__':main()

运行结果

注意

这里出现的有关绝对路径都需要自行进行修改

还有一点,本人能力有限(批量处理还不会多线程操作)

尚不知道以下情况该怎么解决,这里爬取后缀不是index.m3u8文件是没有影响的

实战 | 1——python爬取某动漫网站(2)相关推荐

  1. python实战|python爬取58同城租房数据并以Excel文件格式保存到本地

    python实战|python爬取58同城租房数据并以Excel文件格式保存到本地 一.分析目标网站url 目标网站:https://cq.58.com/minsuduanzu/ 让我们看看网站长啥样 ...

  2. 从入门到入土:基于Python爬取四川大学所有官方网站|狗头保命|

    此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...

  3. 实战 | 用Python爬取《云南虫谷》3.6万条评论,并做数据统计可视化展示分析,好看!...

    最近鬼吹灯系列网剧<云南虫谷>上线,作为鬼吹灯系列作品,承接上部<龙岭迷窟>内容,且还是铁三角原班人马主演,网友直呼非常好看! 今天,我们就用Python爬取目前全部剧集的评论 ...

  4. 实战|用Python爬取《云南虫谷》3.6万条评论,并做数据统计可视化展示分析,好看!

    大家好,我是才哥. 最近鬼吹灯系列网剧<云南虫谷>上线,作为鬼吹灯系列作品,承接上部<龙岭迷窟>内容,且还是铁三角原班人马主演,网友直呼非常好看! 今天,我们就用Python爬 ...

  5. 【爬虫实战】Python 爬取起点热榜,再也不怕没有小说看了!

    最近看完一部小说<大奉打更人>,看得我热血沸腾.但是看完后,有选择困难症的我又不知道可以看什么了. 于是,我打算开发一个爬虫,爬取起点热榜. 一.导入所需库 我们使用 requests 来 ...

  6. 【数据分析项目实战】Python爬取BOSS直聘岗位和数据分析

    说明:这是一个数据分析项目全流程(附带项目实例),本篇教程来源于网络,胖哥对此进行了完整的梳理,并把用到的数据+代码完全奉上.如需数据+完整代码可以直接到文章最后获取. 这里面的数据,我只爬取了部分, ...

  7. Python爬取分析动漫之家订阅量最多的漫画的标签

    最近学到了网页爬虫,在打开动漫之家的时候突然想爬一下动漫之家被订阅最多的漫画的标签,看看大家都喜欢看什么漫画 代码如下 import requests import redef input_info( ...

  8. 【爬虫实战】python爬取虎牙直播间封面美女图片

    Python爬虫爬取虎牙直播间封面美女图片 本文目录 Python爬虫爬取虎牙直播间封面美女图片 写作缘起 上代码 效果展示 思路分析 写作缘起 这篇文章主要是介绍如何使用python爬虫来爬取虎牙直 ...

  9. 【爬虫实战】python爬取中国最好大学排行榜

    最近闲来无事,帮朋友做了个python小作业,爬取武书连2020中国最好大学排名榜单.比较简单,我就直接上代码了. 代码展示 import requests # 请求库 from bs4 import ...

最新文章

  1. 工业互联网平台发展与展望(附PPT)
  2. 为任务关键型Java应用优化垃圾回收
  3. 1.STM32中对LED_GPIO_Config()函数的理解(自定义)之流水灯
  4. 非常不错的文章,囊括啦高性能、高可用的分布式架构体系所有名词
  5. 中小型网站 seo 优化推广策略
  6. 网页开发浏览器兼容性问题
  7. apache 重写和虚拟目录配置
  8. mvc:default-servlet-handler/作用
  9. sql优化个人总结(全)
  10. Windows句柄和指针的区别
  11. Confluence 6 配置边栏
  12. UI 设计常用尺寸规格
  13. html5 打开支付宝app,支付宝H5唤醒APP
  14. 趋肤效应实验报告_电感耦合等离子体发射光谱实验报告
  15. GSMA在G20峰会召开之前就妇女数字融合提出综合性议程
  16. oracle 启用job,Oracle job启动与关闭
  17. Vue3+TypeScript从入门到进阶(六)——TypeScript知识点——附沿途学习案例及项目实战代码
  18. 窗帘轨道怎么安装?方法有哪些?-江南爱窗帘十大品牌
  19. 搜索引擎:高级搜索技巧(初)
  20. intouch中DA server的配置文件

热门文章

  1. 小米/红米手机解锁(红米5 plus 为例)
  2. python求时间序列所有的极值点
  3. Python 文本自动换行
  4. mysql longblob,Mysql LONGBLOB 类型存储二进制数据 (修改+调试+整理)
  5. FreeRTOS原函数库API
  6. 如何对新增用户下载到激活环节进行分析?(案例:时长奖励激励方案)
  7. Linux Anaconda下载安装
  8. 获取应用程序实例句柄HINSTANCE
  9. 《程序员修炼之道》简略笔记:5-8章
  10. LaTeX—将论文模板的关键词从Index Terms 改为Keywords