本次目标  http://www.qiqi.la/vod-detail-id-46194.html
目的,down魔道祖师,实现
前期分析文件得到以下粗略步骤
1 进入二级页面,找到
<iframe width="100%" height="" src="https://cn2.zuixinbo.com/share/722caafb4825ef5d8670710fa29087cf" frameborder="" allowfullscreen=""></iframe>
得到网址
2 访问 https://cn2.zuixinbo.com/share/722caafb4825ef5d8670710fa29087cf
需要带上协议头
Referer: https://cn2.zuixinbo.com/share/722caafb4825ef5d8670710fa29087cf
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
返回另一个页面response_1
得到文件标题 <title>重新压制魔道祖师 前尘篇02 序章 诛邪(下)福利加长版 高清(480P).qlv</title>
3 在response_1
得到:var main = "/20180710/4671_a5ef5a19/index.m3u8?sign=b0023d8b455da27a4294b38c7815f7b3";
拼合网页:https://cn2.zuixinbo.com/20180710/4671_a5ef5a19/index.m3u8?sign=b0023d8b455da27a4294b38c7815f7b3
访问:得到返回结果
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=1080x608
1000k/hls/index.m3u8
4 拼合 https://cn2.zuixinbo.com/20180710/4671_a5ef5a19/1000k/hls/index.m3u8
带协议访问
Referer: https://cn2.zuixinbo.com/share/722caafb4825ef5d8670710fa29087cf
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
得到.ts下载文件路径
分段下载
5 拼合.ts文件 有空更新完整代码
 2018-10-21
    开始编写代码 

     发现在重新写代码的过程中,发现直接在播放页面就有全部的播放地址,只不过是用usc2的
        编码转换了一下,我们需要把其转换成ansi编码
    2 OK,这下直接拿到播放地址,做一下格式化的工作,进行第2步解析,上面的第一步工作算是白费了一片心思

    3 按照上面步骤依次完成,基本没问题

    

# -*- coding:utf-8 -*-
# @time:2018-10-21 14:43
# @Auther:1043453579@qq.com from urllib.request import Request
from urllib.request import urlopen
import re,time,os
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor static_url_1 = 'http://www.qiqi.la/vod-detail-id-46194.html'
class A(object):
def __init__(self,url,e=15):
self.header= {'user-agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'}
self.path = os.getcwd()
self.e = e
self.static_url='https://cn2.zuixinbo.com' def num_of_e(self,url_2):#进入二级页面
res = urlopen(Request(url=url_2,headers=self.header)).read()
res = res.decode() title = self.take_middle_text(res,'<title>',txt_e='</title>') #标题
var_main=re.search('var main = "(.*?)";',res).group(1) #访问下级地址
if not var_main:
exit()
return {'var_main':var_main,'referer':url_2,'标题':title} def open_3(self,url,referer='',**kwargs):
url=self.static_url+url
a={'Referer': referer}
a.update(self.header)
res = urlopen(Request(url=url,headers=a)).read()
res = res.decode()
_=self.take_middle_text(res,'1080x608','.m3u8')+'.m3u8' #得到ts视频地址
return {'url':_.split(),'regerer1':url} def open_4(self,url,referer1='',**kwargs):
referer=referer1
referer= referer.split('/')
referer=referer[0:-1]
referer.append(*url)
url='/'.join(referer)
print(url)
a = {'Referer': referer1}
a.update(self.header)
res = urlopen(Request(url=url,headers=a)).read()
res = res.decode()
ts_list=[]
for i in res.split('\n'):
try:
if i[0]!='#':
ts_list.append(i)
except:pass
return {'ts_list':ts_list,'url':url} def take_middle_text(self,txt, txt_s, txt_e='', seeks=0, seeke=0):
# 取出中间文本,真返回中间文本,假返回False
# seeks有传参,会按照取前几位取值
# seeke有传参,会按照取后几位取值
try:
if txt_e or seeks or seeke:
pass
else:
raise 1
s_1 = txt.find(txt_s)
if s_1 == -1:
raise 1
l_1 = len(txt_s)
if txt_e:
s_2 = txt.find(txt_e)
if s_1 == -1 or s_2 == -1:
return False
return txt[s_1 + l_1:s_2]
if seeks:
return txt[s_1 - seeks:s_1]
if seeke:
return txt[s_1 + l_1:s_1 + l_1 + seeke]
except:
return '传参错误或未找到传参文本' def down_ts(self,dict,path_1):
url = os.path.dirname(dict['url'])+'/'
ts_list=dict['ts_list']
for i in ts_list:
print(path_1,'这里是path_1')
path = os.path.join(path_1, i)
print(path,'这里是path_ts文件网址')
if os.path.exists(path):
print('已存在,跳过')
else:
try:
res = urlopen(Request(url=url+i,headers=self.header)).read()
with open(path,'wb') as f:
f.write(res)
print('成功写入一条')
except:
print('写入失败') def main(self,url):
dict_1 = self.num_of_e(url) #'这里返回一个字典 '
dict_2 = self.open_3(dict_1['var_main'],dict_1['referer'])
dict_3 = self.open_4(dict_2['url'], dict_2['regerer1']) #这里的url未提纯
title = dict_1['标题']
path = os.path.join(self.path,title)
#@print(title,'这里是标题')
if not os.path.exists(path):
os.mkdir(path) #没有就创建一个新的目录
self.down_ts(dict_3,path) if __name__ == '__main__': ex = ProcessPoolExecutor(2)
a_1 = A(static_url_1, 15)
with open('2.txt', 'r', encoding='utf8') as f:
for i in f:
a = i.split()[0].split('$')[1].split('#')[0]
print(ex.submit(a_1.main,a).result())
ex.shutdown()

---第一版,用双进程当作并发,代理未加,隔几天再优化一下,先这样吧

2018-10-30

# -*- coding:utf-8 -*-
# @time:2018-10-21 14:43
# @Auther:1043453579@qq.com from urllib.request import Request
from urllib.request import urlopen
import re,time,os
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor static_url_1 = 'http://www.qiqi.la/vod-detail-id-46194.html'
class A(object):
def __init__(self):
self.header= {'user-agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'}
self.path = os.getcwd()
#self.static_url='https://cn2.zuixinbo.com'
self.static_url = ''
#self.r = redis.Redis(host='127.0.0.1',port=6379,db=0) def get_proxy(self):
return {'http':self.r.randomkey().deocode()} def down_1(self,url,referer='',code=True):
while True:
#proxy = self.get_proxy()
#这里设置代理
try:
_ = self.header
if referer:
a = {'Referer': referer}
_.update(a)
res = urlopen(Request(url=url, headers=_),timeout=60).read()
if code:
res = res.decode()
if res:
time.sleep(1)
return res
else:
raise 1
except Exception as e:
print('请求失败',url)
with open('3.txt','a+') as f:
f.write(url)
f.write('\n')
time.sleep(10) def num_of_e(self,url_2):#进入二级页面
res = self.down_1(url_2)
title = self.take_middle_text(res,'<title>',txt_e='</title>') #标题
var_main=re.search('var main = "(.*?)";',res).group(1) #访问下级地址
if not var_main:
exit()
return {'var_main':var_main,'referer':url_2,'标题':title} def open_3(self,url,referer='',**kwargs):
url=self.static_url+url
res = self.down_1(url,referer=referer)
_=self.take_middle_text(res,'1080x608','.m3u8')+'.m3u8' #得到ts视频地址
return {'url':_.split(),'regerer1':url} def open_4(self,url,referer1='',**kwargs):
referer=referer1
referer= referer.split('/')
referer=referer[0:-1]
referer.append(*url)
url='/'.join(referer)
print(url)
res = self.down_1(url,referer=referer1)
ts_list=[]
for i in res.split('\n'):
try:
if i[0]!='#':
ts_list.append(i)
except:pass
return {'ts_list':ts_list,'url':url} def take_middle_text(self,txt, txt_s, txt_e='', seeks=0, seeke=0):
# 取出中间文本,真返回中间文本,假返回False
# seeks有传参,会按照取前几位取值
# seeke有传参,会按照取后几位取值
try:
if txt_e or seeks or seeke:
pass
else:
raise 1
s_1 = txt.find(txt_s)
if s_1 == -1:
raise 1
l_1 = len(txt_s)
if txt_e:
s_2 = txt.find(txt_e)
if s_1 == -1 or s_2 == -1:
return False
return txt[s_1 + l_1:s_2]
if seeks:
return txt[s_1 - seeks:s_1]
if seeke:
return txt[s_1 + l_1:s_1 + l_1 + seeke]
except:
return '传参错误或未找到传参文本' def down_ts(self,dict,path_1):
url = os.path.dirname(dict['url'])+'/'
ts_list=dict['ts_list']
for i in ts_list:
path = os.path.join(path_1, i)
if os.path.exists(path):
print('已存在,跳过',i)
else:
try:
res = urlopen(Request(url=url+i,headers=self.header),timeout=60).read()
time.sleep(1)
if res:
with open(path,'wb') as f:
f.write(res)
print('成功写入一条',i)
else:
raise 1
except Exception as e:
with open('3.txt','a+') as f:
_ = '-'.join([str(i) for i in time.localtime()[0:6]])
f.write(_ +'###'+e+'$$$'+url)
f.write('\n')
print('写入失败',i,e)
time.sleep(5) def main(self,url):
_ = url.split('com')
self.static_url=_[0]+'com'
dict_1 = self.num_of_e(url) #'这里返回一个字典 '
dict_2 = self.open_3(dict_1['var_main'],dict_1['referer'])
dict_3 = self.open_4(dict_2['url'], dict_2['regerer1']) #这里的url未提纯
title = dict_1['标题']
path = os.path.join(self.path,title)
#@print(title,'这里是标题')
if not os.path.exists(path):
os.mkdir(path) #没有就创建一个新的目录
self.down_ts(dict_3,path) if __name__ == '__main__':
ex = ProcessPoolExecutor(3)
a_1 = A()
with open('2.txt', 'r', encoding='utf8') as f:
for i in f:
a = i.split()[0].split('$')[1].split('#')[0]
ex.submit(a_1.main,a)
ex.shutdown() #BUG在网页的提交网址中

--代理未加,需要的请自行加上代理,稍微优化了一下,里面的2.txt是下载地址,见下面

第01集$https://cn2.zuixinbo.com/share/722caafb4825ef5d8670710fa29087cf#
第02集$https://cn2.zuixinbo.com/share/fbad540b2f3b5638a9be9aa6a4d8e450#
第03集$https://v-xunlei.com/share/c457d7ae48d08a6b84bc0b1b9bd7d474#
第04集$https://v-xunlei.com/share/8db1d4a631a6e9a24e2c0e842e1f1772#
第05集$https://v-xunlei.com/share/197f76fe309657064dbec74d9eea4be4#
第06集$https://v-xunlei.com/share/92b70a527191ca64ca2df1cc32142646#
第07集$https://v-xunlei.com/share/abc99d6b9938aa86d1f30f8ee0fd169f#
第08集$https://v-xunlei.com/share/22cdb13a83f73ccd1f79ffaf607b0621#
第09集$https://v-xunlei.com/share/aceacd5df18526f1d96ee1b9714e95eb#
第10集$https://v-6-cn.com/share/075b051ec3d22dac7b33f788da631fd4#
第11集$https://v-6-cn.com/share/4670c07872d5314c6ad6ffa633d4a059#
第12集$https://v-xunlei.com/share/2bba9f4124283edd644799e0cecd45ca#
第13集$https://v-cntv-cn.com/share/d87aa42cd08ba8612664a73dbdb64221#
第14集$https://v-cntv-cn.com/share/63ceea56ae1563b4477506246829b386#
第15集$https://v-cntv-cn.com/share/e8a69bf65aefc23d0f360ab695e9eac7

--这里是下载地址

2020-05-02

# -*- coding:utf-8 -*-
# @time:2018-10-21 14:43
# @Auther:1043453579@qq.com from urllib.request import Request
from urllib.request import urlopen
import re, os class A(object):
def __init__(self):
self.header = {
'user-agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36',
#':authority':'m3u8.xingc.vip'
}
self.path = os.getcwd()
# self.static_url='https://cn2.zuixinbo.com'
self.static_url = ''
# self.r = redis.Redis(host='127.0.0.1',port=6379,db=0) def get_proxy(self):
return {'http': self.r.randomkey().deocode()} def down_1(self, url, referer='', code=True):
while True:
# proxy = self.get_proxy()
# 这里设置代理
try:
_ = self.header
if referer:
a = {'Referer': referer}
_.update(a)
res = urlopen(Request(url=url, headers=_), timeout=5).read()
if code:
res = res.decode()
if res:
return res
else:
raise 1
except Exception as e:
print('请求失败', url) def num_of_e(self, url_2): # 进入二级页面
res = self.down_1(url_2)
if res:
return res
else:
return None def take_middle_text(self, txt, txt_s, txt_e='', seeks=0, seeke=0):
# 取出中间文本,真返回中间文本,假返回False
# seeks有传参,会按照取前几位取值
# seeke有传参,会按照取后几位取值
try:
if txt_e or seeks or seeke:
pass
else:
raise 1
s_1 = txt.find(txt_s)
if s_1 == -1:
raise 1
l_1 = len(txt_s)
if txt_e:
s_2 = txt.find(txt_e)
if s_1 == -1 or s_2 == -1:
return False
return txt[s_1 + l_1:s_2]
if seeks:
return txt[s_1 - seeks:s_1]
if seeke:
return txt[s_1 + l_1:s_1 + l_1 + seeke]
except:
return '传参错误或未找到传参文本' def down_ts(self, list_1, path_1,url,temp_int):
import requests
for i in list_1:
path = os.path.join(path_1, i)
if os.path.exists(path):
print('已存在,跳过', i)
else:
while True:
try:
res = requests.get(url=url + i, headers=self.header,timeout=5)
if res:
with open(path, 'wb') as f:
f.write(res.content)
print('成功写入一条', i,temp_int)
break
except Exception as e:
print('requests写入失败',temp_int) def main(self, url,title):
_ = url.split('/')
_url="/".join(_[0:-1])+"/"
dict_1 = self.num_of_e(url) # '这里返回m3u8的内容'
m3u8_list=re.findall('\d+.ts',dict_1)
print(m3u8_list)
path = os.path.join(self.path, title)
if not os.path.exists(path):
os.mkdir(path) # 没有就创建一个新的目录
self.down_ts(m3u8_list, path,_url,len(m3u8_list)) if __name__ == '__main__':
#ex = ProcessPoolExecutor(3)
a_1 = A()
a='https:***/index.m3u8'
a_1.main(a,'name')

m3u8单文件,单线程下载(去代理)

2020-05-22 02:31:31

发现最近两年的视频基本都做了加密措施,综合网上的帖子,没有啥值得使用的地方,于此写下

aes-128加密系列 :男人的小视频梦想

使用工具:winhex

使用库命令:binascii.b2a_hex("二进文本")

有一朋友问我,一个小视频APP站做加密,怎么解不出来

m3u8文件上小图,如下:

解密如下:

好的,代码就不发了,自行根据上面的代码进行整改,解密代码如下

import binascii
from Crypto.Cipher import AES
with open('0.ts','rb+') as f:
a = f.read()
print(len(a)%16) #取余为0 就加16位,不为0 就加(16-余数)
a=a+b'\00'*16 #取余为0 就加16位,不为0 就加(16-余数)
print(a)
cryptos = AES.new(binascii.a2b_hex('5a43c7619623bc347fa7dcea3ddfb1b2'), AES.MODE_CBC,bytes.fromhex('3e420d580bd9244dd608850e0dec7ac8'))
c= cryptos.decrypt(a)
with open('0_2.ts','wb') as c1:
c1.write(c)

--解密AES

m3u8系列(一)练手spider的更多相关文章

  1. Python之路【第二十四篇】:Python学习路径及练手项目合集

      Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...

  2. 适合Python的5大练手项目, 你练了么?

    在练手项目的选择上,还存在疑问?不知道要从哪种项目先下手? 首先有两点建议: 最好不要写太应用的程序练手,要思考什么更像是知识,老只会写写爬虫是无用的,但是完全不写也不行. 对于练手的程序,要注意简化 ...

  3. 适合Python 新手的5大练手项目,你练了么?

    接下来就给大家介绍几种适合新手的练手项目. 0.算法系列-排序与查找 Python写swap很方便,就一句话(a, b = b, a),于是写基于比较的排序能短小精悍.刚上手一门新语言练算法最合适不过 ...

  4. 70个Python练手项目列表(都有完整教程)

    前言: 不管学习那门语言都希望能做出实际的东西来,这个实际的东西当然就是项目啦,不用多说大家都知道学编程语言一定要做项目才行. 这里整理了70个Python实战项目列表,都有完整且详细的教程,你可以从 ...

  5. 10个Python基础练习项目,你可能不会想到练手教程还这么有趣

    美国20世纪最重要的实用主义哲学家约翰·杜威提出一个学习方法,叫做:Learning By Doing,在实践中精进.胡适.陶行知.张伯苓.蒋梦麟等都曾是他的学生,杜威的哲学也影响了蔡元培.晏阳初等人 ...

  6. 简单的node爬虫练手,循环中的异步转同步

    简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...

  7. python新手70个练手项目

    不管学习哪门语言都希望能做出实际的东西来,这个实际的东西当然就是项目啦,不用多说大家都知道学编程语言一定要做项目才行. 这里整理了70个Python实战项目列表,都有完整且详细的教程,你可以从中选择自 ...

  8. Python学习路径及练手项目合集

    Python学习路径及练手项目合集 https://zhuanlan.zhihu.com/p/23561159

  9. Cocos2d-Lua (练手) 微信打飞机

    学习下lua,目前入门级,使用版本为 v3.3 Final For Win,空闲时间不足,只能断断续续写点东西.   一.子弹效果          子弹只做了一种,扇形发射,可以增加扇形大小,子弹的 ...

随机推荐

  1. LeetCode_121. Best Time to Buy and Sell Stock

    121. Best Time to Buy and Sell Stock Easy Say you have an array for which the ith element is the pri ...

  2. react 生命周期函数的一些心得体会

    一.理论 组件本质上是状态机,输入确定,输出一定确定 生命周期的三个阶段,三者时间是不固定的,只是在逻辑上的分类: 二.初始化阶段: getDefaultProps:获取实例的默认属性(即使没有生成实 ...

  3. Docker 跨主机网络 overlay(十六)

    目录 一.跨主机网络概述 二.准备 overlay 环境 1.环境描述 2.创建 consul 3.修改 docker 配置文件 4.准备就绪 三.创建 overlay 网络 1.在 host1 中创 ...

  4. Android 反编译技术流程

    为何需要反编译 作为一名Android开发者,很多的时候需要去学习别人优秀的代码,原本在GitHub上就有很多开源的项目代码,但有的时候在使用软件时候遇到自己想要的功能时,想要学习实现的代码时,这时候 ...

  5. AMD, CMD, CommonJS和UMD

    我的Github(https://github.com/tonyzheng1990/tonyzheng1990.github.io/issues),欢迎star 今天由于项目中引入的echarts的文 ...

  6. PHP反射API的使用、体会、说明

    最近开发支付宝相关功能的时候,由于支付宝的SDK比较落伍,不支持composer的方式加载,使用三方的composer SDK又觉得不放心 为了简化代码的调用方式,使用PHP的反射类针对支付宝官方SD ...

  7. Vue 开发技巧或者说Vue知识点梳理(转,自个学习)

    Vue 组件通讯 ——常见使用场景可以分为三类: 父子通信: 父向子传递数据是通过 props,子向父是通过 events($emit):通过父链 / 子链也可以通信($parent / $child ...

  8. S12. Android 检查更新功能实现

    [概述] 不需要从 App Store 或者指定官网直接下载,可以通过 App 直接更新到最新版本. [流程设计] 显示当前版本信息以及版本更新日志 提供 “检查更新” 按钮,点击事件处理逻辑: 1) ...

  9. DB2输出每隔10分钟的数据

    一.输出1-100的数据 此处参考 https://bbs.csdn.net/topics/390516027 with t(id) as ( as id from sysibm.sysdummy1 ...

  10. 使用内存地址点亮LED—跟51单片机一样写代码教学(初步入门)

    51单片机点亮一个小灯 #include <rge52.h> sbit LED = P0^ void main(void) { P0 = 0XFE; // 总线操作 sfr P0 0X80 ...