Skip to content

Commit e06a0f2

Browse files
author
Taois
committed
feat:增加源
1 parent 96fc915 commit e06a0f2

File tree

4 files changed

+862
-1
lines changed

4 files changed

+862
-1
lines changed

spider/catvod/蓝莓聚合短剧[B].js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spider/js/零度.js

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
/*
2+
@header({
3+
'类型': '影视',
4+
lang: 'ds'
5+
})
6+
*/
7+
8+
// 官方推荐安全的参数分割符合: *
9+
var rule = {
10+
title: 'Zero影视',
11+
host: 'http://ldys.sq1005.top',
12+
url: '/api/v1/app/screen/screenMovie',
13+
searchUrl: '/api/v1/app/search/searchMovie#keywords=**;post',
14+
searchable: 2,
15+
quickSearch: 1,
16+
filterable: 1,
17+
headers: {
18+
'HOST': 'ldys.sq1005.top',
19+
'User-Agent': 'okhttp/4.12.0',
20+
'client': 'app',
21+
'deviceType': 'Android',
22+
'Referer': ''
23+
},
24+
class_parse: async () => {
25+
let {HOST} = this;
26+
let html = await request(HOST + '/api/v1/app/screen/screenType', {
27+
headers: rule.headers,
28+
method: 'POST'
29+
});
30+
31+
let content = JSON.parse(html);
32+
let classes = [];
33+
let filterObj = {};
34+
35+
content.data.forEach(mainCate => {
36+
classes.push({
37+
type_id: mainCate.id,
38+
type_name: mainCate.name
39+
});
40+
41+
let filters = [];
42+
mainCate.children.forEach(subCate => {
43+
let filterType = '';
44+
switch (subCate.name) {
45+
case '类型':
46+
filterType = 'type';
47+
break;
48+
case '地区':
49+
filterType = 'area';
50+
break;
51+
case '年份':
52+
filterType = 'year';
53+
break;
54+
}
55+
56+
let filter = {
57+
key: filterType,
58+
name: subCate.name,
59+
value: subCate.children.map(item => ({
60+
n: item.name,
61+
v: item.name
62+
})),
63+
init: subCate.children[0].name
64+
};
65+
filters.push(filter);
66+
});
67+
68+
// 统一添加排序筛选器
69+
filters.push({
70+
key: 'sort',
71+
name: '排序',
72+
init: 'HOT',
73+
value: [{
74+
n: '最新',
75+
v: 'NEWEST'
76+
},
77+
{
78+
n: '热门',
79+
v: 'HOT'
80+
},
81+
{
82+
n: '收藏',
83+
v: 'COLLECT'
84+
}
85+
]
86+
});
87+
88+
filterObj[mainCate.id] = filters;
89+
});
90+
91+
log('classes:', classes)
92+
return {
93+
class: classes,
94+
filters: filterObj,
95+
}
96+
},
97+
98+
预处理: async () => {
99+
let dd = getdid();
100+
let token = await gettk(rule.host, dd);
101+
rule.headers['deviceId'] = dd;
102+
rule.headers['token'] = token;
103+
log("rule.headers>>>>>", rule.headers);
104+
rule.privateKey = `MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCquQQ5r6+yJI8CDFkXRp8vUsdD45ov8EP12ooLs56ca2DQXaSNGS9910bAPVA9chkp0mKIvKqjAsHz5Tl9EeNPblarGEeJUIxpxZtiSqNTpvtiD/TjhpzuHYic7RAfQ/h7p/ypE8ymU42pYjsB5t26Mv6XgkLV+jzrSf73HlCuS0iMyLmt6zz3Mw9izM13EpB8iFLtfbbYymycKTx4RAmPQLwhNGex/AlUIYxXP4R2yyaa4W6mEtc6aME2QuzJFxPgP3HJ9NBx/LWVn4skxWjZ7zg+VRQRHnjyVaSLu3Z5gN5ITWCyE32qaHJa6WBahZj5jWhRyAG1bQ+xKJa8lBL5AgMBAAECggEAUwv9SjJ0PSwbhNuM2w23kcWquROWhYtTA91zGY4esehqB/IFgb2mpIh8Gje5OKqwIu/8jpd4SiOlRYdUF8sD0DfUYRZGdj2AkFNX6tBz8tVfo6wvbB6naA1lzzBij1L5JO3qsjS3cJFkb+kg2yP66AC2Z+0tpfk8eRhdtshAZwfcd1DEGt1uAvYL1eaUK9HRvpt9lPeGcHERDl2hBd4uyaF0K1O+zF9y59nYbTySWPxRZq3sFEE85xRMlstD7YZi7W2gKvMFRD4/FKmrZ3m7aKJRITtyKOyyPcYmepNv3Qv7kk59Pg38n2WWQ0Ra/bCH3E48YNCnQvZMpitkTfJhoQKBgQDbnROOYTP8OTJ6f/qhoGjxeO3x1VOaOp8l0x7b0SCfoqNGS0Cyiqj72BmJtPMPqSTjn6MmNzqbg1KOdhXyzNozs+i5ccW1M56j96mr5I/Z0FpE3oyIHNfDDBlf9M8YQqEF9oYxniYYft9oapO7cRQkHER6qpvnHTavwlv4m78CXwKBgQDHAjs2YlpKDdI1lcbZJCc7TwtH+Pd2bUki8YXafWNcPhITQHbOZjr310eK1QJC6GJncjkOqbX7yv3ivvTO35FZTQhuA1xEG1P00FG8bE0tHYPIwQHi9y0eA5cieMdo8E6XYria1mw/3fqSQEsfZyJlR32JQIoGAipM8iO1X2nZpwKBgDkMFIhnt5lNQk+P7wsNIDWZtDWdtJnboHuy29E+Abt2A/O+mI/IdRz2hau/1WO8DFkUnszOi+rZshhPlGP90rCbi1igtTrcrdjp/KkqNjPea5R4OwkgdOu1uOG0NheXNzzVTQaWjk7Opjn5dWa7eP/oV+GFb/oZHJuLYVizHGsBAoGADA7rjZEKDYCm4w5PPSr+oY5ZjaPdQrS+gLqHtMRyN82fBMGcMUdqfUfzEstzVqCEDeaS5HuOBlK3bXzKkppjUTjksN3NQmcxgBz7RuJ9DqXCLXDcb2cwuafYCYOt+YLOEEgwDVm+t2P44dG5e46hO+fICH/7nP+WlpD5buz4GfMCgYB57r3g/6hi9WUDnfc7ZAzWMqR0EhJVYKYy+KFEtdIPzhkkIHq5RASe88E9kzoGoZFdb3tIjvGZWcHerirrqWkMsuQtP/Qi0zjieid5tAPj+r4kbiCVTw0E0jnmPBzGInQi7lpeTTKnG1fbyS5lBS+WmHfIuzpECgCkxhaT+LJJkg==`;
105+
rule.publicKey = `MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoYt0BP77U+DM08BiI/QbSRIfxijXo85BTPqIM1Ow8BNwhLETzRIZ+dEwdWDbydG/PspgBAfRpGaYVdJYtvaC2JnoO8+Ik6qMWojfEJxSFLa0Pb0A892tun4gsxoEMjcreZ+YGyaBxAfqX0BSMfdrOgIYaZQjYrw9TRLlUT31QoQIDAQAB`;
106+
rule.options = {
107+
block: true,
108+
long: 2,
109+
type: 1
110+
};
111+
},
112+
113+
一级: $js.toString(async () => {
114+
let params = {
115+
condition: {
116+
sreecnTypeEnum: 'NEWEST',
117+
typeId: MY_CATE
118+
},
119+
pageNum: MY_PAGE,
120+
pageSize: 40
121+
};
122+
let data = JSON.parse(await request(HOST + '/api/v1/app/screen/screenMovie', {
123+
headers: rule.headers,
124+
body: params,
125+
method: 'POST'
126+
})).data;
127+
128+
let d = data.records.map(item => ({
129+
title: item.name,
130+
desc: item.totalEpisode,
131+
pic_url: item.cover,
132+
url: HOST + '/api/v1/app/play/movieDesc' + '*' + item.id + '*' + item.typeId
133+
}));
134+
return setResult(d);
135+
}),
136+
137+
二级: $js.toString(async () => {
138+
console.log("input>>>>>" + input);
139+
console.log("MY_URL>>>>>" + MY_URL);
140+
let [url, id, typeId] = MY_URL.split('*');
141+
console.log("id>>>>>" + id);
142+
console.log("typeId>>>>>" + typeId);
143+
144+
// 获取详情信息
145+
let detailParams = {
146+
"id": parseInt(id),
147+
"typeId": typeId
148+
};
149+
150+
let detailRes = await request(HOST + '/api/v1/app/play/movieDesc', {
151+
headers: rule.headers,
152+
body: detailParams,
153+
method: "POST"
154+
});
155+
let detail = JSON.parse(detailRes).data;
156+
log("movieDesc:" + JSON.stringify(detail));
157+
158+
// 获取播放列表
159+
let playParams = {
160+
"key": RSA.encode(JSON.stringify({
161+
"id": parseInt(id),
162+
"source": 0,
163+
"typeId": typeId
164+
}), rule.publicKey, rule.options)
165+
};
166+
167+
let playDataRes = await request(HOST + '/api/v1/app/play/movieDetails', {
168+
headers: rule.headers,
169+
body: playParams,
170+
method: "POST"
171+
});
172+
173+
let playData = JSON.parse(playDataRes).data;
174+
175+
let decryptedData = JSON.parse(await RSA.decode(playData, rule.privateKey, rule.options));
176+
log("movieDetails:", decryptedData);
177+
178+
// 处理播放列表
179+
let playMap = {};
180+
for (const player of decryptedData.moviePlayerList) {
181+
let episodeParams = {
182+
"key": RSA.encode(JSON.stringify({
183+
"id": parseInt(id),
184+
"source": 0,
185+
"typeId": typeId,
186+
"playerId": player.id
187+
}), rule.publicKey, rule.options)
188+
};
189+
190+
let episodeRes = await request(HOST + '/api/v1/app/play/movieDetails', {
191+
headers: rule.headers,
192+
body: episodeParams,
193+
method: "POST"
194+
});
195+
196+
let episodeData = JSON.parse(episodeRes).data;
197+
198+
let decryptedEpisode = JSON.parse(RSA.decode(episodeData, rule.privateKey, rule.options));
199+
log('decryptedEpisode:', decryptedEpisode)
200+
playMap[player.id] = decryptedEpisode.episodeList.map(ep => {
201+
let param = {
202+
id,
203+
typeId,
204+
playerId: player.id,
205+
episodeId: ep.id
206+
};
207+
return ep.episode + '$' + btoa(unescape(encodeURIComponent(JSON.stringify(param))));
208+
}).join('#');
209+
}
210+
211+
VOD = {
212+
vod_name: detail.name,
213+
vod_pic: detail.cover,
214+
vod_year: detail.year,
215+
vod_area: detail.area,
216+
vod_remarks: detail.totalEpisode,
217+
vod_actor: detail.star,
218+
vod_content: detail.introduce,
219+
vod_play_from: decryptedData.moviePlayerList.map(p => p.moviePlayerName).join('$$$'),
220+
vod_play_url: Object.values(playMap).join('$$$')
221+
};
222+
return VOD
223+
}),
224+
225+
搜索: $js.toString(async () => {
226+
let params = {
227+
condition: {
228+
value: KEY
229+
},
230+
pageNum: MY_PAGE,
231+
pageSize: 40
232+
};
233+
let data = JSON.parse(await request(HOST + '/api/v1/app/search/searchMovie', {
234+
headers: rule.headers,
235+
body: params,
236+
method: 'POST'
237+
})).data;
238+
log("data>>>>>" + data)
239+
let d = data.records.map(item => ({
240+
title: item.name,
241+
desc: item.totalEpisode,
242+
pic_url: item.cover,
243+
url: HOST + '/api/v1/app/play/movieDesc' + '*' + item.id + '*' + item.typeId
244+
}));
245+
return setResult(d);
246+
}),
247+
248+
play_parse: true,
249+
lazy: $js.toString(async () => {
250+
let param = JSON.parse(base64Decode(input));
251+
log("param>>>>>" + JSON.stringify(param));
252+
log("id>>>>>" + param.id);
253+
let urlParams = {
254+
"key": RSA.encode(JSON.stringify({
255+
"id": param.id,
256+
"source": 0,
257+
"typeId": param.typeId,
258+
"playerId": param.playerId,
259+
"episodeId": param.episodeId
260+
}), rule.publicKey, rule.options)
261+
};
262+
263+
const postData = await request(`${HOST}/api/v1/app/play/movieDetails`, {
264+
headers: rule.headers,
265+
body: urlParams,
266+
method: 'POST'
267+
});
268+
269+
const encryptedUrl = JSON.parse(postData).data;
270+
const playerUrl = JSON.parse(RSA.decode(encryptedUrl, rule.privateKey, rule.options)).url;
271+
log("playerUrl>>>>>" + playerUrl);
272+
273+
const getResponse = await request(HOST + '/api/v1/app/play/analysisMovieUrl?playerUrl=' + encodeURIComponent(playerUrl) + '&playerId=' + param.playerId, {
274+
headers: rule.headers
275+
});
276+
log("getResponse>>>>>", getResponse);
277+
278+
const player = JSON.parse(getResponse).data;
279+
log("player>>>>>" + player);
280+
return {
281+
parse: 0,
282+
url: player
283+
};
284+
}),
285+
}
286+
287+
async function gettk(HOST, dd) {
288+
let res = JSON.parse(await request(HOST + '/api/v1/app/user/visitorInfo', {
289+
headers: {
290+
'HOST': 'ldys.sq1005.top',
291+
'User-Agent': 'okhttp/4.12.0',
292+
'client': 'app',
293+
'deviceType': 'Android',
294+
'Referer': '',
295+
'deviceId': dd
296+
}
297+
}));
298+
return res.data.token;
299+
}
300+
301+
function getdid() {
302+
let did = getItem('ldid');
303+
if (!did) {
304+
const hex = '0123456789abcdef';
305+
did = Array.from({
306+
length: 16
307+
}, () => hex[Math.floor(Math.random() * 16)]).join('');
308+
setItem('ldid', did);
309+
}
310+
return did;
311+
}

0 commit comments

Comments
 (0)