前言

前几天我想看一个番剧, 正好搜索到了 PP视频,我才知道PP视频就是PPTV聚力,我想把番剧下载下来,结果发现视频竟然不是m3u8格式,而是多段mp4,所以简单的写了个脚本,可以在不登录的情况下直接下载vip和付费视频蓝光画质(只能说明这个视频网站做的不行)

开始分析

经过调试我首先得到了视频地址的url

https://10314.vcdn.pplive.cn/0/0/1/2de8f8694a79c437a11b09941fb1cb0a.mp4?h5vod.ver=2.1.3&k=0b6a74e50374776203bd05d55a090fba-e800-1588284812&type=mhpptv

当然,我当时拿到的url 是很长的一段还有其他参数,但是我发现那些参数都是无用的影响访问的参数只有这几个
h5vod.ver : 固定值
type : 固定值
k : 变值

说明 k 是一个接口得到的, 所以我需要找到对应的接口就可以了

但是现在还有一个问题就是 这个只是视频的一段, 其他视频分段地址又是什么样的呢?
经过我反复调试发现 url 中的

https://10314.vcdn.pplive.cn/a/b/c/

(对应位置我用字母来代替数字了,为了描述方便)
a 分段视频的第几段
b 默认为0 就可以(具体表示什么不清楚,但是瞎填肯定是不行的)
c 这个数字可以随意瞎填,因为后台解析没用到这个参数,但是要有这个参数
a 为 0 第一段视频, a 为 1 为第二段视频

所以接下来的问题就是找到那个接口了
经过调试发现了一个接口

https://web-play.pptv.com/webplay3-0-12407631.xml?o=0&version=6&type=mhpptv&appid=pptv.web.h5&appplt=web&appver=4.0.7&cb=a

这个接口参数只有一个变量 那就是12407631,也就是id,每一集都有唯一的 id ,而这个id 我们也可以通过访问对应视频播放界面的url后返回的html源码中查看到

返回的不只是一集,而是全剧的每一集id都可以通过一个url来获取到

那么我们来看看 这个接口返回了哪些内容

几种画质的 mp4,知道这些那么我们还差一个 k参数就可以构造视频的url了
经过我查找发现了k值, 一个视频的一种清晰度对应唯一一个k值

这里用了url编码看起来乱七八糟,用python解码一下

from urllib.parse import unquote
print(unquote("4e6a8848fb388e09708a132bf4caeb4e-5775-1588285899%26bppcataid%3D17"))

输出:

4e6a8848fb388e09708a132bf4caeb4e-5775-1588285899&bppcataid=17

可以看到 & 符号前面的就是k ,所以到时候我们可以用& 进行分割然后取出 k

到此看起来问题全部解决了我们也可以构造视频url 了,但是还有一个问题, 那就是视频到底分多少段我们还不知道, 毕竟我们不能遍历去访问直到访问不到数据(那样太傻了)

其实接口里面也存在这样的数据了

画质下面mp4 字段 childNodes 是一个列表,这个列表的长度减1 就是不同画质的分段数, 减1 是因为最后一个元素识别的内容不是描述视频分段信息的, 不得不说这个接口返回的数据构造的真是及其混乱, 我解析的时候都费了很大劲!

到此为止问题全部解决

python代码

import requests
import re
import json
import os
from threading import Thread
import sysimport timerequests.packages.urllib3.disable_warnings()def progress():width=30while True:global all_numglobal now_numpercent = now_num/all_num * 100left = int(width * percent // 100)right = width - leftprint('\r[', '#' * left, ' ' * right, ']',f' {percent:.0f}%',sep='', end='', flush=True)if all_num == now_num:breaktime.sleep(1)def hecheng(sh,path):# 判断是否只是一段视频if len(os.listdir(path)) <= 2:os.remove(path+os.sep+"1.txt")else:os.system(sh)for i in os.listdir(path):if i != 'output.mp4':os.remove(path+os.sep+i)def download(url,id_,name):global now_numdata = requests.get(url,headers={"Range": "bytes=0-"},stream=True).contentwith open(name+os.sep+str(id_)+'.mp4','wb') as f:f.write(data)now_num += 1def api_get(id_):global all_num   global now_numall_num = 0now_num = 0api_url = f"https://web-play.pptv.com/webplay3-0-{id_}.xml?o=0&version=6&type=mhpptv&appid=pptv.web.h5&appplt=web&appver=4.0.7&cb=a"s = requests.get(api_url,verify=False,headers=headers)data = json.loads(s.text[2:-4])try:name = data['childNodes'][2]['nm']except Exception:name = data['childNodes'][0]['nm']print("正在下载:"+name)rid = data['childNodes'][-4]['rid']all_num = len(data['childNodes'][-4]['childNodes']) -1kk = data['childNodes'][-5]['childNodes'][-1]['childNodes'][0].split('%26')[0]if not os.path.exists(name):os.makedirs(name)# 合成命令a1 = os.path.abspath(name+os.sep+'1.txt')a2 = os.path.abspath(name+os.sep+'output.mp4')sh = f'ffmpeg -f concat -safe 0 -i "{a1}" -c copy "{a2}" -loglevel error'path = os.path.dirname(a1)# 启动进度条线程progress_t = Thread(target=progress)progress_t.start()t_list = []t_list.append(progress_t)f = open(name+os.sep+'1.txt','w')for i in range(all_num):video_url = f"https://10314.vcdn.pplive.cn/{i}/0/1/{rid}?h5vod.ver=2.1.3&k={kk}&type=mhpptv"f.write("file "+ os.path.abspath(name+os.sep+f'{i}.mp4')+"\n")t = Thread(target=download,args=(video_url,i,name))t_list.append(t)t.start()if not mul_t:t.join()f.close()   for t in t_list:t.join()# print(sh)print("\n"+name+" 正在合成...")hecheng(sh,path)print(name+" 合并成功")def start(url,is_all,s,e,mul_t):response = requests.get(url,verify=False,headers=headers)if response.status_code == 200:result = re.findall("var webcfg = (.*?);",response.text)data = json.loads(result[0])if is_all:# 下载剧集try:for item in data['playList']['data']['list'][s-1:e]:api_get(item['id'])except Exception:for item in data['playList']['data']['list']:api_get(item['id'])else:# 下载单集api_get(data['id'])if __name__ == "__main__":all_num = 0now_num = 0headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"}url = input("输入地址:")is_all = input("是否下载全剧(默认否):")if is_all:r = input("请输入下载剧集(例如1-5,默认全部):")if r:s,e = r.split("-")    s = int(s)if e:e = int(e)else:e = Noneelse:s = Nonee = Nonemul_t = input("是否启用多线程下载(默认否):")start(url,is_all,s,e,mul_t)

也是做了一个简单的命令行工具,功能有限

  1. 通过一次输入可以下载全集的蓝光画质视频
  2. 下载vip 视频
  3. 下载付费视频
  4. 下载完分段视频自动调用 ffmpeg 命令进行合成
  5. 选择性 下载 m-n 集视频
  6. 多线程下载(下载电影的时候最好不要开启)

使用方法: 视频播放界面的url输入进去,然后回车, 剩下的参数不写直接回车相当于默认, 随意写什么相当于是

其他注意 : windows 使用调用 ffmpeg先要把其加入系统环境变量里面,另外 第 81 行代码应改为

f.write("file "+ (os.path.abspath(name+os.sep+f'{i}.mp4')+"\n").replace("\\","\\\\"))

这个主要是windows 脑残的文件路径问题

逆向分析pptv,利用python实现下载蓝光画质视频(Vip)相关推荐

  1. 利用Python爬虫下载王者荣耀教学视频

    前言: 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例的人,却不知道如何去学习更加高深的知识. 那么针对这三类人,我给 ...

  2. 用python可以免费下载音乐吗-利用Python来下载会员歌曲!想让我充会员?不存在的!...

    原标题:利用Python来下载会员歌曲!想让我充会员?不存在的! 低头呢喃,对你的偏爱太过于明目张胆 目标 QQ音乐中VIP才能下载的歌曲 使用库 主要使用的库: requests 向服务器发起请求 ...

  3. APP逆向分析之XX音乐客户端下载歌曲权限绕过

    很长一段时间没有做逆向分析相关的研究了,最近看了一部电影,电影有首插曲名字叫不见不散,那是相当的好听啊,打开XX音乐,准备下载,额-.弹出付费才能下载-.为了一首歌,开一个包月服务,显然不是我这个搞过 ...

  4. 利用python 批量下载美拍视频

    前些日子写了一个利用Python批量下载微博配图的程序,因为是基于微博的移动端,即weibo.cn  ,难度要小很多.而当我面对美拍时却发现,好像有点困难啊. 美拍的页面有很多动态元素,当我们打开某一 ...

  5. 利用python批量下载美拍视频

    前些日子写了一个利用python批量下载微博配图的程序,因为是基于微博的移动端,即weibo.cn  ,难度要小很多.而当我面对美拍时却发现,好像有点困难啊. 美拍的页面有很多动态元素,当我们打开某一 ...

  6. (详细思路)利用py批量下载某站的视频

    (详细思路)利用py批量下载某站的视频 @[TOC]((详细思路)利用py批量下载某站的视频) 前言 一.视频的种类 二.分析网站 三.视频音频合并 四.想要看的更具体的点击这个网址 总结 前言 某站 ...

  7. Python如何下载网页上的视频

    Python如何下载网页上的视频 1.在电脑上创建一个文件夹 2.在文件夹里输入cmd 3.回车 4.输入 pip install you-get 回车 5.输入you-get 自己喜欢的视频链接 回 ...

  8. PS3简易蓝光规格视频制作说明

    本教程对应刻录光碟播放蓝光视频封装制作,并且可以实现软字幕 本教程对应的封装软件下载 http://gilleco.2alien.net/MediaTools/tsMuxer.rar 添加文件 添加是 ...

  9. 如何将蓝光M4V视频格式转换成MP4高清视频格式

    Adobe Premiere Pro相信很多人应该都有用过吧,Adobe Premiere Pro简称"PR",是一款视频编辑软件,PR导出H.264编码的视频文件格式有两种:一种 ...

最新文章

  1. Vue组件中的data和props属性
  2. 五花八门的Shell 的相关概念和配置方法
  3. 转帖:对linux中半增加半连接数量和防止服务器被dos***
  4. javascript 中面向对象实现 如何继承
  5. 还不会python面相对象?活该单身(面向对象基础+交互关系)
  6. 泛型 (Generics)一定是最易懂简单的
  7. python列表-使用
  8. python爬取京东商品属性_python爬虫小项目:爬取京东商品信息
  9. 尝试使用iReport4.7(基于Ubuntu Desktop 12.04 LTS)
  10. Git push - fatal: write error: Bad file descriptor
  11. 户籍化管理系统 c语言,社会单位消防安全“户籍化管理系统录入要点
  12. Python3 找200以内的所有素数/质数 | break与continue
  13. 今天你对我爱搭不理, 明天我让你高攀不起
  14. C++——EOF是个什么东西?
  15. 消息对话框(消息盒子)
  16. 如何用计算机术语写论文,计算机毕业论文结论怎么写?
  17. Excel中如何显示复杂公式中局部的计算结果,例如嵌套函数,使用多个函数
  18. eclipse 换背景图片
  19. 实验二——————路由器口令配置
  20. MVC框架的原理详解

热门文章

  1. 【超实用!!!】如何提高开发效率?免费 IDE 插件 Cloud Toolkit 告诉你
  2. “华为手机”和“荣耀手机”的区别?今天全都告诉你
  3. 平安好医生用互联网降低医疗健康门槛
  4. CSS3新特性有哪些?
  5. 炒股秘笈 好的心态与好的习惯
  6. 「移动端」touch事件,touchEvent对象
  7. 一个人事经理眼中的中国人劣根性
  8. 《丑陋的中国人》之读后感
  9. 消息队列MQ的使用场景
  10. 微信订阅消息 开启验证token失败解决方法