提交 ff03c615 编写于 作者: H hjdhnx

蓝莓影视免嗅探播放搞定,我简直是牛逼到天下第一,心情大好

上级 6486f4b4
......@@ -13,7 +13,7 @@ warnings.filterwarnings('ignore')
import os
from flask import Flask, jsonify, abort,request,redirect,make_response,render_template,send_from_directory,url_for
from js.rules import getRules
from js.rules import getRuleLists
from utils import error,parser
from utils.web import *
import sys
......@@ -28,10 +28,11 @@ app.config.from_object(config) # 单独的配置文件里写了,这里就不
# new_conf = get_conf(settings)
# print(new_conf)
print('自定义播放解析地址:',app.config.get('PLAY_URL'))
print('当前操作系统',sys.platform)
app.logger.name="drLogger"
db = SQLAlchemy(app)
rule_list = getRules()
rule_list = getRuleLists()
logger.info(rule_list)
logger.info(f'http://{getHost(1, 5705)}/index\nhttp://localhost:5705/index')
......@@ -42,6 +43,9 @@ from gevent.pywsgi import WSGIServer
RuleClass = rule_classes.init(db)
PlayParse = play_parse.init(db)
def is_linux():
return not 'win' in sys.platform
def getParmas(key=None,value=''):
"""
获取链接参数
......@@ -66,23 +70,27 @@ def forbidden(): # put application's code here
def index(): # put application's code here
# logger.info("进入了首页")
manager = getHost(1).split(':')[0] + ':9001'
return render_template('index.html',getHost=getHost,manager=manager)
manager2 = getHost(0).split(':')[0] + ':9001'
return render_template('index.html',getHost=getHost,manager=manager,manager2=manager2,is_linux=is_linux())
@app.route('/vod')
def vod():
t0 = time()
rule = getParmas('rule')
ext = getParmas('ext')
if not ext.startswith('http') and not rule:
return jsonify(error.failed('规则字段必填'))
rule_list = getRuleLists()
if not ext.startswith('http') and not rule in rule_list:
msg = f'服务端本地仅支持以下规则:{",".join(rule_list)}'
return jsonify(error.failed(msg))
# logger.info(f'检验耗时:{get_interval(t0)}毫秒')
t1 = time()
js_path = f'js/{rule}.js' if not ext.startswith('http') else ext
with open('js/模板.js', encoding='utf-8') as f:
before = f.read()
logger.info(f'js读取耗时:{get_interval(t1)}毫秒')
# logger.info(f'js读取耗时:{get_interval(t1)}毫秒')
logger.info(f'参数检验js读取共计耗时:{get_interval(t0)}毫秒')
t2 = time()
ctx, js_code = parser.runJs(js_path,before=before)
if not js_code:
......@@ -93,7 +101,7 @@ def vod():
ruleDict['id'] = rule # 把路由请求的id装到字典里,后面播放嗅探才能用
# print(rule)
# print(type(rule))
# print(ruleDict)
logger.info(f'js装载耗时:{get_interval(t2)}毫秒')
# print(rule)
cms = CMS(ruleDict,db,RuleClass,PlayParse,app.config)
......@@ -249,6 +257,9 @@ def random_pics():
@app.route('/config/<int:mode>')
def config_render(mode):
# print(dict(app.config))
if mode == 1:
jyw_ip = getHost(mode)
logger.info(jyw_ip)
html = render_template('config.txt',rules=getRules('js'),host=getHost(mode),mode=mode,jxs=getJxs(),config=dict(app.config))
response = make_response(html)
response.headers['Content-Type'] = 'application/json; charset=utf-8'
......
......@@ -11,7 +11,7 @@ from utils.web import *
from models import *
from utils.config import config
from utils.log import logger
from utils.encode import base64Encode,baseDecode,fetch,post,request
from utils.encode import base64Encode,baseDecode,fetch,post,request,getCryptoJS,getPreJs
from utils.safePython import safePython
from utils.parser import runPy,runJScode
from utils.htmlParser import jsoup
......@@ -22,8 +22,9 @@ from easydict import EasyDict as edict
py_ctx = {
'requests':requests,'print':print,'base64Encode':base64Encode,'baseDecode':baseDecode,
'log':logger.info,'fetch':fetch,'post':post,'request':request
'log':logger.info,'fetch':fetch,'post':post,'request':request,'getCryptoJS':getCryptoJS
}
# print(getCryptoJS())
class CMS:
def __init__(self, rule, db=None, RuleClass=None, PlayParse=None,new_conf=None):
......@@ -649,6 +650,8 @@ class CMS:
})
ctx = py_ctx
# print(ctx)
jscode = getPreJs() + jscode
# print(jscode)
loader,_ = runJScode(jscode,ctx=ctx)
# print(loader.toString())
play_url = loader.eval('input')
......
......@@ -6,7 +6,7 @@
import os
def getRules():
def getRuleLists():
base_path = os.path.dirname(os.path.abspath(__file__)) # 当前文件所在目录
# print(base_path)
file_name = os.listdir(base_path)
......@@ -17,4 +17,4 @@ def getRules():
return rule_list
if __name__ == '__main__':
print(getRules())
\ No newline at end of file
print(getRuleLists())
\ No newline at end of file
var rule = Object.assign(muban.mxpro,{
title:'看视界',
host:'https://www.1080kan.cc',
url:'/show/fyclass--------fypage---.html',
searchUrl:'/search/**-------------.html',
class_parse:'.navbar-items li:gt(1):lt(6);a&&Text;a&&href;.*/(.*?).html',
});
\ No newline at end of file
......@@ -12,6 +12,7 @@ var rule = {
class_parse:'.navbar-items li:gt(1):lt(8);a&&Text;a&&href;/(\\d+).html',
play_parse:true,//一般有免嗅才开,没免嗅还开只能服务器打印日志进行监听并重定向
// lazy:'通用免嗅',
lazy:'js:var MY_HOME="http://lanmeiguojiang.com:5244/d/%E8%93%9D%E8%8E%93%E4%BA%91%E7%9B%98";let fetch_params={headers:d.headers,timeout:d.timeout,encoding:d.encoding};let html=fetch(input,fetch_params);var player=JSON.parse(html.match(/r player_.*?=(.*?)</)[1]);var jsurl=player.url;var from=player.from;if(player.encrypt=="1"){var jsurl=unescape(jsurl)}else if(player.encrypt=="2"){var jsurl=unescape(base64Decode(jsurl))}else{jsurl}eval(getCryptoJS());if(/ddzy|duoduo/.test(from)){eval(fetch(MY_HOME+"/pzwj.js",fetch_params));var jx=MacPlayerConfig.player_list[from].parse;eval(request(jx+jsurl,{headers:{Referer:input}}).match(/var config = {[\\s\\S]*?}/)[0]);jx=jx.replace("?url=","");eval(request(jx+"js/decode.js"));jxk=request(jx+"js/setting.js").split(",");jx+="555tZ4pvzHE3BpiO838.php";config.tm=(new Date).getTime();config.sign="F4penExTGogdt6U8";input=getVideoInfo(JSON.parse(fetch(buildUrl(jx,config))).url)}else{let jxurl="https://lanmeiguojiang.com/dd/?url="+jsurl;input=maoss(jxurl,jxurl,"A42EAC0C2B408472")}',
limit:30,
推荐:'.tab-list.active;a.module-poster-item.module-item;.module-poster-item-title&&Text;.lazyload&&data-original;.module-item-note&&Text;a&&href',
double:true, // 推荐内容是否双层定位
......
此差异已折叠。
//猫函数
function maoss(jxurl, ref, key) {
eval(getCryptoJS());
try {
var getVideoInfo = function(text) {
return CryptoJS.AES.decrypt(text, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8);
};
var token_key = key == undefined ? 'dvyYRQlnPRCMdQSe' : key;
if (ref) {
var html = request(jxurl, {
headers: {
'Referer': ref
}
});
} else {
var html = request(jxurl);
}
if (html.indexOf('&btwaf=') != -1) {
html = request(jxurl + '&btwaf' + html.match(/&btwaf(.*?)"/)[1], {
headers: {
'Referer': ref
}
})
}
var token_iv = html.split('_token = "')[1].split('"')[0];
var key = CryptoJS.enc.Utf8.parse(token_key);
var iv = CryptoJS.enc.Utf8.parse(token_iv);
// log("iv:"+iv);
// log(html);
eval(html.match(/var config = {[\s\S]*?}/)[0] + '');
if (config.url.slice(0, 4) != 'http') {
//config.url = decodeURIComponent(AES(config.url, key, iv));
config.url = CryptoJS.AES.decrypt(config.url, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8)
}
return config.url;
} catch (e) {
return '';
}
}
\ No newline at end of file
无法预览此类型文件
js:
var MY_HOME='http://lanmeiguojiang.com:5244/d/%E8%93%9D%E8%8E%93%E4%BA%91%E7%9B%98';
let fetch_params = {headers:d.headers,timeout:d.timeout,encoding:d.encoding};
let html = fetch(input,fetch_params);
var player = JSON.parse(html.match(/r player_.*?=(.*?)</)[1]);
var jsurl = player.url;
var from = player.from;
if (player.encrypt == '1') {
var jsurl = unescape(jsurl);
} else if (player.encrypt == '2') {
var jsurl = unescape(base64Decode(jsurl));
} else {
jsurl
}
eval(getCryptoJS());
if (/ddzy|duoduo/.test(from)) {
eval(fetch(MY_HOME + '/pzwj.js',fetch_params));
var jx = MacPlayerConfig.player_list[from].parse;
eval(request(jx + jsurl, {
headers: {
'Referer': input
}
}).match(/var config = {[\s\S]*?}/)[0]);
jx = jx.replace('?url=', '');
eval(request(jx + 'js/decode.js'));
jxk = request(jx + 'js/setting.js').split(',');
jx += '555tZ4pvzHE3BpiO838.php'; //eval(jxk[32])
config.tm = new Date().getTime();
config.sign = 'F4penExTGogdt6U8'; //eval(jxk[36])
input = getVideoInfo(JSON.parse(fetch(buildUrl(jx, config))).url);
} else {
let jxurl = "https://lanmeiguojiang.com/dd/?url="+jsurl;
input = maoss(jxurl, jxurl, "A42EAC0C2B408472");
}
\ No newline at end of file
#### dr模板的python实现
###### 更新日志
###### 2022/08/30
- [X] 1.增加动态局域网ip获取
- [X] 2.增加js规则热加载(增删改不用重启)
- [X] 3.增加视界的加密库
- [X] 4.增加蓝莓影视免嗅探
###### 2022/08/29
- [X] 1.更换js引擎,速度更快性能更好
- [X] 2.新版js支持与python互动,后期可能支持js免嗅(lazy:'@js:xxx')
- [X] 2.新版js支持与python互动,后期可能支持js免嗅(lazy:'js:xxx')
- [X] 3.支持了js免嗅和常用的fetch,post方法
- [X] 4.配置uglifyjs可以把js代码压缩到一行(es5不支持多行js)
###### 2022/08/28
......
......@@ -14,7 +14,7 @@
.btn{
margin-bottom: 2rem;
border: 1px solid #615e5e;
width: 180px;
width: 240px;
height: 30px;
text-align: center;
background-color: #1379cb;
......@@ -32,6 +32,9 @@ a {
text-align: center;
line-height: 30px;
}
.jyw{
margin-bottom: 5rem;
}
</style>
<body style="background: #FFFFFF url(https://cdn.seovx.com/d/?mom=302) no-repeat fixed center;max-hright;">
......@@ -65,15 +68,22 @@ a {
<div class="btn">
<a href="http://{{ getHost(0) }}/config/0">本地配置地址</a>
</div>
{% if is_linux %}
<div class="btn">
<a href="http://{{ manager2 }}" target="_blank">本地在线进程管理[linux]</a>
</div>
{% endif %}
<!--<a href="{{ getHost(1) }}">局域网:{{ getHost(1) }}</a>-->
<a href="https://picsum.photos/1280/720/?blur=10">局域网:{{ getHost(1) }}</a>
<a class="jyw" href="https://picsum.photos/1280/720/?blur=10">局域网:{{ getHost(1) }}</a>
{% if '192.168' in getHost(1) %}
<div class="btn">
<a href="http://{{ getHost(1) }}/config/1">局域网配置地址</a>
</div>
{% if is_linux %}
<div class="btn">
<a href="http://{{ manager }}" target="_blank">局域网在线进程管理</a>
<a href="http://{{ manager }}" target="_blank">局域网在线进程管理[linux]</a>
</div>
{% endif %}
<div class="btn">
<a href="http://{{ getHost(1) }}/pics" target="_blank">局域网随机图片</a>
</div>
......
......@@ -6,8 +6,27 @@
import base64
import requests
import os
from utils.web import UC_UA
def getPreJs():
base_path = os.path.dirname(os.path.abspath(os.path.dirname(__file__))) # 上级目
lib_path = os.path.join(base_path, f'libs/pre.js')
with open(lib_path,encoding='utf-8') as f:
code = f.read()
return code
def getCryptoJS():
base_path = os.path.dirname(os.path.abspath(os.path.dirname(__file__))) # 上级目
os.makedirs(os.path.join(base_path, f'libs'), exist_ok=True)
lib_path = os.path.join(base_path, f'libs/crypto-hiker.js')
# print('加密库地址:', lib_path)
if not os.path.exists(lib_path):
return 'undefiend'
with open(lib_path,encoding='utf-8') as f:
code = f.read()
return code
def base64Encode(text):
return base64.b64encode(text.encode("utf8")).decode("utf-8") #base64编码
......
......@@ -35,23 +35,22 @@ def get_host_ip(): # 获取局域网ip
addresses = ''.join([i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr': ''}])])
ips.append(addresses)
real_ips = list(filter(lambda x:x and x!='127.0.0.1',ips))
logger.info(real_ips)
# logger.info(real_ips)
jyw = list(filter(lambda x:str(x).startswith('192.168'),real_ips))
return real_ips[-1] if len(jyw) < 1 else jyw[0]
REAL_IP = get_host_ip()
def getHost(mode=0,port=None):
port = port or request.environ.get('SERVER_PORT')
# hostname = socket.gethostname()
# ip = socket.gethostbyname(hostname)
ip = REAL_IP
# ip = request.remote_addr
# print(ip)
# mode 为0是本地,1是局域网 2是线上
if mode == 0:
host = f'localhost:{port}'
elif mode == 1:
REAL_IP = get_host_ip()
ip = REAL_IP
host = f'{ip}:{port}'
else:
host = 'cms.nokia.press'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册