├── .gitignore ├── Spiders-Lib └── GM.jar ├── index.json └── userScripts ├── 123av.user.js ├── jable.user.js ├── missav.user.js ├── netflav.user.js ├── supjav.user.js └── xojav.user.js /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea -------------------------------------------------------------------------------- /Spiders-Lib/GM.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatVodSpider-GM/NSFW-Spiders/ef64b991afebf1a7338c3ba9e8856a18464328bf/Spiders-Lib/GM.jar -------------------------------------------------------------------------------- /index.json: -------------------------------------------------------------------------------- 1 | { 2 | "spider": "./Spiders-Lib/GM.jar;md5;875ce871703d1c382e0498711b9d3ba0", 3 | "sites": [ 4 | { 5 | "key": "Jable", 6 | "name": "Jable", 7 | "type": 3, 8 | "searchable": 1, 9 | "changeable": 1, 10 | "style": { 11 | "type": "rect", 12 | "ratio": 1.48 13 | }, 14 | "api": "csp_GM", 15 | "ext": { 16 | "userScript": "./userScripts/jable.user.js", 17 | "debug": false, 18 | "webViewSettings": { 19 | "blockNetworkImage": true, 20 | "blockList": [ 21 | "*.ico*", 22 | "*.png*", 23 | "*.css*", 24 | "https://*.adsco.re/*", 25 | "https://*.googleapis.com/*", 26 | "https://*.googlesyndication.com/*", 27 | "https://*.googletagmanager.com/*", 28 | "https://*.hpyjmp.com/*", 29 | "https://*.magsrv.com/*", 30 | "https://*.mnaspm.com/*", 31 | "https://*.shukriya90.com/*", 32 | "https://*.tapioni.com/*", 33 | "https://*.tsyndicate.com/*", 34 | "https://assets.jable.tv/assets/js/player.js" 35 | ] 36 | }, 37 | "spider": { 38 | "homeContent": { 39 | "loadUrl": "https://jable.tv/" 40 | }, 41 | "categoryContent": { 42 | "loadUrl": "https://jable.tv/${tid:-latest-updates}/?from=${pg:-1}${sort_by:-}" 43 | }, 44 | "detailContent": { 45 | "loadUrl": "https://jable.tv/videos/${id}/" 46 | }, 47 | "searchContent": { 48 | "loadUrl": "https://jable.tv/search/${key}/?from=${pg:-1}" 49 | } 50 | } 51 | } 52 | }, 53 | { 54 | "key": "netflav", 55 | "name": "NETFLAV", 56 | "type": 3, 57 | "searchable": 1, 58 | "changeable": 1, 59 | "style": { 60 | "type": "rect", 61 | "ratio": 1.48 62 | }, 63 | "api": "csp_GM", 64 | "ext": { 65 | "userScript": "./userScripts/netflav.user.js", 66 | "debug": false, 67 | "webViewSettings": { 68 | "blockNetworkImage": true, 69 | "blockList": [ 70 | "*.png", 71 | "*.css", 72 | "*.woff2", 73 | "https://*.googletagmanager.com/*", 74 | "https://*.imkirh.com/*", 75 | "https://*.xlvirdr.com/*" 76 | ] 77 | }, 78 | "playUrlMatch": [ 79 | "https://*/*/master.m3u8*", 80 | "https://*/*/v.mp4", 81 | "https://*/*/playlist.m3u8*" 82 | ], 83 | "spider": { 84 | "homeContent": { 85 | "loadUrl": "https://netflav.com/trending" 86 | }, 87 | "categoryContent": { 88 | "loadUrl": "https://netflav.com/${tid}&page=${pg:-1}${range:-}" 89 | }, 90 | "detailContent": { 91 | "loadUrl": "https://netflav.com/video?id=${id}/" 92 | }, 93 | "playerContent": { 94 | "loadUrl": "https://netflav.com/video?id=${vod_id}#${src}" 95 | }, 96 | "searchContent": { 97 | "loadUrl": "https://netflav.com/search?keyword=${key}&page=${pg:-1}&type=title" 98 | } 99 | } 100 | } 101 | }, 102 | { 103 | "key": "123av", 104 | "name": "123AV", 105 | "type": 3, 106 | "searchable": 1, 107 | "changeable": 1, 108 | "style": { 109 | "type": "rect", 110 | "ratio": 1.49 111 | }, 112 | "api": "csp_GM", 113 | "ext": { 114 | "userScript": "./userScripts/123av.user.js", 115 | "debug": false, 116 | "webViewSettings": { 117 | "blockNetworkImage": true, 118 | "blockList": [ 119 | "*.ico", 120 | "*.png", 121 | "*.jpg", 122 | "*.vtt", 123 | "*.css*", 124 | "https://*.googleapis.com/*", 125 | "https://*.googletagmanager.com/*", 126 | "https://*.recombee.com/*", 127 | "https://*.google-analytics.com/*", 128 | "https://njav.tv/recomm/items/*" 129 | ] 130 | }, 131 | "playUrlMatch": [ 132 | "https://*.skyearth*.xyz/*/v.m3u8" 133 | ], 134 | "spider": { 135 | "homeContent": { 136 | "loadUrl": "https://123av.com/zh/" 137 | }, 138 | "categoryContent": { 139 | "loadUrl": "https://123av.com/zh/${tid}?page=${pg:-1}${filter:-}${sort:-}" 140 | }, 141 | "detailContent": { 142 | "loadUrl": "https://123av.com/zh/${id}" 143 | }, 144 | "playerContent": { 145 | "loadUrl": "https://123av.com/zh/${vod_id}" 146 | }, 147 | "searchContent": { 148 | "loadUrl": "https://123av.com/zh/search?keyword=${key}&page=${pg:-1}" 149 | } 150 | } 151 | } 152 | }, 153 | { 154 | "key": "MissAV", 155 | "name": "MissAV", 156 | "type": 3, 157 | "searchable": 1, 158 | "changeable": 1, 159 | "style": { 160 | "type": "rect", 161 | "ratio": 1.49 162 | }, 163 | "api": "csp_GM", 164 | "ext": { 165 | "userScript": "./userScripts/missav.user.js", 166 | "debug": false, 167 | "webViewSettings": { 168 | "blockNetworkImage": true, 169 | "blockList": [ 170 | "*.ico", 171 | "*.png", 172 | "*.css", 173 | "*.svg", 174 | "https://*.cloudflareinsights.com/*", 175 | "https://*.googletagmanager.com/*", 176 | "https://*.ktkjmp.com/*", 177 | "https://*.magsrv.com/*", 178 | "https://*.mnaspm.com/*", 179 | "https://*.myavlive.com/*", 180 | "https://*.recombee.com/*", 181 | "https://*.rmhfrtnd.com/*", 182 | "https://*.trackwilltrk.com/*", 183 | "https://*.tsyndicate.com/*", 184 | "https://missav.com/fonts/*", 185 | "https://tsyndicate.com/*", 186 | "https://hartattenuate.com/*" 187 | ] 188 | }, 189 | "spider": { 190 | "homeContent": { 191 | "loadUrl": "https://missav.ws/cn/" 192 | }, 193 | "categoryContent": { 194 | "loadUrl": "https://missav.ws/cn/${tid}?page=${pg:-1}${filter:-}${sort:-}" 195 | }, 196 | "detailContent": { 197 | "loadUrl": "https://missav.ws/cn/${id}" 198 | }, 199 | "searchContent": { 200 | "loadUrl": "https://missav.ws/cn/search/${key}?page=${pg:-1}" 201 | } 202 | } 203 | } 204 | }, 205 | { 206 | "key": "supjav", 207 | "name": "Supjav", 208 | "type": 3, 209 | "searchable": 1, 210 | "changeable": 1, 211 | "style": { 212 | "type": "rect", 213 | "ratio": 1.48 214 | }, 215 | "api": "csp_GM", 216 | "ext": { 217 | "userScript": "./userScripts/supjav.user.js", 218 | "debug": false, 219 | "webViewSettings": { 220 | "blockNetworkImage": false, 221 | "blockList": [ 222 | "https://*.adforcast.com/*", 223 | "https://*.adxadserv.com/*", 224 | "https://*.bbrdbr.com/*", 225 | "https://*.fanza.cc/*", 226 | "https://*.google-analytics.com/*", 227 | "https://*.googletagmanager.com/*", 228 | "https://*.mnaspm.com/*", 229 | "https://*.recombee.com/*", 230 | "https://*.sacdnssedge.com/*", 231 | "https://*.tapioni.com/*", 232 | "https://*.yandex.ru/*", 233 | "https://*/prebid.min.js", 234 | "https://divisiondrearilyunfiled.com/*", 235 | "https://endowmentoverhangutmost.com/*", 236 | "https://imasdk.googleapis.com/*", 237 | "https://psoroumukr.com/*", 238 | "https://static.ads-twitter.com/*", 239 | "https://streamhg.com/*" 240 | ] 241 | }, 242 | "playUrlMatch": [ 243 | "https://*.cdn-centaurus.com/*/master.m3u8*", 244 | "https://*.cloudatacdn.com/*", 245 | "https://*.cloudflarestorage.com/*", 246 | "https://*.linkofnyz.com/*.m3u8*", 247 | "https://*.tapecontent.net/*", 248 | "https://*.turboviplay.*/*.m3u8", 249 | "https://*.voe-network.net/*/master.m3u8*", 250 | "https://dood.la/pass_md5/*", 251 | "https://streamtape.com/get_video*" 252 | ], 253 | "spider": { 254 | "homeContent": { 255 | "loadUrl": "https://supjav.com/zh/popular" 256 | }, 257 | "categoryContent": { 258 | "loadUrl": "https://supjav.com/zh/${tid}/page/${pg:-1}?sort=${sort:-quantity}" 259 | }, 260 | "detailContent": { 261 | "loadUrl": "https://supjav.com/zh/${id}" 262 | }, 263 | "playerContent": { 264 | "loadUrl": "https://supjav.com/zh/${pathname}#${link}" 265 | }, 266 | "searchContent": { 267 | "loadUrl": "https://supjav.com/zh/page/${pg:-1}?s=${key}" 268 | } 269 | } 270 | } 271 | }, 272 | { 273 | "key": "XOJAV", 274 | "name": "XOJAV", 275 | "type": 3, 276 | "searchable": 1, 277 | "changeable": 1, 278 | "style": { 279 | "type": "rect", 280 | "ratio": 1.78 281 | }, 282 | "api": "csp_GM", 283 | "ext": { 284 | "userScript": "./userScripts/xojav.user.js", 285 | "debug": false, 286 | "webViewSettings": { 287 | "blockNetworkImage": true, 288 | "blockList": [ 289 | "*.css*", 290 | "*.ico*", 291 | "*.png*", 292 | "*.svg", 293 | "https://*.googleapis.com/*", 294 | "https://*.googletagmanager.com/*", 295 | "https://*.magsrv.com/*", 296 | "https://*.pemsrv.com/*" 297 | ] 298 | }, 299 | "spider": { 300 | "homeContent": { 301 | "loadUrl": "https://xojav.tv/?lang=zh" 302 | }, 303 | "categoryContent": { 304 | "loadUrl": "https://xojav.tv/${tid}${sort_by:-}&mode=async&function=get_block&from=${pg:-1}" 305 | }, 306 | "detailContent": { 307 | "loadUrl": "https://xojav.tv/videos/${id}" 308 | }, 309 | "searchContent": { 310 | "loadUrl": "https://xojav.tv/search/${key}/?mode=async&function=get_block&sort_by=most_relevant&from_videos=${pg:-1}" 311 | } 312 | } 313 | } 314 | } 315 | ] 316 | } -------------------------------------------------------------------------------- /userScripts/123av.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name 123av 3 | // @namespace gmspider 4 | // @version 2024.12.03 5 | // @description 123av GMSpider 6 | // @author Luomo 7 | // @match https://123av.com/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @grant unsafeWindow 10 | // ==/UserScript== 11 | console.log(JSON.stringify(GM_info)); 12 | (function () { 13 | const GMSpiderArgs = {}; 14 | if (typeof GmSpiderInject !== 'undefined') { 15 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 16 | GMSpiderArgs.fName = args.shift(); 17 | GMSpiderArgs.fArgs = args; 18 | } else { 19 | GMSpiderArgs.fName = "homeContent"; 20 | GMSpiderArgs.fArgs = ["tags"]; 21 | } 22 | Object.freeze(GMSpiderArgs); 23 | const GmSpider = (function () { 24 | const filter = { 25 | key: "filter", 26 | name: "过滤", 27 | value: [{ 28 | n: "全部", 29 | v: "" 30 | }, { 31 | n: "单个女演员", 32 | v: "&filter=single_actress" 33 | }] 34 | }; 35 | const filterWithoutSort = [ 36 | filter 37 | ]; 38 | const defaultFilter = [ 39 | filter, 40 | { 41 | key: "sort", 42 | name: "排序方式", 43 | value: [ 44 | { 45 | n: "最近更新", 46 | v: "&sort=recent_update" 47 | }, 48 | { 49 | n: "发布时间", 50 | v: "&sort=release_date" 51 | }, 52 | { 53 | n: "动态", 54 | v: "&sort=trending" 55 | }, 56 | { 57 | n: "今日最好", 58 | v: "&sort=most_viewed_today" 59 | }, 60 | { 61 | n: "本周最好", 62 | v: "&sort=most_viewed_week" 63 | }, 64 | { 65 | n: "本月最好", 66 | v: "&sort=most_viewed_month" 67 | }, 68 | { 69 | n: "观看次数最多", 70 | v: "&sort=most_viewed" 71 | }, 72 | { 73 | n: "最喜欢", 74 | v: "&sort=most_favourited" 75 | } 76 | ] 77 | }]; 78 | 79 | function pageList(select) { 80 | let itemList = []; 81 | $(select).each(function (i) { 82 | if ($(this).find("a").attr("href") != "javascript:void(0);") { 83 | itemList.push({ 84 | vod_id: $(this).find("a").attr("href").split("/zh/").at(-1), 85 | vod_name: $(this).find(".detail a").text(), 86 | vod_pic: $(this).find("img").data("src"), 87 | vod_year: $(this).find(".duration").text() 88 | }) 89 | } 90 | }); 91 | return itemList; 92 | } 93 | 94 | function formatDetail(detail, ...keys) { 95 | let format = ""; 96 | for (let key of keys) { 97 | format += key in detail ? (Array.isArray(detail[key]) ? detail[key].join(" ") : detail[key]) : ""; 98 | } 99 | return format; 100 | } 101 | 102 | 103 | return { 104 | homeContent: function () { 105 | let result = { 106 | class: [ 107 | {type_id: "recent-update", type_name: "最近更新"}, 108 | {type_id: "trending", type_name: "热门"}, 109 | {type_id: "new-release", type_name: "全新上市"}, 110 | {type_id: "censored", type_name: "有码"}, 111 | {type_id: "uncensored", type_name: "无码"}, 112 | {type_id: "tags", type_name: "厂牌"}, 113 | {type_id: "genres", type_name: "类型"} 114 | ], 115 | filters: { 116 | "recent-update": filterWithoutSort, 117 | "trending": defaultFilter, 118 | "new-release": filterWithoutSort, 119 | "censored": defaultFilter, 120 | "uncensored": defaultFilter, 121 | "tags": defaultFilter, 122 | "genres": defaultFilter 123 | }, 124 | list: [] 125 | }; 126 | result.class.map(item=>{ 127 | $("#nav a").each(function () { 128 | if($(this).attr("href").endsWith(item.type_id)){ 129 | item.type_id=$(this).attr("href") 130 | return false 131 | } 132 | }); 133 | }) 134 | let itemList = pageList(".box-item-list .box-item:not(.splide__slide)"); 135 | result.list = itemList.filter((item, index) => { 136 | return itemList.findIndex(i => i.vod_id === item.vod_id) === index 137 | }); 138 | return result; 139 | }, 140 | categoryContent: function (tid, pg, filter, extend) { 141 | console.log(tid, pg, filter, JSON.stringify(extend)); 142 | let result = { 143 | list: [], 144 | page: pg, 145 | pagecount: 0 146 | }; 147 | if (tid === "tags") { 148 | $("#nav ul li a").each(function () { 149 | let tagHref = $(this).attr("href"); 150 | if (tagHref.includes("tags") && !tagHref.includes("http")) { 151 | tagHref = tagHref.split("/"); 152 | result.list.push({ 153 | vod_id: tagHref.at(-2) + "/" + tagHref.at(-1), 154 | vod_name: $(this).text().trim(), 155 | vod_tag: "folder", 156 | style: { 157 | "type": "rect", 158 | "ratio": 2 159 | } 160 | }) 161 | } 162 | }); 163 | result.pagecount = 1; 164 | } else if (tid === "genres") { 165 | $("#page-list .bl-item").each(function () { 166 | result.list.push({ 167 | vod_id: $(this).find("a").attr("href"), 168 | vod_name: $(this).find(".name").text(), 169 | vod_remarks: $(this).find(".text-muted").text(), 170 | vod_tag: "folder", 171 | style: { 172 | "type": "rect", 173 | "ratio": 1 174 | } 175 | }) 176 | }); 177 | result.pagecount = 1; 178 | } else { 179 | result.list = pageList("#page-list .box-item-list .box-item"); 180 | result.pagecount = Math.ceil(parseInt($("#page-list .section-title .text-muted").text().replace(",", "")) / 12); 181 | } 182 | return result; 183 | }, 184 | detailContent: function (ids) { 185 | let detail = {}; 186 | $("#details .detail-item div").each(function (item) { 187 | const key = $(this).find("span:first").text().replace(":", ""); 188 | if ($(this).find("span:eq(1) a").length === 0) { 189 | detail[key] = $(this).find("span:eq(1)").text().trim(); 190 | } else { 191 | detail[key] = []; 192 | $(this).find("span:eq(1) a").each(function () { 193 | const id = $(this).attr("href"); 194 | const name = $(this).text(); 195 | detail[key].push(`[a=cr:{"id":"${id}","name":"${name}"}/]${name}[/a]`); 196 | }) 197 | } 198 | }); 199 | const vod = { 200 | vod_id: ids[0], 201 | vod_name: $(".favourite:first").data("code"), 202 | vod_pic: $("#player").data("poster"), 203 | vod_year: formatDetail(detail, "发布日期"), 204 | vod_remarks: formatDetail(detail, "类型"), 205 | vod_director: formatDetail(detail, "制作者", "标签"), 206 | vod_actor: formatDetail(detail, "演员"), 207 | vod_content: $(".justify-content-between.align-items-start h1").text().trim(), 208 | vod_play_data: [{ 209 | from: "123AV", 210 | media: [{ 211 | name: "720P", 212 | type: "webview", 213 | ext: { 214 | replace: { 215 | vod_id: ids[0] 216 | } 217 | } 218 | }] 219 | }] 220 | }; 221 | return {list: [vod]}; 222 | }, 223 | playerContent: function (flag, id, vipFlags) { 224 | return { 225 | type: "match" 226 | }; 227 | }, 228 | searchContent: function (key, quick, pg) { 229 | const result = { 230 | list: [], 231 | page: pg, 232 | pagecount: 0 233 | }; 234 | result.list = pageList("#page-list .box-item-list .box-item"); 235 | result.pagecount = Math.ceil(parseInt($("#page-list .section-title .text-muted").text().replace(",", "")) / 12); 236 | return result; 237 | } 238 | }; 239 | })(); 240 | $(document).ready(function () { 241 | let result = ""; 242 | if ($("#cf-wrapper").length > 0) { 243 | console.log("源站不可用:" + $('title').text()); 244 | GM_toastLong("源站不可用:" + $('title').text()); 245 | } else { 246 | result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 247 | } 248 | console.log(JSON.stringify(result)); 249 | if (typeof GmSpiderInject !== 'undefined') { 250 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 251 | } 252 | }); 253 | })(); -------------------------------------------------------------------------------- /userScripts/jable.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Jable 3 | // @namespace gmspider 4 | // @version 2024.12.03 5 | // @description Jable GMSpider 6 | // @author Luomo 7 | // @match https://jable.tv/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @grant unsafeWindow 10 | // ==/UserScript== 11 | console.log(JSON.stringify(GM_info)); 12 | (function () { 13 | const GMSpiderArgs = {}; 14 | if (typeof GmSpiderInject !== 'undefined') { 15 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 16 | GMSpiderArgs.fName = args.shift(); 17 | GMSpiderArgs.fArgs = args; 18 | } else { 19 | GMSpiderArgs.fName = "homeContent"; 20 | GMSpiderArgs.fArgs = [true]; 21 | } 22 | Object.freeze(GMSpiderArgs); 23 | const GmSpider = (function () { 24 | function listVideos(result) { 25 | result.pagecount = parseInt($(".pagination .page-item:last").text()); 26 | $("[id^='list_videos_'] .row:first .video-img-box").each(function (i) { 27 | const subTitle = $(this).find(".sub-title").text().split('\n'); 28 | const remarks = [ 29 | "👁️" + subTitle[1].trim(), 30 | "❤️" + subTitle[2].trim() 31 | ]; 32 | const url = new URL($(this).find(".img-box a").attr("href")); 33 | result.list.push({ 34 | vod_id: url.pathname.split('/').at(2).toUpperCase(), 35 | vod_name: $(this).find(".title").text(), 36 | vod_pic: $(this).find(".img-box img").data("src"), 37 | vod_remarks: remarks.join(" "), 38 | vod_year: $(this).find(".absolute-bottom-right").text().trim() 39 | }) 40 | }); 41 | return result; 42 | } 43 | 44 | return { 45 | homeContent: function (filter) { 46 | let result = { 47 | class: [ 48 | {type_id: "latest-updates", type_name: "最近更新"}, 49 | {type_id: "hot", type_name: "热门影片"}, 50 | {type_id: "categories/chinese-subtitle", type_name: "中文字幕"}, 51 | {type_id: "new-release", type_name: "全新上市"}, 52 | {type_id: "categories", type_name: "主题&标签"}, 53 | ], 54 | filters: { 55 | hot: [{ 56 | key: "sort_by", 57 | name: "时间", 58 | value: [ 59 | { 60 | n: "所有时间", 61 | v: "&sort_by=video_viewed" 62 | }, 63 | { 64 | n: "本月热门", 65 | v: "&sort_by=video_viewed_month" 66 | }, 67 | { 68 | n: "本周热门", 69 | v: "&sort_by=video_viewed_week" 70 | }, 71 | { 72 | n: "今日热门", 73 | v: "&sort_by=video_viewed_today" 74 | } 75 | ] 76 | }], 77 | "categories/chinese-subtitle": [{ 78 | key: "sort_by", 79 | name: "时间", 80 | value: [ 81 | { 82 | n: "近期最佳", 83 | v: "&sort_by=post_date_and_popularity" 84 | }, 85 | { 86 | n: "最近更新", 87 | v: "&sort_by=post_date" 88 | }, 89 | { 90 | n: "最多观看", 91 | v: "&sort_by=video_viewed" 92 | }, 93 | { 94 | n: "最高收藏", 95 | v: "&sort_by=most_favourited" 96 | } 97 | ] 98 | }], 99 | categories: [{ 100 | key: "sort_by", 101 | name: "时间", 102 | value: [ 103 | { 104 | n: "近期最佳", 105 | v: "&sort_by=post_date_and_popularity" 106 | }, 107 | { 108 | n: "最近更新", 109 | v: "&sort_by=post_date" 110 | }, 111 | { 112 | n: "最多观看", 113 | v: "&sort_by=video_viewed" 114 | }, 115 | { 116 | n: "最高收藏", 117 | v: "&sort_by=most_favourited" 118 | } 119 | ] 120 | }] 121 | }, 122 | list: [] 123 | }; 124 | let itemList = []; 125 | $(".video-img-box").has(".detail").has("img").each(function () { 126 | const url = new URL($(this).find(".img-box a").attr("href")); 127 | if (url.hostname === "jable.tv") { 128 | itemList.push({ 129 | vod_id: url.pathname.split('/').at(2).toUpperCase(), 130 | vod_name: $(this).find(".title").text(), 131 | vod_pic: $(this).find("img").data("src"), 132 | vod_year: $(this).find(".absolute-bottom-right").text().trim() 133 | }) 134 | } 135 | }); 136 | result.list = itemList.filter((item, index) => { 137 | return itemList.findIndex(i => i.vod_id === item.vod_id) === index 138 | }); 139 | return result; 140 | }, 141 | categoryContent: function (tid, pg, filter, extend) { 142 | let result = { 143 | list: [], 144 | pagecount: 1 145 | }; 146 | if (tid === "categories") { 147 | $("#list_categories_video_categories_list .video-img-box").each(function () { 148 | const url = new URL($(this).find("a").attr("href")).pathname.split('/'); 149 | result.list.push({ 150 | vod_id: url[1] + "/" + url[2], 151 | vod_name: $(this).find("h4").text(), 152 | vod_pic: $(this).find("img").attr("src"), 153 | vod_remarks: $(this).find(".absolute-center span").text(), 154 | vod_tag: "folder", 155 | style: { 156 | "type": "rect", 157 | "ratio": 1 158 | } 159 | }) 160 | }); 161 | const tags = []; 162 | $(".app-nav .title-box:gt(0)").each(function () { 163 | const remark = $(this).text(); 164 | $(this).next(".row").find(".tag").each(function () { 165 | const url = new URL($(this).attr("href")).pathname.split('/'); 166 | result.list.push({ 167 | vod_id: url[1] + "/" + url[2], 168 | vod_name: $(this).text(), 169 | vod_remarks: remark, 170 | vod_tag: "folder", 171 | }) 172 | }); 173 | }); 174 | result.pagecount = 1; 175 | } else { 176 | listVideos(result); 177 | } 178 | return result; 179 | }, 180 | detailContent: function (ids) { 181 | let vodActor = [], categories = [], tags = []; 182 | $(".video-info .info-header .models .model").each(function () { 183 | const url = new URL($(this).attr("href")).pathname.split('/'); 184 | const id = url[1] + "/" + url[2]; 185 | const name = $(this).find(".rounded-circle").data("original-title"); 186 | vodActor.push(`[a=cr:{"id":"${id}","name":"${name}"}/]${name}[/a]`); 187 | }); 188 | $(".video-info .tags .cat").each(function () { 189 | const url = new URL($(this).attr("href")).pathname.split('/'); 190 | const id = url[1] + "/" + url[2]; 191 | const name = $(this).text(); 192 | categories.push(`[a=cr:{"id":"${id}","name":"${name}"}/]#${name}[/a]`); 193 | }); 194 | $(".video-info .tags a:not(.cat)").each(function () { 195 | const url = new URL($(this).attr("href")).pathname.split('/'); 196 | const id = url[1] + "/" + url[2]; 197 | const name = $(this).text(); 198 | tags.push(`[a=cr:{"id":"${id}","name":"${name}"}/]#${name}[/a]`); 199 | }); 200 | const vod = { 201 | vod_id: ids[0], 202 | vod_name: ids[0].toUpperCase(), 203 | vod_pic: $("#player").attr("poster"), 204 | vod_year: "更新於 " + $(".video-info .info-header .mr-3:first").text() + " " + $(".video-info .info-header .inactive-color").text(), 205 | vod_remarks: tags.join(" "), 206 | vod_actor: vodActor.join(" ") + " " + categories.join(" "), 207 | vod_content: $(".video-info h4").text(), 208 | vod_play_from: $(".video-info .info-header .header-right h6").children().remove().end().text().trim(), 209 | vod_play_url: "1080P$" + unsafeWindow.hlsUrl, 210 | }; 211 | return {list: [vod]}; 212 | }, 213 | searchContent: function (key, quick, pg) { 214 | const result = { 215 | list: [], 216 | pagecount: 1 217 | }; 218 | listVideos(result); 219 | return result; 220 | } 221 | }; 222 | })(); 223 | $(document).ready(function () { 224 | let result = ""; 225 | if ($("#cf-wrapper").length > 0) { 226 | console.log("源站不可用:" + $('title').text()); 227 | GM_toastLong("源站不可用:" + $('title').text()); 228 | } else { 229 | result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 230 | } 231 | console.log(result); 232 | if (typeof GmSpiderInject !== 'undefined') { 233 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 234 | } 235 | }); 236 | })(); 237 | 238 | -------------------------------------------------------------------------------- /userScripts/missav.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name MissAV 3 | // @namespace gmspider 4 | // @version 2024.12.03 5 | // @description MissAV GMSpider 6 | // @author Luomo 7 | // @match https://missav.*/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @grant unsafeWindow 10 | // ==/UserScript== 11 | console.log(JSON.stringify(GM_info)); 12 | (function () { 13 | const GMSpiderArgs = {}; 14 | if (typeof GmSpiderInject !== 'undefined') { 15 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 16 | GMSpiderArgs.fName = args.shift(); 17 | GMSpiderArgs.fArgs = args; 18 | } else { 19 | GMSpiderArgs.fName = "detailContent"; 20 | GMSpiderArgs.fArgs = [true]; 21 | } 22 | Object.freeze(GMSpiderArgs); 23 | const GmSpider = (function () { 24 | const filter = { 25 | key: "filter", 26 | name: "过滤", 27 | value: [{ 28 | n: "所有", 29 | v: "" 30 | }, { 31 | n: "单人作品", 32 | v: "&filters=individual" 33 | }, { 34 | n: "多人作品", 35 | v: "&filters=multiple" 36 | }, { 37 | n: "中文字幕", 38 | v: "&filters=chinese-subtitle" 39 | }] 40 | }; 41 | const filterWithoutSort = [ 42 | filter 43 | ]; 44 | const defaultFilter = [ 45 | filter, 46 | { 47 | key: "sort", 48 | name: "排序方式", 49 | value: [ 50 | { 51 | n: "发行日期", 52 | v: "&sort=released_at" 53 | }, 54 | { 55 | n: "最近更新", 56 | v: "&sort=published_at" 57 | }, 58 | { 59 | n: "收藏数", 60 | v: "&sort=saved" 61 | }, 62 | { 63 | n: "今日浏览数", 64 | v: "&sort=today_views" 65 | }, 66 | { 67 | n: "本周浏览数", 68 | v: "&sort=weekly_views" 69 | }, 70 | { 71 | n: "本月浏览数", 72 | v: "&sort=monthly_views" 73 | }, 74 | { 75 | n: "总浏览数", 76 | v: "&sort=views" 77 | } 78 | ] 79 | }]; 80 | 81 | function pageList(result) { 82 | result.pagecount = parseInt($("#price-currency").text().replace(/[^0-9]/ig, "")); 83 | result.total = result.pagecount * result.limit; 84 | $(".gap-5 .thumbnail").each(function (i) { 85 | result.list.push({ 86 | vod_id: $(this).find(".text-secondary").attr("alt"), 87 | vod_name: $(this).find(".text-secondary").text().trim(), 88 | vod_pic: $(this).find("img").data("src"), 89 | vod_year: $(this).find(".right-1").text().trim(), 90 | vod_remarks: $(this).find(".left-1").text().trim(), 91 | }) 92 | }); 93 | return result; 94 | } 95 | 96 | function categoryList(result) { 97 | $(".gap-4 div").each(function () { 98 | result.list.push({ 99 | vod_id: getCategoryFromUrl($(this).find(".text-nord13").attr("href")), 100 | vod_name: $(this).find(".text-nord13").text().trim(), 101 | vod_remarks: $(this).find(".text-nord10 a").text().trim(), 102 | vod_tag: "folder", 103 | style: { 104 | "type": "rect", 105 | "ratio": 2 106 | } 107 | }) 108 | }); 109 | result.limit = 36; 110 | result.pagecount = parseInt($("#price-currency").text().replace(/[^0-9]/ig, "")); 111 | result.total = result.pagecount * result.limit; 112 | return result; 113 | } 114 | 115 | function getCategoryFromUrl(url) { 116 | return url.split('/cn/').at(1); 117 | } 118 | 119 | function formatDetail(detail, ...keys) { 120 | let format = ""; 121 | for (let key of keys) { 122 | format += key in detail ? (Array.isArray(detail[key]) ? detail[key].join(" ") : detail[key]) : ""; 123 | } 124 | return format; 125 | } 126 | 127 | return { 128 | homeContent: function (filter) { 129 | let result = { 130 | class: [ 131 | {type_id: "new", type_name: "所有影片"}, 132 | {type_id: "madou", type_name: "麻豆传媒"}, 133 | {type_id: "chinese-subtitle", type_name: "中文字幕"}, 134 | {type_id: "uncensored-leak", type_name: "无码流出"}, 135 | {type_id: "actresses/ranking", type_name: "热门女优"}, 136 | {type_id: "makers", type_name: "发行商"}, 137 | {type_id: "genres", type_name: "类型"}, 138 | ], 139 | filters: { 140 | "new": defaultFilter, 141 | "madou": defaultFilter, 142 | "chinese-subtitle": defaultFilter, 143 | "uncensored-leak": defaultFilter, 144 | "actresses/ranking": defaultFilter, 145 | "makers": defaultFilter, 146 | "genres": defaultFilter 147 | }, 148 | list: [] 149 | }; 150 | $(".gap-5:eq(5) .thumbnail").each(function () { 151 | result.list.push({ 152 | vod_id: $(this).find(".text-secondary").attr("alt"), 153 | vod_name: $(this).find(".text-secondary").text().trim(), 154 | vod_pic: $(this).find("img").data("src"), 155 | vod_year: $(this).find(".absolute").text().trim() 156 | }) 157 | }); 158 | console.log(result); 159 | return result; 160 | }, 161 | categoryContent: function (tid, pg, filter, extend) { 162 | let result = { 163 | list: [], 164 | limit: 12, 165 | total: 0, 166 | page: pg, 167 | pagecount: 0 168 | }; 169 | if (tid === "actresses/ranking") { 170 | $(".gap-4 .space-y-4").each(function () { 171 | result.list.push({ 172 | vod_id: getCategoryFromUrl($(this).find(".space-y-2 a").attr("href")), 173 | vod_name: $(this).find(".truncate").text().trim(), 174 | vod_pic: $(this).find("img").length > 0 ? $(this).find("img").attr("src") : "", 175 | vod_remarks: $(this).find(".text-sm").text().trim(), 176 | vod_tag: "folder", 177 | style: { 178 | "type": "rect", 179 | "ratio": 1 180 | } 181 | }) 182 | }); 183 | result.limit = 100; 184 | result.total = 100; 185 | result.pagecount = 1; 186 | } else if (tid === "makers") { 187 | function getNavs(name) { 188 | $("nav.hidden .relative a.group span:contains('" + name + "')").parents(".relative:first").find(".py-1 a").each(function () { 189 | result.list.push({ 190 | vod_id: getCategoryFromUrl($(this).attr("href")), 191 | vod_name: $(this).text().trim(), 192 | vod_remarks: name, 193 | vod_tag: "folder", 194 | style: { 195 | "type": "rect", 196 | "ratio": 2 197 | } 198 | }) 199 | }) 200 | } 201 | 202 | if (pg == 1) { 203 | getNavs("国产 AV"); 204 | getNavs("无码影片"); 205 | getNavs("素人"); 206 | } 207 | result = categoryList(result) 208 | } else if (tid === "genres") { 209 | result = categoryList(result) 210 | } else { 211 | result = pageList(result); 212 | } 213 | return result; 214 | }, 215 | detailContent: function (ids) { 216 | let detail = {}; 217 | $(".space-y-2:not(.list-disc) .text-secondary").each(function () { 218 | const key = $(this).find("span:first").text().replace(":", ""); 219 | if ($(this).find("a").length === 0) { 220 | detail[key] = $(this).find("span:first").remove().end().text().trim(); 221 | } else { 222 | detail[key] = []; 223 | $(this).find("a").each(function () { 224 | const id = getCategoryFromUrl($(this).attr("href")); 225 | const name = $(this).text(); 226 | detail[key].push(`[a=cr:{"id":"${id}","name":"${name}"}/]${name}[/a]`); 227 | }) 228 | } 229 | }); 230 | 231 | console.log($('a.items-center:contains("显示更多")')); 232 | const vod = { 233 | vod_id: ids[0], 234 | vod_name: ids[0].toUpperCase(), 235 | vod_pic: $("head link[as=image]").attr("href"), 236 | vod_year: $("#space-y-2 time").text(), 237 | vod_remarks: formatDetail(detail, "类型"), 238 | vod_actor: formatDetail(detail, "女优"), 239 | vod_content: $('a.items-center:contains("显示更多")').length > 0 ? $("head meta[name=description]").attr("content") : $("head meta[property='og:title']").attr("content"), 240 | vod_play_from: "MissAV", 241 | vod_play_url: "多视轨$" + hls.url, 242 | }; 243 | console.log({list: [vod]}) 244 | return {list: [vod]}; 245 | }, 246 | searchContent: function (key, quick, pg) { 247 | let result = { 248 | list: [], 249 | limit: 12, 250 | total: 0, 251 | page: pg, 252 | pagecount: 0 253 | }; 254 | result = pageList(result); 255 | return result; 256 | } 257 | }; 258 | })(); 259 | $(document).ready(function () { 260 | let result = ""; 261 | if ($("#cf-wrapper").length > 0) { 262 | console.log("源站不可用:" + $('title').text()); 263 | GM_toastLong("源站不可用:" + $('title').text()); 264 | } else { 265 | result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 266 | } 267 | console.log(result); 268 | if (typeof GmSpiderInject !== 'undefined') { 269 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 270 | } 271 | }); 272 | })(); -------------------------------------------------------------------------------- /userScripts/netflav.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name NETFLAV 3 | // @namespace gmspider 4 | // @version 2024.12.11 5 | // @description NETFLAV GMSpider 6 | // @author Luomo 7 | // @match https://netflav.com/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @grant unsafeWindow 10 | // ==/UserScript== 11 | console.log(JSON.stringify(GM_info)); 12 | if (typeof unsafeWindow.gmSpiderRunning === "undefined") { 13 | unsafeWindow.gmSpiderRunning = true; 14 | (function () { 15 | const GMSpiderArgs = {}; 16 | if (typeof GmSpiderInject !== 'undefined') { 17 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 18 | GMSpiderArgs.fName = args.shift(); 19 | GMSpiderArgs.fArgs = args; 20 | } else { 21 | GMSpiderArgs.fName = "categoryContent"; 22 | GMSpiderArgs.fArgs = ["2024?"]; 23 | } 24 | Object.freeze(GMSpiderArgs); 25 | let _gotHookFunction = function () { 26 | console.log("_gotHookFunction hook failed"); 27 | }; 28 | let itemCount = 0; 29 | let gotItems = []; 30 | Object.defineProperty(Object.prototype, 'componentDidMount', { 31 | configurable: true, 32 | get: function () { 33 | let item = this?.props?.item; 34 | if (typeof item?.videoId !== "undefined") { 35 | gotItems.push(item); 36 | if (gotItems.length === itemCount) { 37 | _gotHookFunction(gotItems); 38 | } 39 | } 40 | return true; 41 | }, 42 | set: function (value) { 43 | return true; 44 | }, 45 | }); 46 | 47 | const GmSpider = (function () { 48 | function getVideos(key, result) { 49 | const formatData = JSON.parse($("#__NEXT_DATA__").html()); 50 | let vods = []; 51 | formatData.props.initialState[key].docs.forEach(function (media) { 52 | vods.push({ 53 | vod_id: media.videoId, 54 | vod_name: media.title, 55 | vod_pic: media.preview.length > 0 ? media.preview : media.preview_hp, 56 | vod_remarks: "👁️" + media.views, 57 | }) 58 | }); 59 | if (typeof result == "object") { 60 | result.list = vods; 61 | result.pagecount = formatData.props.initialState[key].pages; 62 | } 63 | return vods; 64 | } 65 | 66 | return { 67 | homeContent: function (filter) { 68 | let result = { 69 | class: [ 70 | {type_id: "trending?", type_name: "最受欢迎"}, 71 | {type_id: "browse?", type_name: "年度精选"}, 72 | {type_id: "chinese-sub?", type_name: "中文字幕"}, 73 | {type_id: "all?genre=國產AV", type_name: "国产AV"}, 74 | {type_id: "censored?", type_name: "有码影片"}, 75 | {type_id: "uncensored?", type_name: "无码影片"}, 76 | {type_id: "genre?", type_name: "类别"}], 77 | filters: { 78 | "trending?": [{ 79 | key: "range", name: "时间", value: [{ 80 | n: "全部", v: "" 81 | }, { 82 | n: "本月", v: "&range=month&value=1" 83 | }, { 84 | n: "上个月", v: "&range=month&value=2" 85 | }, { 86 | n: "2个月前", v: "&range=month&value=3" 87 | }, { 88 | n: "3个月前", v: "&range=month&value=4" 89 | }, { 90 | n: "4个月前", v: "&range=month&value=5" 91 | }, { 92 | n: "5个月前", v: "&range=month&value=6" 93 | }] 94 | }] 95 | }, list: [] 96 | }; 97 | result.list = getVideos("trending"); 98 | return result; 99 | }, categoryContent: function (tid, pg, filter, extend) { 100 | console.log(tid, pg, filter, extend); 101 | let result = { 102 | list: [], pagecount: 1 103 | }; 104 | if (tid === "genre?") { 105 | $(".genre_item_container .genre_item").each(function () { 106 | result.list.push({ 107 | vod_id: $(this).attr("href").substring(1), 108 | vod_name: $(this).find("div").text(), 109 | vod_tag: "folder", 110 | style: { 111 | "type": "rect", "ratio": 1 112 | } 113 | }) 114 | }) 115 | } else if (tid === "browse?") { 116 | result.list.push( 117 | { 118 | vod_id: "2024?", vod_name: "2024年度精选", vod_remarks: "年度精选", vod_tag: "folder" 119 | }, { 120 | vod_id: "2023?", vod_name: "2023年度精选", vod_remarks: "年度精选", vod_tag: "folder" 121 | }, { 122 | vod_id: "2022?", vod_name: "2022年度精选", vod_remarks: "年度精选", vod_tag: "folder" 123 | }, { 124 | vod_id: "2021?", vod_name: "2021年度精选", vod_remarks: "年度精选", vod_tag: "folder" 125 | }, { 126 | vod_id: "2020?", vod_name: "2020年度精选", vod_remarks: "年度精选", vod_tag: "folder" 127 | }, { 128 | vod_id: "2019?", vod_name: "2019年度精选", vod_remarks: "年度精选", vod_tag: "folder" 129 | }); 130 | const formatData = JSON.parse($("#__NEXT_DATA__").html()); 131 | formatData.props.initialState.randomShareList.docs.forEach(function (share) { 132 | result.list.push({ 133 | vod_id: `share?c=${share.shareCode}`, 134 | vod_name: share.shareCode, 135 | vod_remarks: "片单", 136 | vod_pic: share.srcs[0], 137 | vod_tag: "folder" 138 | }) 139 | }); 140 | } else { 141 | const formatData = JSON.parse($("#__NEXT_DATA__").html()); 142 | const key = tid.split("?").at(0).split("-").at(0); 143 | if ($.isNumeric(key)) { 144 | $(".playlist_grid_full a").each(function () { 145 | result.list.push({ 146 | vod_id: $(this).attr("href").substring(1), 147 | vod_name: $(this).find(".playlist_head div").eq(1).text().trim(), 148 | vod_remarks: "片单", 149 | vod_pic: $(this).find("img").eq(1).attr("src"), 150 | vod_tag: "folder" 151 | }) 152 | }); 153 | console.log(gotItems.length, $(".video_grid_container .grid_0_cell").length); 154 | if (gotItems.length === $(".video_grid_container .grid_0_cell").length) { 155 | gotItems.forEach(function (media) { 156 | result.list.push({ 157 | vod_id: media.videoId, 158 | vod_name: media.title, 159 | vod_pic: media.preview.length > 0 ? media.preview : media.preview_hp, 160 | vod_remarks: media.duration, 161 | }) 162 | }) 163 | } else { 164 | return new Promise(function (resolve) { 165 | _gotHookFunction = resolve; 166 | itemCount = $(".video_grid_container .grid_0_cell").length; 167 | }).then((items) => { 168 | items.forEach(function (media) { 169 | result.list.push({ 170 | vod_id: media.videoId, 171 | vod_name: media.title, 172 | vod_pic: media.preview.length > 0 ? media.preview : media.preview_hp, 173 | vod_remarks: media.duration, 174 | }) 175 | }) 176 | return result 177 | }); 178 | } 179 | } else { 180 | getVideos(key, result); 181 | } 182 | } 183 | return result; 184 | }, 185 | detailContent: function (ids) { 186 | const formatData = JSON.parse($("#__NEXT_DATA__").html()); 187 | const video = formatData.props.initialState.video.data; 188 | let vodActor = [], tags = []; 189 | video?.actors.forEach(function (actor) { 190 | if (actor.startsWith("zh:")) { 191 | const actress = actor.substring(3); 192 | vodActor.push(`[a=cr:{"id":"all?actress=${actress}","name":"${actress}"}/]${actress}[/a]`); 193 | } 194 | }) 195 | video?.tags.forEach(function (tag) { 196 | if (tag.startsWith("zh:")) { 197 | const genre = tag.substring(3); 198 | tags.push(`[a=cr:{"id":"all?genre=${genre}","name":"${genre}"}/]${genre}[/a]`); 199 | } 200 | }) 201 | let vodPlayData = []; 202 | video?.srcs.forEach(function (src, index) { 203 | vodPlayData.push({ 204 | from: `播放源${index + 1}`, 205 | media: [{ 206 | name: video?.category ?? video.code, 207 | type: "webview", 208 | ext: { 209 | replace: { 210 | vod_id: video.videoId, 211 | src: index + 1 212 | } 213 | } 214 | }] 215 | }) 216 | }) 217 | return { 218 | vod_id: video.videoId, 219 | vod_name: video.code, 220 | vod_pic: video.preview_hp, 221 | vod_year: video.videoDate.substring(0, 10), 222 | vod_remarks: tags.join(" "), 223 | vod_actor: vodActor.join(" "), 224 | vod_content: video.description, 225 | vod_play_data: vodPlayData 226 | }; 227 | }, 228 | playerContent: function (flag, id, vipFlags) { 229 | let link = window.location.hash.split("#").at(1); 230 | document.querySelector(`.videoiframe_source_container .videoiframe_source_tag:nth-child(${link})`).dispatchEvent(new Event("click")); 231 | return { 232 | type: "match" 233 | }; 234 | }, 235 | searchContent: function (key, quick, pg) { 236 | const result = { 237 | list: [], pagecount: 1 238 | }; 239 | getVideos("search", result); 240 | return result; 241 | } 242 | }; 243 | })(); 244 | $(document).ready(async function () { 245 | let result = await GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 246 | console.log(result); 247 | if (typeof GmSpiderInject !== 'undefined') { 248 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 249 | } 250 | }); 251 | })(); 252 | } else { 253 | console.log("gmSpider run again"); 254 | } 255 | -------------------------------------------------------------------------------- /userScripts/supjav.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Supjav 3 | // @namespace gmspider 4 | // @version 2024.12.03 5 | // @description Supjav GMSpider 6 | // @author Luomo 7 | // @match https://supjav.com/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @grant GM_cookie 10 | // @grant unsafeWindow 11 | // ==/UserScript== 12 | console.log(JSON.stringify(GM_info)); 13 | (function () { 14 | const GMSpiderArgs = {}; 15 | if (typeof GmSpiderInject !== 'undefined') { 16 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 17 | GMSpiderArgs.fName = args.shift(); 18 | GMSpiderArgs.fArgs = args; 19 | } else { 20 | GMSpiderArgs.fName = "homeContent"; 21 | GMSpiderArgs.fArgs = ["tag"]; 22 | } 23 | Object.freeze(GMSpiderArgs); 24 | const GmSpider = (function () { 25 | function listVideos() { 26 | let itemList = []; 27 | $(".post").each(function () { 28 | const url = new URL($(this).find(".img").attr("href")); 29 | itemList.push({ 30 | vod_id: url.pathname.split('/').at(2), 31 | vod_name: $(this).find(".img").attr("title"), 32 | vod_pic: formatImgUrl($(this).find("img").data("original")), 33 | vod_remarks: $(this).find(".date").text(), 34 | vod_year: $(this).find(".meta").children().remove().end().text() 35 | }) 36 | }); 37 | return itemList; 38 | } 39 | 40 | let cf_clearance = null; 41 | 42 | function formatImgUrl(url) { 43 | if (cf_clearance === null) { 44 | GM_cookie.list({name: "cf_clearance"}, function (cookies, error) { 45 | if (!error && cookies.length > 0) { 46 | cf_clearance = cookies[0].value; 47 | localStorage.setItem("cf_clearance", cf_clearance); 48 | } else { 49 | let cache_cf_clearance = localStorage.getItem("cf_clearance"); 50 | if (typeof cache_cf_clearance !== "undefined" && cache_cf_clearance !== null && cache_cf_clearance.length > 0) { 51 | cf_clearance = cache_cf_clearance; 52 | } 53 | } 54 | }); 55 | } 56 | if (cf_clearance !== null) { 57 | url = url + "@User-Agent=" + window.navigator.userAgent + "@Cookie=cf_clearance=" + cf_clearance; 58 | } 59 | return url; 60 | } 61 | 62 | return { 63 | homeContent: function (filter) { 64 | const defaultFilter = [{ 65 | key: "sort", 66 | name: "排序", 67 | value: [ 68 | { 69 | n: "观看数", 70 | v: "views" 71 | }, 72 | { 73 | n: "更新时间", 74 | v: "" 75 | } 76 | ] 77 | }]; 78 | let result = { 79 | class: [ 80 | {type_id: "popular", type_name: "热门"}, 81 | {type_id: "category/censored-jav", type_name: "有码"}, 82 | {type_id: "category/uncensored-jav", type_name: "无码"}, 83 | {type_id: "category/amateur", type_name: "素人"}, 84 | {type_id: "category/chinese-subtitles", type_name: "中文字幕"}, 85 | {type_id: "category/reducing-mosaic", type_name: "无码破解"}, 86 | {type_id: "category/english-subtitles", type_name: "英文字幕"}, 87 | {type_id: "tag", type_name: "类别"}, 88 | ], 89 | filters: { 90 | popular: [{ 91 | key: "sort", 92 | name: "时间", 93 | value: [ 94 | { 95 | n: "本月热门", 96 | v: "month" 97 | }, 98 | { 99 | n: "本周热门", 100 | v: "week" 101 | }, 102 | { 103 | n: "今日热门", 104 | v: "" 105 | } 106 | ] 107 | }] 108 | }, 109 | list: [] 110 | }; 111 | result.class.forEach((item) => { 112 | if (typeof result.filters[item.type_id] === "undefined") { 113 | result.filters[item.type_id] = defaultFilter; 114 | } 115 | }) 116 | result.list = listVideos() 117 | return result; 118 | }, 119 | categoryContent: function (tid, pg, filter, extend) { 120 | let result = { 121 | list: [], 122 | pagecount: 1 123 | }; 124 | if (tid === "tag") { 125 | $(".categorys .child").each(function () { 126 | const url = new URL($(this).find("a").attr("href")).pathname.split('/'); 127 | const text = $(this).text().trim().split("(") 128 | result.list.push({ 129 | vod_id: url[2] + "/" + url[3], 130 | vod_name: text[0], 131 | vod_remarks: parseInt(text[1]) + " 部影片", 132 | vod_tag: "folder", 133 | style: { 134 | "type": "rect", 135 | "ratio": 1 136 | } 137 | }) 138 | }); 139 | result.pagecount = $(".pagination li").not(".next-page").last().text().trim(); 140 | } else { 141 | if ($(".pagination li").length > 0) { 142 | result.pagecount = $(".pagination li").not(".next-page").last().text().trim(); 143 | } 144 | result.list = listVideos(); 145 | } 146 | return result; 147 | }, 148 | detailContent: function (ids) { 149 | $("#vserver").click(); 150 | let vodActor = [], tags = []; 151 | $(".post-meta .cats a").each(function () { 152 | const id = new URL($(this).attr("href")).pathname.replace("/zh/", ""); 153 | const name = $(this).text().trim(); 154 | vodActor.unshift(`[a=cr:{"id":"${id}","name":"${name}"}/]${name}[/a]`); 155 | }); 156 | $(".post-meta .tags a").each(function () { 157 | const id = new URL($(this).attr("href")).pathname.replace("/zh/", ""); 158 | const name = $(this).text().trim(); 159 | tags.push(`[a=cr:{"id":"${id}","name":"${name}"}/]#${name}[/a]`); 160 | }); 161 | let vodContent = $(".post-meta .img").attr("alt").trim(); 162 | let vodName = vodContent.replace("[无码破解]", ''); 163 | let match = vodName.match(/^[\w|-]+/g); 164 | if (match) { 165 | if (match[0].includes("-")) { 166 | vodName = match[0]; 167 | } else { 168 | match = vodContent.match(/^[\w]+\s[\w]+/g); 169 | if (match) { 170 | vodName = match[0].replace(" ", "-"); 171 | } 172 | } 173 | } 174 | let vodPlayData = []; 175 | let btnServers; 176 | if ($(".video-wrap .cd-server").length > 0) { 177 | btnServers = $(".video-wrap .cd-server:first .btn-server"); 178 | } else { 179 | btnServers = $(".video-wrap .btn-server"); 180 | 181 | } 182 | btnServers.each(function (i) { 183 | vodPlayData.push({ 184 | from: $(this).text().trim(), 185 | media: [{ 186 | name: vodName, 187 | type: "webview", 188 | ext: { 189 | replace: { 190 | pathname: ids[0], 191 | link: i 192 | } 193 | } 194 | }] 195 | }); 196 | }) 197 | const result = { 198 | list: [{ 199 | vod_id: ids[0], 200 | vod_name: vodName, 201 | vod_pic: formatImgUrl($(".post-meta .img").attr("src")), 202 | vod_actor: vodActor.join(" "), 203 | vod_remarks: tags.join(" "), 204 | vod_content: vodContent, 205 | vod_play_data: vodPlayData 206 | }] 207 | }; 208 | return result 209 | }, 210 | playerContent: function (flag, id, vipFlags) { 211 | const link = window.location.hash.split("#").at(1); 212 | document.querySelectorAll(`.video-wrap .btn-server`)[link].dispatchEvent(new Event("click")); 213 | return { 214 | type: "match" 215 | }; 216 | }, 217 | searchContent: function (key, quick, pg) { 218 | const result = { 219 | list: [], 220 | pagecount: 1 221 | }; 222 | result.list = listVideos(); 223 | if ($(".pagination li").length > 0) { 224 | result.pagecount = $(".pagination li").not(".next-page").last().text().trim(); 225 | } 226 | return result; 227 | } 228 | }; 229 | })(); 230 | $(unsafeWindow).on("load", function () { 231 | const result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 232 | console.log(result); 233 | if (typeof GmSpiderInject !== 'undefined') { 234 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 235 | } 236 | }); 237 | })(); 238 | 239 | -------------------------------------------------------------------------------- /userScripts/xojav.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name XOJAV 3 | // @namespace gmspider 4 | // @version 2024.12.02 5 | // @description XOJAV GMSpider 6 | // @author Luomo 7 | // @match https://xojav.tv/* 8 | // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.slim.min.js 9 | // @grant unsafeWindow 10 | // ==/UserScript== 11 | console.log(JSON.stringify(GM_info)); 12 | (function () { 13 | const GMSpiderArgs = {}; 14 | if (typeof GmSpiderInject !== 'undefined') { 15 | let args = JSON.parse(GmSpiderInject.GetSpiderArgs()); 16 | GMSpiderArgs.fName = args.shift(); 17 | GMSpiderArgs.fArgs = args; 18 | } else { 19 | GMSpiderArgs.fName = "searchContent"; 20 | GMSpiderArgs.fArgs = [["ssni-748"]]; 21 | } 22 | Object.freeze(GMSpiderArgs); 23 | const GmSpider = (function () { 24 | function listVideos(select) { 25 | let vods = []; 26 | $(select).each(function () { 27 | const remarks = [ 28 | "👁️" + $(this).find(".card-video__stats .num:first").text().trim(), 29 | "❤️" + $(this).find(".card-video__fav-button .num").text().trim() 30 | ]; 31 | const url = new URL($(this).find(".card-video__title a").attr("href")); 32 | vods.push({ 33 | vod_id: url.pathname.split('/').at(2).toUpperCase(), 34 | vod_name: $(this).find(".card-video__img img").attr("alt"), 35 | vod_pic: $(this).find(".card-video__img img").data("src"), 36 | vod_remarks: remarks.join(" "), 37 | vod_year: $(this).find(".card-video__duration").text().trim() 38 | }) 39 | }) 40 | return vods; 41 | } 42 | 43 | return { 44 | homeContent: function (filter) { 45 | let result = { 46 | class: [ 47 | {type_id: "latest-updates?sort_by=release_at", type_name: "最近更新"}, 48 | {type_id: "categories/taiwan-av?sort_by=release_at", type_name: "台湾AV"}, 49 | {type_id: "stars?sort_by=stars", type_name: "近期最佳"}, 50 | {type_id: "hot?sort_by=views", type_name: "热门"}, 51 | {type_id: "categories?", type_name: "所有分类"}, 52 | ], 53 | filters: { 54 | "categories/taiwan-av?sort_by=release_at": [{ 55 | key: "sort_by", 56 | name: "排序", 57 | value: [ 58 | {n: "近期最佳", v: "&sort_by=stars"}, 59 | {n: "观看数", v: "&sort_by=views"}, 60 | {n: "最近更新", v: "&sort_by=release_at"} 61 | ] 62 | }], 63 | "categories?": [{ 64 | key: "sort_by", 65 | name: "排序", 66 | value: [ 67 | {n: "近期最佳", v: "&sort_by=stars"}, 68 | {n: "观看数", v: "&sort_by=views"}, 69 | {n: "最近更新", v: "&sort_by=release_at"}, 70 | ] 71 | }] 72 | }, 73 | list: [] 74 | }; 75 | let itemList = listVideos(".card-video"); 76 | result.list = itemList.filter((item, index) => { 77 | return itemList.findIndex(i => i.vod_id === item.vod_id) === index 78 | }); 79 | return result; 80 | }, 81 | categoryContent: function (tid, pg, filter, extend) { 82 | let result = { 83 | list: [], 84 | pagecount: 1 85 | }; 86 | if (tid === "categories?") { 87 | $(".padding-bottom-xl").each(function () { 88 | let remarks = $(this).find(".title--listing").text().trim(); 89 | $(this).find(".card-cat-v2").each(function () { 90 | const url = new URL($(this).find(".card-cat-v2__link").attr("href")).pathname.split('/'); 91 | result.list.push({ 92 | vod_id: url[1] + "/" + url[2] + "?sort_by=release_at", 93 | vod_name: $(this).find(".card-cat-v2__title h4").text(), 94 | vod_pic: $(this).find("img").attr("src"), 95 | vod_remarks: remarks, 96 | vod_tag: "folder", 97 | style: { 98 | "type": "rect", 99 | "ratio": 0.7 100 | } 101 | }) 102 | }); 103 | }) 104 | result.pagecount = 1; 105 | } else { 106 | result.list = listVideos(".card-video"); 107 | result.pagecount = $('.pagination__list li[class] .pagination__item:last').text().trim(); 108 | } 109 | return result; 110 | }, 111 | detailContent: function (ids) { 112 | let categories = [], tags = []; 113 | $(".content-details__meta a").each(function () { 114 | const url = new URL($(this).attr("href")).pathname.split('/'); 115 | const id = url[1] + "/" + url[2] + "?sort_by=release_at"; 116 | const name = $(this).text().trim(); 117 | if (name.length > 0) { 118 | if (url[1] === "categories") { 119 | categories.push(`[a=cr:{"id":"${id}","name":"${name}"}/]${name}[/a]`); 120 | } else { 121 | tags.push(`[a=cr:{"id":"${id}","name":"${name}"}/]${name}[/a]`); 122 | } 123 | } 124 | }) 125 | const vod = { 126 | vod_id: ids[0], 127 | vod_name: ids[0].toUpperCase(), 128 | vod_year: $(".content-details__meta time").text(), 129 | vod_remarks: categories.join(" "), 130 | vod_actor: tags.join(" "), 131 | vod_content: $(".content-details__title").text(), 132 | vod_play_from: "XOJAV", 133 | vod_play_url: "720P$" + unsafeWindow.stream, 134 | }; 135 | return {list: [vod]}; 136 | }, 137 | searchContent: function (key, quick, pg) { 138 | const result = { 139 | list: [], 140 | pagecount: 1 141 | }; 142 | result.list = listVideos(".card-video"); 143 | result.pagecount = Math.ceil($('.title--sub-title').text().replace(/[^0-9]/ig, "") / 24) 144 | return result; 145 | } 146 | }; 147 | })(); 148 | $(document).ready(function () { 149 | let result = ""; 150 | if ($("#cf-wrapper").length > 0) { 151 | console.log("源站不可用:" + $('title').text()); 152 | GM_toastLong("源站不可用:" + $('title').text()); 153 | } else { 154 | result = GmSpider[GMSpiderArgs.fName](...GMSpiderArgs.fArgs); 155 | } 156 | console.log(result); 157 | if (typeof GmSpiderInject !== 'undefined') { 158 | GmSpiderInject.SetSpiderResult(JSON.stringify(result)); 159 | } 160 | }); 161 | })(); 162 | 163 | --------------------------------------------------------------------------------