ysfp.user.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. // ==UserScript==
  2. // @name yfsp
  3. // @namespace gmspider
  4. // @version 2024.11.12
  5. // @description 爱壹帆 GMSpider
  6. // @author Luomo
  7. // @match https://m.yfsp.tv/*
  8. // @require https://cdn.jsdelivr.net/gh/CatVodSpider-GM/Spiders-Lib@main/lib/browser-extension-url-match-1.2.0.min.js
  9. // @require https://cdn.jsdelivr.net/npm/ajax-hook@3.0.3/dist/ajaxhook.umd.min.js
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // @grant unsafeWindow
  13. // @run-at document-start
  14. // ==/UserScript==
  15. console.log(JSON.stringify(GM_info));
  16. (function () {
  17. const GMSpiderArgs = {};
  18. if (typeof GmSpiderInject !== 'undefined') {
  19. let args = JSON.parse(GmSpiderInject.GetSpiderArgs());
  20. GMSpiderArgs.fName = args.shift();
  21. GMSpiderArgs.fArgs = args;
  22. } else {
  23. // GMSpiderArgs.fName = "homeContent";
  24. // GMSpiderArgs.fArgs = [true];
  25. // GMSpiderArgs.fName = "categoryContent";
  26. // GMSpiderArgs.fArgs = ["movie", 2, true, {}];
  27. // GMSpiderArgs.fName = "detailContent";
  28. // GMSpiderArgs.fArgs = [["XOkJ0XqSwI2"]];
  29. GMSpiderArgs.fName = "searchContent";
  30. GMSpiderArgs.fArgs = ["小巷人家", false, 1];
  31. }
  32. Object.freeze(GMSpiderArgs);
  33. (function () {
  34. switch (GMSpiderArgs.fName) {
  35. case "searchContent":
  36. localStorage.setItem("historyList", JSON.stringify([GMSpiderArgs.fArgs [0]]));
  37. break;
  38. }
  39. })();
  40. let hookConfigs = {
  41. "homeContent": [{
  42. dataKey: "navigationbar",
  43. matcher: matchPattern("https://*.yfsp.tv/api/list/navigationbar?*").assertValid()
  44. }, {
  45. dataKey: "index",
  46. matcher: matchPattern("https://*.yfsp.tv/api/list/index?*").assertValid()
  47. }],
  48. "categoryContent": [{
  49. dataKey: "filtertagsdata",
  50. matcher: matchPattern("https://*.yfsp.tv/api/list/getfiltertagsdata?*").assertValid()
  51. }, {
  52. dataKey: "conditionfilterdata",
  53. matcher: matchPattern("https://*.yfsp.tv/api/list/getconditionfilterdata?*").assertValid(),
  54. onRequestHook: function (config, handler) {
  55. let url = new URL(config.url);
  56. url.searchParams.set('page', GMSpiderArgs.fArgs[1]);
  57. config.url = url.toString();
  58. }
  59. }],
  60. "detailContent": [{
  61. dataKey: "videodetails",
  62. matcher: matchPattern("https://*.yfsp.tv/api/video/videodetails?*").assertValid()
  63. }, {
  64. dataKey: "playdata",
  65. matcher: matchPattern("https://*.yfsp.tv/api/video/getplaydata?*").assertValid()
  66. }, {
  67. dataKey: "videochoosegather",
  68. require: false,
  69. matcher: matchPattern("https://*.yfsp.tv/api/video/videochoosegather?*").assertValid()
  70. }],
  71. "playerContent": [{
  72. dataKey: "playdata",
  73. matcher: matchPattern("https://*.yfsp.tv/api/video/getplaydata?*").assertValid()
  74. }],
  75. "searchContent": [{
  76. dataKey: "titlegetdata",
  77. matcher: matchPattern("https://*.yfsp.tv/api/list/gettitlegetdata?*").assertValid()
  78. }, {
  79. matcher: matchPattern("https://*.yfsp.tv/api/home/gethotsearch?*").assertValid(),
  80. onResponseHook: function (response, handler) {
  81. document.querySelector(".search-log span").dispatchEvent(new Event("click"));
  82. }
  83. }],
  84. };
  85. const GmSpider = (function () {
  86. const categoryFilterCachePrefix = "category.";
  87. return {
  88. homeContent: function (filter) {
  89. let result = {
  90. class: [],
  91. filters: {},
  92. list: []
  93. };
  94. let categoryIds = [];
  95. hookResult.navigationbar.data.list.forEach((item) => {
  96. if (item.type === 1) {
  97. result.class.push({
  98. type_id: item.routeName,
  99. type_name: item.name
  100. });
  101. categoryIds.push(item.categoryId);
  102. // const cacheFilter = GM_getValue(item.routeName);
  103. // console.log("cacheFilter", item.routeName, cacheFilter);
  104. const cacheFilter = localStorage.getItem(categoryFilterCachePrefix + item.routeName);
  105. console.log("localStorage", item.routeName, localStorage.getItem(item.routeName));
  106. if (typeof cacheFilter !== "undefined" && cacheFilter !== null) {
  107. result.filters[item.routeName] = JSON.parse(cacheFilter);
  108. }
  109. }
  110. })
  111. hookResult.index.data.list.forEach((item) => {
  112. if (categoryIds.includes(item.type)) {
  113. item.list.forEach((media) => {
  114. if (!media.isRecommend) {
  115. result.list.push({
  116. vod_id: media.mediaKey,
  117. vod_name: media.title,
  118. vod_pic: media.coverImgUrl,
  119. vod_remarks: media.updateStatus,
  120. vod_year: media.mediaType
  121. })
  122. }
  123. })
  124. }
  125. })
  126. return result;
  127. },
  128. categoryContent: function (tid, pg, filter, extend) {
  129. let result = {
  130. list: [],
  131. pagecount: 1000
  132. };
  133. let cacheFilters = [];
  134. hookResult.filtertagsdata.data.list.forEach(classify => {
  135. let cacheFilter = {
  136. key: "index-" + classify.list[0].index,
  137. name: classify.name,
  138. value: []
  139. }
  140. classify.list.forEach((item) => {
  141. cacheFilter.value.push({
  142. n: item.classifyName,
  143. v: (item.index > 0 ? "," : "") + item.classifyId
  144. });
  145. })
  146. cacheFilters.push(cacheFilter);
  147. })
  148. // GM_setValue(tid, JSON.stringify(cacheFilters));
  149. localStorage.setItem(categoryFilterCachePrefix + tid, JSON.stringify(cacheFilters));
  150. console.log("cacheFilter", tid, cacheFilters);
  151. hookResult.conditionfilterdata.data.list.forEach((media) => {
  152. result.list.push({
  153. vod_id: media.mediaKey,
  154. vod_name: media.title,
  155. vod_pic: media.coverImgUrl,
  156. vod_remarks: media.updateStatus,
  157. vod_year: media.regional
  158. })
  159. })
  160. return result;
  161. },
  162. detailContent: function (ids) {
  163. const videodetails = hookResult.videodetails.data.detailInfo;
  164. let mediaUrl = "";
  165. let episodeKey = "";
  166. hookResult.playdata.data.list.forEach((item) => {
  167. if (mediaUrl === "" && item.mediaUrl !== "") {
  168. mediaUrl = item.mediaUrl;
  169. episodeKey = item.episodeKey;
  170. }
  171. })
  172. let media = [];
  173. if (videodetails.videoType !== 0) {
  174. if (typeof hookResult.videochoosegather !== "undefined") {
  175. hookResult.videochoosegather.data.list.forEach((item) => {
  176. if (videodetails.episodeTitle === item.episodeTitle) {
  177. media.push({
  178. name: item.episodeTitle,
  179. type: "finalUrl",
  180. ext: {
  181. "header": {
  182. "User-Agent": window.navigator.userAgent,
  183. "Referer": window.location.href
  184. },
  185. "url": mediaUrl
  186. }
  187. });
  188. } else {
  189. media.push({
  190. name: item.episodeTitle,
  191. type: "webview",
  192. ext: {
  193. replace: {
  194. mediaKey: item.mediaKey,
  195. episodeKey: item.episodeKey
  196. }
  197. }
  198. })
  199. }
  200. })
  201. } else {
  202. spiderExecuted = false;
  203. return;
  204. }
  205. } else {
  206. media.push({
  207. name: videodetails.episodeTitle,
  208. type: "finalUrl",
  209. ext: {
  210. "header": {
  211. "User-Agent": window.navigator.userAgent,
  212. "Referer": window.location.href
  213. },
  214. "url": mediaUrl
  215. }
  216. })
  217. }
  218. return {
  219. vod_id: videodetails.mediaKey,
  220. vod_name: videodetails.title,
  221. vod_pic: videodetails.coverImgUrl,
  222. vod_actor: videodetails.actor,
  223. vod_director: videodetails.director,
  224. vod_tag: videodetails.cidMapper,
  225. vod_area: videodetails.regional,
  226. vod_content: videodetails.introduce,
  227. vod_play_data: [{
  228. from: "爱壹帆",
  229. media: media
  230. }]
  231. };
  232. },
  233. playerContent: function (flag, id, vipFlags) {
  234. let mediaUrl = "";
  235. hookResult.playdata.data.list.forEach((item) => {
  236. if (mediaUrl === "" && item.mediaUrl !== "") {
  237. mediaUrl = item.mediaUrl;
  238. }
  239. })
  240. return {
  241. type: "finalUrl",
  242. ext: {
  243. "header": {
  244. "User-Agent": window.navigator.userAgent,
  245. "Referer": window.location.href
  246. },
  247. "url": mediaUrl
  248. }
  249. };
  250. },
  251. searchContent: function (key, quick, pg) {
  252. console.log(hookResult);
  253. let result = {
  254. list: [],
  255. pagecount: 1
  256. };
  257. if (pg == 1) {
  258. hookResult.titlegetdata.data.list.forEach((media) => {
  259. result.list.push({
  260. vod_id: media.mediaKey,
  261. vod_name: media.title,
  262. vod_pic: media.coverImgUrl,
  263. vod_remarks: media.updateStatus,
  264. vod_year: media.regional
  265. })
  266. })
  267. }
  268. return result;
  269. }
  270. };
  271. })();
  272. let spiderExecuted = false;
  273. let dataReadyCount = 0;
  274. let hookResult = {};
  275. const {unProxy, originXhr} = proxy({
  276. onRequest: (config, handler) => {
  277. hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => {
  278. if (typeof hookConfig.onRequestHook === "function" && hookConfig.matcher.match(config.url)) {
  279. hookConfig.onRequestHook(config, handler);
  280. }
  281. });
  282. handler.next(config);
  283. },
  284. onResponse: (response, handler) => {
  285. if (!spiderExecuted) {
  286. let dataTodoCount = 0;
  287. hookConfigs[GMSpiderArgs.fName].forEach((hookConfig) => {
  288. if (typeof hookConfig.dataKey !== "undefined") {
  289. if (hookConfig?.require !== false) {
  290. dataTodoCount++;
  291. }
  292. if (hookConfig.matcher.match(response.config.url)) {
  293. if (hookConfig?.require !== false) {
  294. dataReadyCount++;
  295. }
  296. try {
  297. let data = JSON.parse(response.response);
  298. if (typeof data === 'object' && data) {
  299. hookResult[hookConfig.dataKey] = data;
  300. } else {
  301. hookResult[hookConfig.dataKey] = response.response;
  302. }
  303. } catch (e) {
  304. }
  305. }
  306. }
  307. if (typeof hookConfig.onResponseHook === "function" && hookConfig.matcher.match(response.config.url)) {
  308. hookConfig.onResponseHook(response, handler);
  309. }
  310. });
  311. if (dataTodoCount === dataReadyCount) {
  312. spiderExecuted = true;
  313. const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs);
  314. console.log(result);
  315. if (typeof GmSpiderInject !== 'undefined' && spiderExecuted) {
  316. GmSpiderInject.SetSpiderResult(JSON.stringify(result));
  317. }
  318. }
  319. }
  320. handler.next(response);
  321. }
  322. }, unsafeWindow)
  323. })();