提交 ff03c615 编写于 作者: H hjdhnx

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

上级 6486f4b4
...@@ -13,7 +13,7 @@ warnings.filterwarnings('ignore') ...@@ -13,7 +13,7 @@ warnings.filterwarnings('ignore')
import os import os
from flask import Flask, jsonify, abort,request,redirect,make_response,render_template,send_from_directory,url_for 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 import error,parser
from utils.web import * from utils.web import *
import sys import sys
...@@ -28,10 +28,11 @@ app.config.from_object(config) # 单独的配置文件里写了,这里就不 ...@@ -28,10 +28,11 @@ app.config.from_object(config) # 单独的配置文件里写了,这里就不
# new_conf = get_conf(settings) # new_conf = get_conf(settings)
# print(new_conf) # print(new_conf)
print('自定义播放解析地址:',app.config.get('PLAY_URL')) print('自定义播放解析地址:',app.config.get('PLAY_URL'))
print('当前操作系统',sys.platform)
app.logger.name="drLogger" app.logger.name="drLogger"
db = SQLAlchemy(app) db = SQLAlchemy(app)
rule_list = getRules() rule_list = getRuleLists()
logger.info(rule_list) logger.info(rule_list)
logger.info(f'http://{getHost(1, 5705)}/index\nhttp://localhost:5705/index') logger.info(f'http://{getHost(1, 5705)}/index\nhttp://localhost:5705/index')
...@@ -42,6 +43,9 @@ from gevent.pywsgi import WSGIServer ...@@ -42,6 +43,9 @@ from gevent.pywsgi import WSGIServer
RuleClass = rule_classes.init(db) RuleClass = rule_classes.init(db)
PlayParse = play_parse.init(db) PlayParse = play_parse.init(db)
def is_linux():
return not 'win' in sys.platform
def getParmas(key=None,value=''): def getParmas(key=None,value=''):
""" """
获取链接参数 获取链接参数
...@@ -66,23 +70,27 @@ def forbidden(): # put application's code here ...@@ -66,23 +70,27 @@ def forbidden(): # put application's code here
def index(): # put application's code here def index(): # put application's code here
# logger.info("进入了首页") # logger.info("进入了首页")
manager = getHost(1).split(':')[0] + ':9001' 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') @app.route('/vod')
def vod(): def vod():
t0 = time()
rule = getParmas('rule') rule = getParmas('rule')
ext = getParmas('ext') ext = getParmas('ext')
if not ext.startswith('http') and not rule: if not ext.startswith('http') and not rule:
return jsonify(error.failed('规则字段必填')) return jsonify(error.failed('规则字段必填'))
rule_list = getRuleLists()
if not ext.startswith('http') and not rule in rule_list: if not ext.startswith('http') and not rule in rule_list:
msg = f'服务端本地仅支持以下规则:{",".join(rule_list)}' msg = f'服务端本地仅支持以下规则:{",".join(rule_list)}'
return jsonify(error.failed(msg)) return jsonify(error.failed(msg))
# logger.info(f'检验耗时:{get_interval(t0)}毫秒')
t1 = time() t1 = time()
js_path = f'js/{rule}.js' if not ext.startswith('http') else ext js_path = f'js/{rule}.js' if not ext.startswith('http') else ext
with open('js/模板.js', encoding='utf-8') as f: with open('js/模板.js', encoding='utf-8') as f:
before = f.read() 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() t2 = time()
ctx, js_code = parser.runJs(js_path,before=before) ctx, js_code = parser.runJs(js_path,before=before)
if not js_code: if not js_code:
...@@ -93,7 +101,7 @@ def vod(): ...@@ -93,7 +101,7 @@ def vod():
ruleDict['id'] = rule # 把路由请求的id装到字典里,后面播放嗅探才能用 ruleDict['id'] = rule # 把路由请求的id装到字典里,后面播放嗅探才能用
# print(rule) # print(rule)
# print(type(rule)) # print(type(rule))
# print(ruleDict)
logger.info(f'js装载耗时:{get_interval(t2)}毫秒') logger.info(f'js装载耗时:{get_interval(t2)}毫秒')
# print(rule) # print(rule)
cms = CMS(ruleDict,db,RuleClass,PlayParse,app.config) cms = CMS(ruleDict,db,RuleClass,PlayParse,app.config)
...@@ -249,6 +257,9 @@ def random_pics(): ...@@ -249,6 +257,9 @@ def random_pics():
@app.route('/config/<int:mode>') @app.route('/config/<int:mode>')
def config_render(mode): def config_render(mode):
# print(dict(app.config)) # 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)) html = render_template('config.txt',rules=getRules('js'),host=getHost(mode),mode=mode,jxs=getJxs(),config=dict(app.config))
response = make_response(html) response = make_response(html)
response.headers['Content-Type'] = 'application/json; charset=utf-8' response.headers['Content-Type'] = 'application/json; charset=utf-8'
......
...@@ -11,7 +11,7 @@ from utils.web import * ...@@ -11,7 +11,7 @@ from utils.web import *
from models import * from models import *
from utils.config import config from utils.config import config
from utils.log import logger 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.safePython import safePython
from utils.parser import runPy,runJScode from utils.parser import runPy,runJScode
from utils.htmlParser import jsoup from utils.htmlParser import jsoup
...@@ -22,8 +22,9 @@ from easydict import EasyDict as edict ...@@ -22,8 +22,9 @@ from easydict import EasyDict as edict
py_ctx = { py_ctx = {
'requests':requests,'print':print,'base64Encode':base64Encode,'baseDecode':baseDecode, '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: class CMS:
def __init__(self, rule, db=None, RuleClass=None, PlayParse=None,new_conf=None): def __init__(self, rule, db=None, RuleClass=None, PlayParse=None,new_conf=None):
...@@ -649,6 +650,8 @@ class CMS: ...@@ -649,6 +650,8 @@ class CMS:
}) })
ctx = py_ctx ctx = py_ctx
# print(ctx) # print(ctx)
jscode = getPreJs() + jscode
# print(jscode)
loader,_ = runJScode(jscode,ctx=ctx) loader,_ = runJScode(jscode,ctx=ctx)
# print(loader.toString()) # print(loader.toString())
play_url = loader.eval('input') play_url = loader.eval('input')
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import os import os
def getRules(): def getRuleLists():
base_path = os.path.dirname(os.path.abspath(__file__)) # 当前文件所在目录 base_path = os.path.dirname(os.path.abspath(__file__)) # 当前文件所在目录
# print(base_path) # print(base_path)
file_name = os.listdir(base_path) file_name = os.listdir(base_path)
...@@ -17,4 +17,4 @@ def getRules(): ...@@ -17,4 +17,4 @@ def getRules():
return rule_list return rule_list
if __name__ == '__main__': if __name__ == '__main__':
print(getRules()) print(getRuleLists())
\ No newline at end of file \ 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 = { ...@@ -12,6 +12,7 @@ var rule = {
class_parse:'.navbar-items li:gt(1):lt(8);a&&Text;a&&href;/(\\d+).html', class_parse:'.navbar-items li:gt(1):lt(8);a&&Text;a&&href;/(\\d+).html',
play_parse:true,//一般有免嗅才开,没免嗅还开只能服务器打印日志进行监听并重定向 play_parse:true,//一般有免嗅才开,没免嗅还开只能服务器打印日志进行监听并重定向
// lazy:'通用免嗅', // 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, 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', 推荐:'.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, // 推荐内容是否双层定位 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实现 #### dr模板的python实现
###### 更新日志 ###### 更新日志
###### 2022/08/30
- [X] 1.增加动态局域网ip获取
- [X] 2.增加js规则热加载(增删改不用重启)
- [X] 3.增加视界的加密库
- [X] 4.增加蓝莓影视免嗅探
###### 2022/08/29 ###### 2022/08/29
- [X] 1.更换js引擎,速度更快性能更好 - [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] 3.支持了js免嗅和常用的fetch,post方法
- [X] 4.配置uglifyjs可以把js代码压缩到一行(es5不支持多行js) - [X] 4.配置uglifyjs可以把js代码压缩到一行(es5不支持多行js)
###### 2022/08/28 ###### 2022/08/28
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
.btn{ .btn{
margin-bottom: 2rem; margin-bottom: 2rem;
border: 1px solid #615e5e; border: 1px solid #615e5e;
width: 180px; width: 240px;
height: 30px; height: 30px;
text-align: center; text-align: center;
background-color: #1379cb; background-color: #1379cb;
...@@ -32,6 +32,9 @@ a { ...@@ -32,6 +32,9 @@ a {
text-align: center; text-align: center;
line-height: 30px; line-height: 30px;
} }
.jyw{
margin-bottom: 5rem;
}
</style> </style>
<body style="background: #FFFFFF url(https://cdn.seovx.com/d/?mom=302) no-repeat fixed center;max-hright;"> <body style="background: #FFFFFF url(https://cdn.seovx.com/d/?mom=302) no-repeat fixed center;max-hright;">
...@@ -65,15 +68,22 @@ a { ...@@ -65,15 +68,22 @@ a {
<div class="btn"> <div class="btn">
<a href="http://{{ getHost(0) }}/config/0">本地配置地址</a> <a href="http://{{ getHost(0) }}/config/0">本地配置地址</a>
</div> </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="{{ 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) %} {% if '192.168' in getHost(1) %}
<div class="btn"> <div class="btn">
<a href="http://{{ getHost(1) }}/config/1">局域网配置地址</a> <a href="http://{{ getHost(1) }}/config/1">局域网配置地址</a>
</div> </div>
{% if is_linux %}
<div class="btn"> <div class="btn">
<a href="http://{{ manager }}" target="_blank">局域网在线进程管理</a> <a href="http://{{ manager }}" target="_blank">局域网在线进程管理[linux]</a>
</div> </div>
{% endif %}
<div class="btn"> <div class="btn">
<a href="http://{{ getHost(1) }}/pics" target="_blank">局域网随机图片</a> <a href="http://{{ getHost(1) }}/pics" target="_blank">局域网随机图片</a>
</div> </div>
......
...@@ -6,8 +6,27 @@ ...@@ -6,8 +6,27 @@
import base64 import base64
import requests import requests
import os
from utils.web import UC_UA 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): def base64Encode(text):
return base64.b64encode(text.encode("utf8")).decode("utf-8") #base64编码 return base64.b64encode(text.encode("utf8")).decode("utf-8") #base64编码
......
...@@ -35,23 +35,22 @@ def get_host_ip(): # 获取局域网ip ...@@ -35,23 +35,22 @@ def get_host_ip(): # 获取局域网ip
addresses = ''.join([i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr': ''}])]) addresses = ''.join([i['addr'] for i in ifaddresses(ifaceName).setdefault(AF_INET, [{'addr': ''}])])
ips.append(addresses) ips.append(addresses)
real_ips = list(filter(lambda x:x and x!='127.0.0.1',ips)) 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)) jyw = list(filter(lambda x:str(x).startswith('192.168'),real_ips))
return real_ips[-1] if len(jyw) < 1 else jyw[0] return real_ips[-1] if len(jyw) < 1 else jyw[0]
REAL_IP = get_host_ip()
def getHost(mode=0,port=None): def getHost(mode=0,port=None):
port = port or request.environ.get('SERVER_PORT') port = port or request.environ.get('SERVER_PORT')
# hostname = socket.gethostname() # hostname = socket.gethostname()
# ip = socket.gethostbyname(hostname) # ip = socket.gethostbyname(hostname)
ip = REAL_IP
# ip = request.remote_addr # ip = request.remote_addr
# print(ip) # print(ip)
# mode 为0是本地,1是局域网 2是线上 # mode 为0是本地,1是局域网 2是线上
if mode == 0: if mode == 0:
host = f'localhost:{port}' host = f'localhost:{port}'
elif mode == 1: elif mode == 1:
REAL_IP = get_host_ip()
ip = REAL_IP
host = f'{ip}:{port}' host = f'{ip}:{port}'
else: else:
host = 'cms.nokia.press' host = 'cms.nokia.press'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册