sp360.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. /*
  2. * @File : sp360.js
  3. * @Author : jade
  4. * @Date : 2024/3/21 11:18
  5. * @Email : jadehh@1ive.com
  6. * @Software : Samples
  7. * @Desc : SP360(需要用到解析)
  8. */
  9. import {Spider} from "./spider.js";
  10. import {_, Crypto, load} from "../lib/cat.js";
  11. import {VodDetail, VodShort} from "../lib/vod.js";
  12. import * as Utils from "../lib/utils.js";
  13. class Sp360Spider extends Spider {
  14. constructor() {
  15. super();
  16. this.siteUrl = "https://api.web.360kan.com"
  17. }
  18. getName() {
  19. return "🥎┃360影视┃🥎"
  20. }
  21. getAppName() {
  22. return "360"
  23. }
  24. getJSName() {
  25. return "sp360"
  26. }
  27. getType() {
  28. return 3
  29. }
  30. async init(cfg) {
  31. await super.init(cfg);
  32. this.danmuStaus = true
  33. }
  34. async setClasses() {
  35. this.classes = [this.getTypeDic("最近更新", "最近更新"), this.getTypeDic("电影", "1"), this.getTypeDic("剧集", "2"), this.getTypeDic("综艺", "3"), this.getTypeDic("动漫", "4")]
  36. }
  37. async setFilterObj() {
  38. this.filterObj = {
  39. "1": [{
  40. "key": "cat", "name": "类型", "value": [{
  41. "n": "全部", "v": ""
  42. }, {
  43. "n": "喜剧", "v": "喜剧"
  44. }, {
  45. "n": "爱情", "v": "爱情"
  46. }, {
  47. "n": "动作", "v": "动作"
  48. }, {
  49. "n": "恐怖", "v": "恐怖"
  50. }, {
  51. "n": "科幻", "v": "科幻"
  52. }, {
  53. "n": "剧情", "v": "剧情"
  54. }, {
  55. "n": "犯罪", "v": "犯罪"
  56. }, {
  57. "n": "奇幻", "v": "奇幻"
  58. }, {
  59. "n": "战争", "v": "战争"
  60. }, {
  61. "n": "悬疑", "v": "悬疑"
  62. }, {
  63. "n": "动画", "v": "动画"
  64. }, {
  65. "n": "文艺", "v": "文艺"
  66. }, {
  67. "n": "纪录", "v": "纪录"
  68. }, {
  69. "n": "传记", "v": "传记"
  70. }, {
  71. "n": "歌舞", "v": "歌舞"
  72. }, {
  73. "n": "古装", "v": "古装"
  74. }, {
  75. "n": "历史", "v": "历史"
  76. }, {
  77. "n": "惊悚", "v": "惊悚"
  78. }, {
  79. "n": "伦理", "v": "伦理"
  80. }, {
  81. "n": "其他", "v": "其他"
  82. }]
  83. }, {
  84. "key": "year", "name": "年代", "value": [{
  85. "n": "全部", "v": ""
  86. }, {
  87. "n": "2024", "v": "2024"
  88. }, {
  89. "n": "2023", "v": "2023"
  90. }, {
  91. "n": "2022", "v": "2022"
  92. }, {
  93. "n": "2021", "v": "2021"
  94. }, {
  95. "n": "2020", "v": "2020"
  96. }, {
  97. "n": "2019", "v": "2019"
  98. }, {
  99. "n": "2018", "v": "2018"
  100. }, {
  101. "n": "2017", "v": "2017"
  102. }, {
  103. "n": "2016", "v": "2016"
  104. }, {
  105. "n": "2015", "v": "2015"
  106. }, {
  107. "n": "2014", "v": "2014"
  108. }, {
  109. "n": "2013", "v": "2013"
  110. }, {
  111. "n": "2012", "v": "2012"
  112. }, {
  113. "n": "2010", "v": "2010"
  114. }, {
  115. "n": "2009", "v": "2009"
  116. }, {
  117. "n": "2008", "v": "2008"
  118. }, {
  119. "n": "2007", "v": "2007"
  120. }, {
  121. "n": "更早", "v": "lt_year"
  122. }]
  123. }, {
  124. "key": "area", "name": "地区", "value": [{
  125. "n": "全部", "v": ""
  126. }, {
  127. "n": "内地", "v": "大陆"
  128. }, {
  129. "n": "中国香港", "v": "香港"
  130. }, {
  131. "n": "中国台湾", "v": "台湾"
  132. }, {
  133. "n": "泰国", "v": "泰国"
  134. }, {
  135. "n": "美国", "v": "美国"
  136. }, {
  137. "n": "韩国", "v": "韩国"
  138. }, {
  139. "n": "日本", "v": "日本"
  140. }, {
  141. "n": "法国", "v": "法国"
  142. }, {
  143. "n": "英国", "v": "英国"
  144. }, {
  145. "n": "德国", "v": "德国"
  146. }, {
  147. "n": "印度", "v": "印度"
  148. }, {
  149. "n": "其他", "v": "其他"
  150. }]
  151. }, {
  152. "key": "rank", "name": "排序", "value": [{
  153. "n": "最近热映", "v": "rankhot"
  154. }, {
  155. "n": "最近上映", "v": "ranklatest"
  156. }, {
  157. "n": "最受好评", "v": "rankpoint"
  158. }]
  159. }], "2": [{
  160. "key": "cat", "name": "类型", "value": [{
  161. "n": "全部", "v": ""
  162. }, {
  163. "n": "言情", "v": "言情"
  164. }, {
  165. "n": "剧情", "v": "剧情"
  166. }, {
  167. "n": "伦理", "v": "伦理"
  168. }, {
  169. "n": "喜剧", "v": "喜剧"
  170. }, {
  171. "n": "悬疑", "v": "悬疑"
  172. }, {
  173. "n": "都市", "v": "都市"
  174. }, {
  175. "n": "偶像", "v": "偶像"
  176. }, {
  177. "n": "古装", "v": "古装"
  178. }, {
  179. "n": "军事", "v": "军事"
  180. }, {
  181. "n": "警匪", "v": "警匪"
  182. }, {
  183. "n": "历史", "v": "历史"
  184. }, {
  185. "n": "励志", "v": "励志"
  186. }, {
  187. "n": "神话", "v": "神话"
  188. }, {
  189. "n": "谍战", "v": "谍战"
  190. }, {
  191. "n": "青春", "v": "青春剧"
  192. }, {
  193. "n": "家庭", "v": "家庭剧"
  194. }, {
  195. "n": "动作", "v": "动作"
  196. }, {
  197. "n": "情景", "v": "情景"
  198. }, {
  199. "n": "武侠", "v": "武侠"
  200. }, {
  201. "n": "科幻", "v": "科幻"
  202. }, {
  203. "n": "其他", "v": "其他"
  204. }, {
  205. "n": "全部", "v": ""
  206. }]
  207. }, {
  208. "key": "year", "name": "年代", "value": [{
  209. "n": "2024", "v": "2024"
  210. }, {
  211. "n": "2023", "v": "2023"
  212. }, {
  213. "n": "2022", "v": "2022"
  214. }, {
  215. "n": "2021", "v": "2021"
  216. }, {
  217. "n": "2020", "v": "2020"
  218. }, {
  219. "n": "2019", "v": "2019"
  220. }, {
  221. "n": "2018", "v": "2018"
  222. }, {
  223. "n": "2017", "v": "2017"
  224. }, {
  225. "n": "2016", "v": "2016"
  226. }, {
  227. "n": "2015", "v": "2015"
  228. }, {
  229. "n": "2014", "v": "2014"
  230. }, {
  231. "n": "2013", "v": "2013"
  232. }, {
  233. "n": "2012", "v": "2012"
  234. }, {
  235. "n": "2010", "v": "2010"
  236. }, {
  237. "n": "2009", "v": "2009"
  238. }, {
  239. "n": "2008", "v": "2008"
  240. }, {
  241. "n": "2007", "v": "2007"
  242. }, {
  243. "n": "更早", "v": "lt_year"
  244. }]
  245. }, {
  246. "key": "area", "name": "地区", "value": [{
  247. "n": "全部", "v": ""
  248. }, {
  249. "n": "内地", "v": "内地"
  250. }, {
  251. "n": "中国香港", "v": "香港"
  252. }, {
  253. "n": "中国台湾", "v": "台湾"
  254. }, {
  255. "n": "泰国", "v": "泰国"
  256. }, {
  257. "n": "日本", "v": "日本"
  258. }, {
  259. "n": "韩国", "v": "韩国"
  260. }, {
  261. "n": "美国", "v": "美国"
  262. }, {
  263. "n": "英国", "v": "英国"
  264. }, {
  265. "n": "新加坡", "v": "新加坡"
  266. }]
  267. }, {
  268. "key": "rank", "name": "排序", "value": [{
  269. "n": "最近热映", "v": "rankhot"
  270. }, {
  271. "n": "最近上映", "v": "ranklatest"
  272. }, {
  273. "n": "最受好评", "v": "rankpoint"
  274. }]
  275. }], "3": [{
  276. "key": "cat", "name": "类型", "value": [{
  277. "n": "全部", "v": ""
  278. }, {
  279. "n": "脱口秀", "v": "脱口秀"
  280. }, {
  281. "n": "真人秀", "v": "真人秀"
  282. }, {
  283. "n": "搞笑", "v": "搞笑"
  284. }, {
  285. "n": "选秀", "v": "选秀"
  286. }, {
  287. "n": "八卦", "v": "八卦"
  288. }, {
  289. "n": "访谈", "v": "访谈"
  290. }, {
  291. "n": "情感", "v": "情感"
  292. }, {
  293. "n": "生活", "v": "生活"
  294. }, {
  295. "n": "晚会", "v": "晚会"
  296. }, {
  297. "n": "音乐", "v": "音乐"
  298. }, {
  299. "n": "职场", "v": "职场"
  300. }, {
  301. "n": "美食", "v": "美食"
  302. }, {
  303. "n": "时尚", "v": "时尚"
  304. }, {
  305. "n": "游戏", "v": "游戏"
  306. }, {
  307. "n": "少儿", "v": "少儿"
  308. }, {
  309. "n": "体育", "v": "体育"
  310. }, {
  311. "n": "纪实", "v": "纪实"
  312. }, {
  313. "n": "科教", "v": "科教"
  314. }, {
  315. "n": "曲艺", "v": "曲艺"
  316. }, {
  317. "n": "歌舞", "v": "歌舞"
  318. }, {
  319. "n": "财经", "v": "财经"
  320. }, {
  321. "n": "汽车", "v": "汽车"
  322. }, {
  323. "n": "播报", "v": "播报"
  324. }, {
  325. "n": "其他", "v": "其他"
  326. }]
  327. }, {
  328. "key": "area", "name": "地区", "value": [{
  329. "n": "全部", "v": ""
  330. }, {
  331. "n": "内地", "v": "大陆"
  332. }, {
  333. "n": "中国香港", "v": "香港"
  334. }, {
  335. "n": "中国台湾", "v": "台湾"
  336. }, {
  337. "n": "日本", "v": "日本"
  338. }, {
  339. "n": "欧美", "v": "欧美"
  340. }]
  341. }, {
  342. "key": "rank", "name": "排序", "value": [{
  343. "n": "最近热映", "v": "rankhot"
  344. }, {
  345. "n": "最近上映", "v": "ranklatest"
  346. }]
  347. }], "4": [{
  348. "key": "cat", "name": "类型", "value": [{
  349. "n": "全部", "v": ""
  350. }, {
  351. "n": "热血", "v": "热血"
  352. }, {
  353. "n": "科幻", "v": "科幻"
  354. }, {
  355. "n": "美少女", "v": "美少女"
  356. }, {
  357. "n": "魔幻", "v": "魔幻"
  358. }, {
  359. "n": "经典", "v": "经典"
  360. }, {
  361. "n": "励志", "v": "励志"
  362. }, {
  363. "n": "少儿", "v": "少儿"
  364. }, {
  365. "n": "冒险", "v": "冒险"
  366. }, {
  367. "n": "搞笑", "v": "搞笑"
  368. }, {
  369. "n": "推理", "v": "推理"
  370. }, {
  371. "n": "恋爱", "v": "恋爱"
  372. }, {
  373. "n": "治愈", "v": "治愈"
  374. }, {
  375. "n": "幻想", "v": "幻想"
  376. }, {
  377. "n": "校园", "v": "校园"
  378. }, {
  379. "n": "动物", "v": "动物"
  380. }, {
  381. "n": "机战", "v": "机战"
  382. }, {
  383. "n": "亲子", "v": "亲子"
  384. }, {
  385. "n": "儿歌", "v": "儿歌"
  386. }, {
  387. "n": "运动", "v": "运动"
  388. }, {
  389. "n": "悬疑", "v": "悬疑"
  390. }, {
  391. "n": "怪物", "v": "怪物"
  392. }, {
  393. "n": "战争", "v": "战争"
  394. }, {
  395. "n": "益智", "v": "益智"
  396. }, {
  397. "n": "青春", "v": "青春"
  398. }, {
  399. "n": "童话", "v": "童话"
  400. }, {
  401. "n": "竞技", "v": "竞技"
  402. }, {
  403. "n": "动作", "v": "动作"
  404. }, {
  405. "n": "社会", "v": "社会"
  406. }, {
  407. "n": "友情", "v": "友情"
  408. }, {
  409. "n": "真人版", "v": "真人版"
  410. }, {
  411. "n": "电影版", "v": "电影版"
  412. }, {
  413. "n": "OVA版", "v": "OVA版"
  414. }, {
  415. "n": "TV版", "v": "TV版"
  416. }, {
  417. "n": "新番动画", "v": "新番动画"
  418. }, {
  419. "n": "完结动画", "v": "完结动画"
  420. }]
  421. }, {
  422. "key": "year", "name": "年代", "value": [{
  423. "n": "全部", "v": ""
  424. }, {
  425. "n": "2024", "v": "2024"
  426. }, {
  427. "n": "2023", "v": "2023"
  428. }, {
  429. "n": "2022", "v": "2022"
  430. }, {
  431. "n": "2021", "v": "2021"
  432. }, {
  433. "n": "2020", "v": "2020"
  434. }, {
  435. "n": "2019", "v": "2019"
  436. }, {
  437. "n": "2018", "v": "2018"
  438. }, {
  439. "n": "2017", "v": "2017"
  440. }, {
  441. "n": "2016", "v": "2016"
  442. }, {
  443. "n": "2015", "v": "2015"
  444. }, {
  445. "n": "2014", "v": "2014"
  446. }, {
  447. "n": "2013", "v": "2013"
  448. }, {
  449. "n": "2012", "v": "2012"
  450. }, {
  451. "n": "2011", "v": "2011"
  452. }, {
  453. "n": "2010", "v": "2010"
  454. }, {
  455. "n": "2009", "v": "2009"
  456. }, {
  457. "n": "2008", "v": "2008"
  458. }, {
  459. "n": "2007", "v": "2007"
  460. }, {
  461. "n": "2006", "v": "2006"
  462. }, {
  463. "n": "2005", "v": "2005"
  464. }, {
  465. "n": "2004", "v": "2004"
  466. }, {
  467. "n": "更早", "v": "更早"
  468. }]
  469. }, {
  470. "key": "area", "name": "地区", "value": [{
  471. "n": "全部", "v": ""
  472. }, {
  473. "n": "内地", "v": "大陆"
  474. }, {
  475. "n": "日本", "v": "日本"
  476. }, {
  477. "n": "美国", "v": "美国"
  478. }]
  479. }, {
  480. "key": "rank", "name": "排序", "value": [{
  481. "n": "最近热映", "v": "rankhot"
  482. }, {
  483. "n": "最近上映", "v": "ranklatest"
  484. }]
  485. }]
  486. }
  487. }
  488. async parseVodShortListFromJson(obj) {
  489. let vod_list = []
  490. for (const data of obj["data"]) {
  491. let vodShort = new VodShort();
  492. vodShort.vod_id = data["ent_id"] + "+" + data["cat"]
  493. if (!data["cover"].startsWith("http")) {
  494. vodShort.vod_pic = "https:" + data["cover"]
  495. } else {
  496. vodShort.vod_pic = data["cover"]
  497. }
  498. vodShort.vod_name = data["title"]
  499. vodShort.vod_remarks = data["upinfo"]
  500. vod_list.push(vodShort)
  501. }
  502. return vod_list
  503. }
  504. async parseVodShortListFromJsonByCategory(obj, tid) {
  505. let vod_list = []
  506. for (const data of obj["data"]["movies"]) {
  507. let vodShort = new VodShort();
  508. vodShort.vod_id = data["id"] + "+" + tid
  509. if (!data["cover"].startsWith("http")) {
  510. vodShort.vod_pic = "https:" + data["cover"]
  511. } else {
  512. vodShort.vod_pic = data["cover"]
  513. }
  514. vodShort.vod_name = data["title"]
  515. vodShort.vod_remarks = data["tag"]
  516. if (!_.isEmpty(data["doubanscore"])) {
  517. vodShort.vod_remarks = "豆瓣评分:" + data["doubanscore"]
  518. } else {
  519. if (_.isEmpty(vodShort.vod_remarks)) {
  520. vodShort.vod_remarks = data["pubdate"]
  521. }
  522. }
  523. vod_list.push(vodShort)
  524. }
  525. return vod_list
  526. }
  527. async parseVodDetailfromJson(obj) {
  528. let vodDetail = new VodDetail()
  529. let data = obj["data"]
  530. vodDetail.vod_name = data["title"]
  531. vodDetail.vod_pic = data["cdncover"]
  532. vodDetail.vod_remarks = data["pubdate"]
  533. vodDetail.vod_actor = data["actor"].join("*")
  534. vodDetail.vod_director = data["director"].join("*")
  535. vodDetail.type_name = data["moviecategory"].join("*")
  536. vodDetail.vod_year = data["pubdate"]
  537. vodDetail.vod_area = data["area"].join("*")
  538. vodDetail.vod_content = data["description"]
  539. let playlist = {}
  540. for (const playFormat of data["playlink_sites"]) {
  541. let vodItems = []
  542. if (!_.isEmpty(data["allepidetail"])) {
  543. if (data["allepidetail"][playFormat] !== undefined) {
  544. for (const items of data["allepidetail"][playFormat]) {
  545. let episodeUrl = items["url"]
  546. let episodeName = items["playlink_num"]
  547. vodItems.push(episodeName + "$" + episodeUrl);
  548. }
  549. }
  550. } else {
  551. let items = data["playlinksdetail"][playFormat]
  552. let episodeUrl = items["default_url"]
  553. let episodeName = items["quality"]
  554. vodItems.push(episodeName + "$" + episodeUrl);
  555. }
  556. if (vodItems.length > 0){
  557. playlist[playFormat] = vodItems.join("#")
  558. }
  559. }
  560. vodDetail.vod_play_url = _.values(playlist).join('$$$');
  561. vodDetail.vod_play_from = _.keys(playlist).join('$$$');
  562. return vodDetail
  563. }
  564. async parseVodShortListFromJsonBySearch(obj) {
  565. let vod_list = []
  566. for (const data of obj["data"]["longData"]["rows"]) {
  567. let vodShort = new VodShort();
  568. vodShort.vod_id = data["en_id"] + "+" + data["cat_id"]
  569. if (!data["cover"].startsWith("http")) {
  570. vodShort.vod_pic = "https:" + data["cover"]
  571. } else {
  572. vodShort.vod_pic = data["cover"]
  573. }
  574. vodShort.vod_name = data["titleTxt"]
  575. vodShort.vod_remarks = data["coverInfo"]["txt"]
  576. vod_list.push(vodShort)
  577. }
  578. return vod_list
  579. }
  580. async setHomeVod() {
  581. let response = await this.fetch(this.siteUrl + "/v1/rank?cat=1", null, this.getHeader())
  582. this.homeVodList = await this.parseVodShortListFromJson(JSON.parse(response))
  583. }
  584. async setCategory(tid, pg, filter, extend) {
  585. let rank = extend["by"] ?? "rankhot"
  586. let year = extend["year"] ?? ""
  587. let cat = extend["cat"] ?? ""
  588. let area = extend["area"] ?? ""
  589. let url = this.siteUrl + `/v1/filter/list?catid=${tid}&rank=${rank}&cat=${cat}&year=${year}&area=${area}&act=&size=35&pageno=${pg}&callback=`
  590. let response = await this.fetch(url, null, this.getHeader())
  591. this.vodList = await this.parseVodShortListFromJsonByCategory(JSON.parse(response), tid)
  592. }
  593. async setDetail(id) {
  594. let tid_list = id.split("+")
  595. let url = this.siteUrl + `/v1/detail?cat=${tid_list[1]}&id=${tid_list[0]}`
  596. let response = await this.fetch(url, null, this.getHeader())
  597. this.vodDetail = await this.parseVodDetailfromJson(JSON.parse(response))
  598. }
  599. async setSearch(wd, quick) {
  600. let url = `https://api.so.360kan.com/index?force_v=1&kw=${wd}&from=&pageno=1&v_ap=1&tab=all`
  601. let response = await this.fetch(url, null, this.getHeader())
  602. this.vodList = await this.parseVodShortListFromJsonBySearch(JSON.parse(response))
  603. }
  604. async setPlay(flag, id, flags) {
  605. if (this.danmuStaus && ! this.catOpenStatus) {
  606. this.danmuUrl = await this.danmuSpider.getVideoUrl(id, 0)
  607. }
  608. this.result.parse = 1 //启用自动解析
  609. this.result.jx = 1
  610. this.playUrl = id
  611. }
  612. }
  613. let spider = new Sp360Spider()
  614. async function init(cfg) {
  615. await spider.init(cfg)
  616. }
  617. async function home(filter) {
  618. return await spider.home(filter)
  619. }
  620. async function homeVod() {
  621. return await spider.homeVod()
  622. }
  623. async function category(tid, pg, filter, extend) {
  624. return await spider.category(tid, pg, filter, extend)
  625. }
  626. async function detail(id) {
  627. return await spider.detail(id)
  628. }
  629. async function play(flag, id, flags) {
  630. return await spider.play(flag, id, flags)
  631. }
  632. async function search(wd, quick) {
  633. return await spider.search(wd, quick)
  634. }
  635. export function __jsEvalReturn() {
  636. return {
  637. init: init, home: home, homeVod: homeVod, category: category, detail: detail, play: play, search: search,
  638. };
  639. }
  640. export {spider}