前言

前几天我想看一个番剧, 正好搜索到了 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 是因为最后一个元素是别的内容不是描述视频分段信息的, 不得不说这个接口返回的数据构造的真是及其混乱, 我解析的时候都费了很大劲!

到此问题全部解决

代码实现

import requests
import re
import json
import os
from threading import Thread
import sys import time requests.packages.urllib3.disable_warnings() def progress():
width=30
while True:
global all_num
global now_num
percent = now_num/all_num * 100
left = int(width * percent // 100)
right = width - left
print('\r[', '#' * left, ' ' * right, ']',f' {percent:.0f}%',sep='', end='', flush=True)
if all_num == now_num:
break
time.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_num
data = requests.get(url,headers={"Range": "bytes=0-"},stream=True).content
with open(name+os.sep+str(id_)+'.mp4','wb') as f:
f.write(data)
now_num += 1 def api_get(id_):
global all_num
global now_num
all_num = 0
now_num = 0 api_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']) -1
kk = 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 = 0
now_num = 0
headers = {
"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 = None
else:
s = None
e = None mul_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 脑残的文件路径问题

PP视频(PPTV聚力)web接口分析的更多相关文章

  1. TensorFlow.训练_资料(有视频)

    ZC:自己训练 的文章 貌似 能度娘出来很多,得 自己弄过才知道哪些个是坑 哪些个好用...(在CSDN文章的右侧 也有列出很多相关的文章链接)(貌似 度娘的关键字是"TensorFlow ...

  2. 使用you-get下载视频网站视频或其他

    使用you-get下载视频网站视频或其他 文/玄魂 目录 使用you-get下载视频网站视频或其他 前言 1.1 下载.安装 依赖 exe安装 pip安装 Antigen安装 Git 克隆源码 Hom ...

  3. You-Get 一键下载全网视频资源

      下载视频 无论是单纯的下载视频收藏,还是以便离线收看,都离不开“下载”,好的工具让你把注意力更好的放在视频的本身,而不用考虑要如何下载视频.下载视频从来不乏方法,之前也介绍了下载 Youtube ...

  4. 如何下载哔哩哔哩、爱奇艺、腾讯视频、优酷、斗鱼、TED、YouTube网页视频

    这里使用you-get工具进行下载 github地址:https://github.com/soimort/you-get/ github项目文档:https://github.com/soimort ...

  5. pptv泥够了!pptv“关闭”事件为营销炒作坐实!

    昨天还让人心生怜悯的pptv聚力,今天下午2点07分又再一次发布微博,而几天发布的内容是see U again!再次证实了pptv昨天的“关闭”还是“倒闭”消息为营销炒作.不过马浩周要问了,真的要这么 ...

  6. 2016中国APP分类排行榜参选入围产品公示

    2016中国APP分类排行榜参选入围产品公示   由中国科学院<互联网周刊>.中国社会科学院信息化研究中心.eNet硅谷动力共同主办的2016中国APP分类排行榜发布暨颁奖晚宴即将举行.此 ...

  7. you-get中文说明

    来源于:https://github.com/soimort/you-get/wiki/%E4%B8%AD%E6%96%87%E8%AF%B4%E6%98%8E You-Get 乃一小小哒命令行程序, ...

  8. OpenWrt 路由器过滤广告的N种方法

    路由器已经成为每个家庭不可缺少的角色,手机.电脑.电视,凡是需要互联网的设备都要用到它.那么路由器除了给我们的网络设备分发网络外,还有其他用途吗? 现在很多人家里都用着智能路由器,智能路由器究竟怎么智 ...

  9. 发现一个直播录制工具you-get

    地址:https://github.com/soimort/you-get 截至到今天,支持的平台如下: Site URL Videos? Images? Audios? YouTube https: ...

  10. 融云SDK触达用户数破20亿 王者风范双倍展现

    11月1日,融云SDK触达用户数突破20亿,业务增长速度及用户覆盖量再创即时通讯云领域新高.自去年11月10日公布SDK触达用户数破10亿以来,融云仅用了一年时间,便取得了触达用户数翻倍的成绩,迅猛的 ...

随机推荐

  1. 02-MyBatisPlus入门

    快速开始参考:https://baomidou.com/pages/226c21/ 测试项目: mybatis_plus 数据库:mybatis_plus 一.创建并初始化数据库 1.创建数据库: m ...

  2. 高德地图与CAD图叠加显示方法汇总及优缺点分析

    前言 ​ 高德地图应用在许多领域,平常我们用的地图导航,除过正常的地图导航指引功能之外,其实还有很多实用的功能.如高德影像地图应用在包括地理.土地测量.水文学.生态学.气象学以及海洋学等方面.Auto ...

  3. day03-3私聊功能

    多用户即时通讯系统03 4.编码实现02 4.4功能实现-私聊功能实现 4.4.1思路分析 客户端 - 发送者: 用户在控制台输入信息,客户端接收内容 将消息构建成Messgae对象,通过对应的soc ...

  4. 使用MinIO中暂未解决的问题

    时间显示问题 web页面上创建桶的时间跟使用SDK获取的时间不一样,相差8个小时,但是mc命令行客户端获取的时间跟web上的一样

  5. Ceph 有关知识简介

    Ceph 存储集群至少需要一个 Ceph Monitor 和两个 OSD 守护进程.而运行 Ceph 文件系统客户端时,则必须要有元数据服务器( Metadata Server ). Ceph OSD ...

  6. 【前端必会】前端开发利器VSCode

    介绍 工欲善其事必先利其器,开发工具方面选择一个自己用的顺手的,这里就用VSCode 安装参考 https://www.runoob.com/w3cnote/vscode-tutorial.html ...

  7. display:block 和display:inline-block的区别和用法

    1).块状元素:(div,p,form,ul,ol,li) ,独占一行,默认情况width为100% 2).行内块状元素:(span,img,a),不会独占一行,相邻的元素一直排在同一行,排满了才会换 ...

  8. 使用开源计算引擎提升Excel格式文件处理效率

    对Excel进行解析\生成\查询\计算等处理是Java下较常见的任务,但Excel的文件格式很复杂,自行编码读写太困难,有了POI\EasyExcel\JExcel等类库就方便多了,其中POI最为出色 ...

  9. 【pytest官方文档】解读- 插件开发之hooks 函数(钩子)

    上一节讲到如何安装和使用第三方插件,用法很简单.接下来解读下如何自己开发pytest插件. 但是,由于一个插件包含一个或多个钩子函数开发而来,所以在具体开发插件之前还需要先学习hooks函数. 一.什 ...

  10. 前端框架Vue------>第三天学习(1)

    ` 文章目录 10 .组件基础 10.1 .什么是组件 11.什么是计算属性 10 .组件基础 10.1 .什么是组件 件是可复用的Vue实例,说白了就是一组可以重复使用的模板 <!DOCTYP ...