diff --git a/app/src/main/java/com/github/catvod/bean/ali/Auth.java b/app/src/main/java/com/github/catvod/bean/ali/Auth.java index 92855641..997444fb 100644 --- a/app/src/main/java/com/github/catvod/bean/ali/Auth.java +++ b/app/src/main/java/com/github/catvod/bean/ali/Auth.java @@ -7,7 +7,10 @@ public class Auth { private String refreshToken; private String accessToken; private String shareToken; + private String signature; + private String deviceId; private String shareId; + private String userId; public String getRefreshToken() { return TextUtils.isEmpty(refreshToken) ? "" : refreshToken; @@ -33,6 +36,22 @@ public class Auth { this.shareToken = shareToken; } + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + public String getShareId() { return TextUtils.isEmpty(shareId) ? "" : shareId; } @@ -41,6 +60,14 @@ public class Auth { this.shareId = shareId; } + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + public boolean isEmpty() { return getAccessToken().isEmpty(); } diff --git a/app/src/main/java/com/github/catvod/demo/MainActivity.java b/app/src/main/java/com/github/catvod/demo/MainActivity.java index c952993d..981cfdba 100644 --- a/app/src/main/java/com/github/catvod/demo/MainActivity.java +++ b/app/src/main/java/com/github/catvod/demo/MainActivity.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.os.Bundle; import com.github.catvod.R; +import com.github.catvod.spider.Ali; import com.github.catvod.spider.Init; public class MainActivity extends Activity { @@ -14,7 +15,9 @@ public class MainActivity extends Activity { setContentView(R.layout.activity_main); Init.init(getApplicationContext()); new Thread(() -> { - + Ali ali = new Ali(); + ali.init("https://agit.ai/Yoursmile7/TVBox/raw/branch/master/token.txt"); + ali.playerContent("普畫", "63de1c59a77dc671045c4a35b42e96d5621f4dc0"); }).start(); } } \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/Ali.java b/app/src/main/java/com/github/catvod/spider/Ali.java index 00d5b7c8..7e1ccd23 100644 --- a/app/src/main/java/com/github/catvod/spider/Ali.java +++ b/app/src/main/java/com/github/catvod/spider/Ali.java @@ -6,6 +6,7 @@ import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.SystemClock; import android.text.TextUtils; +import android.util.Log; import android.view.Gravity; import android.widget.FrameLayout; import android.widget.ImageView; @@ -31,6 +32,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -74,8 +76,11 @@ public class Ali { private HashMap getAuthHeader() { HashMap headers = getHeaders(); - headers.put("authorization", auth.getAccessToken()); + headers.put("content-type", "application/json"); + headers.put("Authorization", auth.getAccessToken()); headers.put("x-share-token", auth.getShareToken()); + headers.put("x-device-id", auth.getDeviceId()); + headers.put("x-signature", auth.getSignature()); return headers; } @@ -194,8 +199,11 @@ public class Ali { body.put("refresh_token", token); body.put("grant_type", "refresh_token"); JSONObject object = new JSONObject(post("https://auth.aliyundrive.com/v2/account/token", body)); + auth.setUserId(object.getString("user_id")); + auth.setDeviceId(object.getString("device_id")); auth.setAccessToken(object.getString("token_type") + " " + object.getString("access_token")); auth.setRefreshToken(object.getString("refresh_token")); + generateSign(); return true; } catch (Exception e) { stopService(); @@ -207,6 +215,20 @@ public class Ali { } } + /* + * secpAppID := "5dde4e1bdf9e4966b387ba58f4b3fdc3" + * singdata := fmt.Sprintf("%s:%s:%s:%d", secpAppID, state.deviceID, d.UserID, state.nonce) + * hash := sha256.Sum256([]byte(singdata)) + * data, _ := ecc.SignBytes(state.privateKey, hash[:], ecc.RecID|ecc.LowerS) + * state.signature = hex.EncodeToString(data) + * */ + private void generateSign() throws Exception { + String appID = "5dde4e1bdf9e4966b387ba58f4b3fdc3"; + String signData = String.format(Locale.getDefault(), "%s:%s:%s:%d", appID, auth.getDeviceId(), auth.getUserId(), 0); + String signature = ""; + auth.setSignature(signature); + } + private boolean refreshShareToken() { try { JSONObject body = new JSONObject(); @@ -287,6 +309,7 @@ public class Ali { body.put("share_id", auth.getShareId()); body.put("expire_sec", 600); String json = postAuth("v2/file/get_share_link_download_url", body); + Log.e("DDD", json); String url = new JSONObject(json).optString("download_url"); Map> respHeaders = new HashMap<>(); OkHttp.stringNoRedirect(url, getHeaders(), respHeaders); diff --git a/app/src/main/java/com/github/catvod/spider/XPath.java b/app/src/main/java/com/github/catvod/spider/XPath.java index 78dd0990..0ba54f90 100644 --- a/app/src/main/java/com/github/catvod/spider/XPath.java +++ b/app/src/main/java/com/github/catvod/spider/XPath.java @@ -6,15 +6,14 @@ import android.text.TextUtils; import com.github.catvod.bean.Class; import com.github.catvod.bean.Result; import com.github.catvod.bean.Vod; +import com.github.catvod.bean.xpath.Rule; import com.github.catvod.crawler.Spider; import com.github.catvod.crawler.SpiderDebug; import com.github.catvod.net.OkHttp; -import com.github.catvod.utils.Utils; import com.github.catvod.utils.Trans; -import com.github.catvod.bean.xpath.Rule; +import com.github.catvod.utils.Utils; import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; import org.seimicrawler.xpath.JXDocument; import org.seimicrawler.xpath.JXNode; @@ -27,38 +26,32 @@ import java.util.Set; public class XPath extends Spider { - protected Rule rule = null; - private HashMap getHeaders() { HashMap headers = new HashMap<>(); headers.put("User-Agent", rule.getUa().isEmpty() ? Utils.CHROME : rule.getUa()); return headers; } - private void fetchRule(String ext) { - if (ext.startsWith("http")) { - String json = OkHttp.string(ext); - rule = Rule.fromJson(json); - loadRuleExt(json); - } else { - rule = Rule.fromJson(ext); - loadRuleExt(ext); - } + @Override + public void init(Context context) { + super.init(context); } - @Override public void init(Context context, String extend) { super.init(context, extend); - fetchRule(extend); + this.ext = extend; } @Override - public String homeContent(boolean filter) throws JSONException { + public String homeContent(boolean filter) { + fetchRule(); List list = new ArrayList<>(); List classes = new ArrayList<>(); if (rule.getCateManual().size() > 0) { Set keys = rule.getCateManual().keySet(); - for (String k : keys) classes.add(new Class(rule.getCateManual().get(k), k)); + for (String k : keys) { + classes.add(new Class(rule.getCateManual().get(k), k)); + } } String webUrl = rule.getHomeUrl(); JXDocument doc = JXDocument.create(fetch(webUrl)); @@ -103,8 +96,9 @@ public class XPath extends Spider { @Override public String categoryContent(String tid, String pg, boolean filter, HashMap extend) { - String webUrl = categoryUrl(tid, pg, filter, extend); + fetchRule(); List list = new ArrayList<>(); + String webUrl = categoryUrl(tid, pg, filter, extend); JXDocument doc = JXDocument.create(fetch(webUrl)); List vodNodes = doc.selN(rule.getCateVodNode()); for (int i = 0; i < vodNodes.size(); i++) { @@ -130,7 +124,8 @@ public class XPath extends Spider { } @Override - public String detailContent(List ids) throws JSONException { + public String detailContent(List ids) { + fetchRule(); String webUrl = rule.getDetailUrl().replace("{vid}", ids.get(0)); String webContent = fetch(webUrl); JXDocument doc = JXDocument.create(webContent); @@ -138,15 +133,9 @@ public class XPath extends Spider { String cover = "", title = "", desc = "", category = "", area = "", year = "", remark = "", director = "", actor = ""; title = vodNode.selOne(rule.getDetailName()).asString().trim(); title = rule.getDetailNameR(title); - if (!rule.getDetailImg().isEmpty()) { - try { - cover = vodNode.selOne(rule.getDetailImg()).asString().trim(); - cover = rule.getDetailImgR(cover); - cover = Utils.fixUrl(webUrl, cover); - } catch (Exception e) { - SpiderDebug.log(e); - } - } + cover = vodNode.selOne(rule.getDetailImg()).asString().trim(); + cover = rule.getDetailImgR(cover); + cover = Utils.fixUrl(webUrl, cover); if (!rule.getDetailCate().isEmpty()) { try { category = vodNode.selOne(rule.getDetailCate()).asString().trim(); @@ -236,11 +225,13 @@ public class XPath extends Spider { id = rule.getDetailUrlIdR(id); vodItems.add(Trans.get(name) + "$" + id); } + // 排除播放列表為空的播放源 if (vodItems.size() == 0 && playFrom.size() > i) { playFrom.set(i, ""); } playList.add(TextUtils.join("#", vodItems)); } + // 排除播放列表為空的播放源 for (int i = playFrom.size() - 1; i >= 0; i--) { if (playFrom.get(i).isEmpty()) playFrom.remove(i); } @@ -257,6 +248,7 @@ public class XPath extends Spider { @Override public String playerContent(String flag, String id, List vipFlags) { + fetchRule(); String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id); SpiderDebug.log(webUrl); HashMap headers = new HashMap<>(); @@ -266,7 +258,8 @@ public class XPath extends Spider { } @Override - public String searchContent(String key, boolean quick) throws JSONException { + public String searchContent(String key, boolean quick) throws Exception { + fetchRule(); if (rule.getSearchUrl().isEmpty()) return ""; String webUrl = rule.getSearchUrl().replace("{wd}", URLEncoder.encode(key)); String webContent = fetch(webUrl); @@ -320,6 +313,34 @@ public class XPath extends Spider { return Result.string(list); } + @Override + public boolean manualVideoCheck() { + return false; + } + + @Override + public boolean isVideoFormat(String url) { + return Utils.isVideoFormat(url); + } + + protected String ext = null; + protected Rule rule = null; + + protected void fetchRule() { + if (rule == null) { + if (ext != null) { + if (ext.startsWith("http")) { + String json = OkHttp.string(ext, null); + rule = Rule.fromJson(json); + loadRuleExt(json); + } else { + rule = Rule.fromJson(ext); + loadRuleExt(ext); + } + } + } + } + protected void loadRuleExt(String json) { } @@ -327,4 +348,4 @@ public class XPath extends Spider { SpiderDebug.log(webUrl); return OkHttp.string(webUrl, getHeaders()); } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/XPathFilter.java b/app/src/main/java/com/github/catvod/spider/XPathFilter.java index 1a1bbb7c..604166c4 100644 --- a/app/src/main/java/com/github/catvod/spider/XPathFilter.java +++ b/app/src/main/java/com/github/catvod/spider/XPathFilter.java @@ -1,7 +1,5 @@ package com.github.catvod.spider; -import android.text.TextUtils; - import java.net.URLEncoder; import java.util.HashMap; import java.util.regex.Matcher; @@ -9,14 +7,20 @@ import java.util.regex.Pattern; public class XPathFilter extends XPath { + @Override + protected void loadRuleExt(String json) { + super.loadRuleExt(json); + } + @Override protected String categoryUrl(String tid, String pg, boolean filter, HashMap extend) { String cateUrl = rule.getCateUrl(); if (filter && extend != null && extend.size() > 0) { for (String key : extend.keySet()) { String value = extend.get(key); - if (TextUtils.isEmpty(value)) continue; - cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value)); + if (value.length() > 0) { + cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value)); + } } } cateUrl = cateUrl.replace("{cateId}", tid).replace("{catePg}", pg); diff --git a/app/src/main/java/com/github/catvod/spider/XPathMac.java b/app/src/main/java/com/github/catvod/spider/XPathMac.java index 610761ca..841f18cf 100644 --- a/app/src/main/java/com/github/catvod/spider/XPathMac.java +++ b/app/src/main/java/com/github/catvod/spider/XPathMac.java @@ -1,10 +1,13 @@ package com.github.catvod.spider; +import android.content.Context; import android.text.TextUtils; import android.util.Base64; import com.github.catvod.crawler.SpiderDebug; +import com.github.catvod.utils.Trans; import com.github.catvod.utils.Utils; +import com.google.gson.Gson; import org.json.JSONException; import org.json.JSONObject; @@ -30,7 +33,17 @@ public class XPathMac extends XPath { // 播放器配置js取值正則 private String playerConfigJsRegex = "[\\W|\\S|.]*?MacPlayerConfig.player_list[\\W|\\S|.]*?=([\\W|\\S|.]*?),MacPlayerConfig.downer_list"; // 站點里播放源對應的真實官源 - private HashMap show2VipFlag = new HashMap<>(); + private final HashMap show2VipFlag = new HashMap<>(); + + /** + * mac cms 直連和官源調用應用內播放列表支持 + * + * @param context + * @param extend + */ + public void init(Context context, String extend) { + super.init(context, extend); + } @Override protected void loadRuleExt(String json) { @@ -43,51 +56,68 @@ public class XPathMac extends XPath { Iterator keys = dcShow2Vip.keys(); while (keys.hasNext()) { String name = keys.next(); - show2VipFlag.put(name.trim(), dcShow2Vip.getString(name).trim()); + show2VipFlag.put(Trans.get(name.trim()), dcShow2Vip.getString(name).trim()); } } playerConfigJs = jsonObj.optString("pCfgJs").trim(); playerConfigJsRegex = jsonObj.optString("pCfgJsR", playerConfigJsRegex).trim(); - } catch (Exception e) { + } catch (JSONException e) { SpiderDebug.log(e); } } @Override - public String homeContent(boolean filter) throws JSONException { + public String homeContent(boolean filter) { String result = super.homeContent(filter); - if (result.isEmpty() || playerConfigJs.isEmpty()) return result; - //嘗試通過playerConfigJs獲取展示和flag匹配關系 - String webContent = fetch(playerConfigJs); - Matcher matcher = Pattern.compile(playerConfigJsRegex).matcher(webContent); - if (!matcher.find()) return result; - JSONObject jsonObject = new JSONObject(matcher.group(1)); - Iterator keys = jsonObject.keys(); - while (keys.hasNext()) { - String key = keys.next(); - JSONObject keyObj = jsonObject.optJSONObject(key); - if (keyObj == null) continue; - String show = keyObj.optString("show").trim(); - if (show.isEmpty()) continue; - show2VipFlag.put(show, key); + if (result.length() > 0 && playerConfigJs.length() > 0) { // 嘗試通過playerConfigJs獲取展示和flag匹配關系 + String webContent = fetch(playerConfigJs); + Matcher matcher = Pattern.compile(playerConfigJsRegex).matcher(webContent); + if (matcher.find()) { + try { + JSONObject jsonObject = new JSONObject(matcher.group(1)); + Iterator keys = jsonObject.keys(); + while (keys.hasNext()) { + String key = keys.next(); + JSONObject keyObj = jsonObject.optJSONObject(key); + if (keyObj == null) continue; + String show = keyObj.optString("show").trim(); + if (show.isEmpty()) continue; + show2VipFlag.put(Trans.get(show), key); + } + } catch (Exception e) { + SpiderDebug.log(e); + } + } } return result; } @Override - public String detailContent(List ids) throws JSONException { + public String detailContent(List ids) { String result = super.detailContent(ids); - if (!decodeVipFlag || result.isEmpty()) return result; - JSONObject jsonObject = new JSONObject(result); - String[] playFrom = jsonObject.optJSONArray("list").getJSONObject(0).optString("vod_play_from").split("\\$\\$\\$"); - if (playFrom.length == 0) return result; - for (int i = 0; i < playFrom.length; i++) if (show2VipFlag.containsKey(playFrom[i])) playFrom[i] = show2VipFlag.get(playFrom[i]); - jsonObject.optJSONArray("list").getJSONObject(0).put("vod_play_from", TextUtils.join("$$$", playFrom)); - return jsonObject.toString(); + if (decodeVipFlag && result.length() > 0) { + try { + JSONObject jsonObject = new JSONObject(result); + String[] playFrom = jsonObject.optJSONArray("list").getJSONObject(0).optString("vod_play_from").split("\\$\\$\\$"); + if (playFrom.length > 0) { + for (int i = 0; i < playFrom.length; i++) { + if (show2VipFlag.containsKey(playFrom[i])) { + playFrom[i] = show2VipFlag.get(playFrom[i]); + } + } + jsonObject.optJSONArray("list").getJSONObject(0).put("vod_play_from", TextUtils.join("$$$", playFrom)); + result = jsonObject.toString(); + } + } catch (Throwable th) { + SpiderDebug.log(th); + } + } + return result; } @Override public String playerContent(String flag, String id, List vipFlags) { + fetchRule(); String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id); String videoUrl = null; // 嘗試分析直連 @@ -145,13 +175,16 @@ public class XPathMac extends XPath { } } // 如果是視頻直連 直接返回免解 - else if (Utils.isVideoFormat(videoUrl)) { + else if (isVideoFormat(videoUrl)) { try { JSONObject result = new JSONObject(); result.put("parse", 0); result.put("playUrl", ""); result.put("url", videoUrl); - result.put("header", ""); + HashMap headers = new HashMap<>(); + if (rule.getPlayUa().length() > 0) headers.put("User-Agent", rule.getPlayUa()); + if (rule.getPlayReferer().length() > 0) headers.put("Referer", rule.getPlayReferer()); + result.put("header", new Gson().toJson(headers)); return result.toString(); } catch (Exception e) { SpiderDebug.log(e); diff --git a/app/src/main/java/com/github/catvod/spider/XPathMacFilter.java b/app/src/main/java/com/github/catvod/spider/XPathMacFilter.java index 59dc372e..435f11c9 100644 --- a/app/src/main/java/com/github/catvod/spider/XPathMacFilter.java +++ b/app/src/main/java/com/github/catvod/spider/XPathMacFilter.java @@ -1,7 +1,5 @@ package com.github.catvod.spider; -import android.text.TextUtils; - import java.net.URLEncoder; import java.util.HashMap; import java.util.regex.Matcher; @@ -15,8 +13,9 @@ public class XPathMacFilter extends XPathMac { if (filter && extend != null && extend.size() > 0) { for (String key : extend.keySet()) { String value = extend.get(key); - if (TextUtils.isEmpty(value)) continue; - cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value)); + if (value.length() > 0) { + cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value)); + } } } cateUrl = cateUrl.replace("{cateId}", tid).replace("{catePg}", pg); diff --git a/app/src/main/java/com/github/catvod/utils/Utils.java b/app/src/main/java/com/github/catvod/utils/Utils.java index dfafb07c..7c05dae6 100644 --- a/app/src/main/java/com/github/catvod/utils/Utils.java +++ b/app/src/main/java/com/github/catvod/utils/Utils.java @@ -33,6 +33,7 @@ public class Utils { } public static boolean isVideoFormat(String url) { + if (url.contains("url=http") || url.contains(".js") || url.contains(".css") || url.contains(".html")) return false; return Sniffer.RULE.matcher(url).find(); } diff --git a/jar/custom_spider.jar b/jar/custom_spider.jar index 38d529e9..5cad26fb 100644 Binary files a/jar/custom_spider.jar and b/jar/custom_spider.jar differ diff --git a/jar/custom_spider.jar.md5 b/jar/custom_spider.jar.md5 index bec53f46..a0ba5901 100644 --- a/jar/custom_spider.jar.md5 +++ b/jar/custom_spider.jar.md5 @@ -1 +1 @@ -008dbb5b68b754af12a2337810f78dc0 +c8bba231546a63b3431cf31e5d856794 diff --git a/json/adult.json b/json/adult.json index 020f3e81..3d763503 100644 --- a/json/adult.json +++ b/json/adult.json @@ -1,5 +1,5 @@ { - "spider": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;008dbb5b68b754af12a2337810f78dc0", + "spider": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;c8bba231546a63b3431cf31e5d856794", "wallpaper": "https://gao.chuqiuyu.tk", "lives": [ { diff --git a/json/alist.json b/json/alist.json index 816d6782..075fe3d0 100644 --- a/json/alist.json +++ b/json/alist.json @@ -1,8 +1,8 @@ { "drives": [ { - "name": "肥羊", - "server": "https://pan.d1.mk" + "name": "小雅", + "server": "http://alist.xiaoya.pro" }, { "name": "觸光", @@ -27,6 +27,10 @@ { "name": "梓澪", "server": "https://zi0.cc" + }, + { + "name": "Testing purpose", + "server": "https://alist.you-mostmost.repl.co" } ] -} \ No newline at end of file +} diff --git a/json/config.json b/json/config.json index 9f3eee48..ce64d6b5 100644 --- a/json/config.json +++ b/json/config.json @@ -1,5 +1,5 @@ { - "spider": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;008dbb5b68b754af12a2337810f78dc0", + "spider": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/jar/custom_spider.jar;md5;c8bba231546a63b3431cf31e5d856794", "wallpaper": "http://www.kf666888.cn/api/tvbox/img", "lives": [ { @@ -40,6 +40,16 @@ "filterable": 1, "changeable": 1 }, + { + "key": "獨播", + "name": "獨播", + "type": 3, + "api": "csp_XPathMacFilter", + "searchable": 1, + "filterable": 1, + "changeable": 1, + "ext": "https://gh-proxy.com/https://raw.githubusercontent.com/FongMi/CatVodSpider/main/json/duboku.json" + }, { "key": "快播", "name": "快播", diff --git a/json/duboku.json b/json/duboku.json new file mode 100644 index 00000000..77c8ed8b --- /dev/null +++ b/json/duboku.json @@ -0,0 +1,772 @@ +{ + "author": "takagen99", + "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", + "homeUrl": "https://www.duboku.tv/", + "dcVipFlag": "true", + "dcPlayUrl": "true", + "cateNode": "//ul[contains(@class,'nav-menu')]/li/a[contains(@href, 'vodtype')]", + "cateName": "/text()", + "cateId": "/@href", + "cateIdR": "/vodtype/(\\w+).html", + "cateManual": { + "陆剧": "13", + "日韩剧": "15", + "短剧": "21", + "英美剧": "16", + "台泰剧": "14", + "港剧": "20", + "综艺": "3", + "动漫": "4" + }, + "homeVodNode": "//ul[contains(@class,'myui-vodlist')]/li/div/a", + "homeVodName": "/@title", + "homeVodId": "/@href", + "homeVodIdR": "/voddetail/(\\w+).html", + "homeVodImg": "/@data-original", + "homeVodImgR": "\\S+(http\\S+)", + "homeVodMark": "//span[contains(@class,'pic-text')]/text()", + "cateUrl": "https://www.duboku.tv/vodshow/{cateId}-{area}-{by}------{catePg}---{year}.html", + "cateVodNode": "//ul[contains(@class,'myui-vodlist')]/li/div/a", + "cateVodName": "/@title", + "cateVodId": "/@href", + "cateVodIdR": "/voddetail/(\\w+).html", + "cateVodImg": "/@data-original", + "cateVodImgR": "\\S+(http\\S+)", + "cateVodMark": "//span[contains(@class,'pic-text')]/text()", + "dtUrl": "https://my.duboku.vip/voddetail/{vid}.html", + "dtNode": "//body", + "dtName": "//div[contains(@class,'myui-content__thumb')]/a/@title", + "dtNameR": "", + "dtImg": "//div[contains(@class,'myui-content__thumb')]/a/img/@data-original", + "dtImgR": "", + "dtCate": "//div[contains(@class,'myui-content__detail')]/p/span[contains(text(), '分类')]/following-sibling::a/text()", + "dtYear": "//div[contains(@class,'myui-content__detail')]/p/span[contains(text(), '年份')]/following-sibling::a/text()", + "dtArea": "//div[contains(@class,'myui-content__detail')]/p/span[contains(text(), '地区')]/following-sibling::a/text()", + "dtMark": "//div[contains(@class,'myui-content__detail')]/p/span[contains(text(), '更新')]/following-sibling::a/text()", + "dtDirector": "//div[contains(@class,'myui-content__detail')]/p/span[contains(text(), '导演')]/following-sibling::a/text()", + "dtActor": "//div[contains(@class,'myui-content__detail')]/p/span[contains(text(), '主演')]/following-sibling::a/text()", + "dtDesc": "//div[contains(@class,'myui-content__detail')]/p/span[contains(text(), '简介')]/following-sibling::a/text()", + "dtFromNode": "//ul[contains(@class,'nav-tabs')]/li/a", + "dtFromName": "/text()", + "dtFromNameR": "", + "dtUrlNode": "//ul[contains(@class,'myui-content__list')]", + "dtUrlSubNode": "/li/a", + "dtUrlId": "/@href", + "dtUrlIdR": "/vodplay/(\\S+).html", + "dtUrlName": "/text()", + "dtUrlNameR": "", + "playUrl": "https://my.duboku.vip/vodplay/{playUrl}.html", + "playUa": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", + "playReferer": "https://www.duboku.tv/", + "searchUrl": "https://my.duboku.vip/index.php/ajax/suggest?mid=1&wd={wd}&limit=10", + "scVodNode": "json:list", + "scVodName": "name", + "scVodId": "id", + "scVodIdR": "", + "scVodImg": "pic", + "scVodMark": "", + "filter": { + "13": [ + { + "key": "year", + "name": "年份", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "2023", + "v": "2023" + }, + { + "n": "2022", + "v": "2022" + }, + { + "n": "2021", + "v": "2021" + }, + { + "n": "2020", + "v": "2020" + }, + { + "n": "2019", + "v": "2019" + }, + { + "n": "2018", + "v": "2018" + }, + { + "n": "2017", + "v": "2017" + } + ] + }, + { + "key": "by", + "name": "排序", + "value": [ + { + "n": "排序", + "v": "" + }, + { + "n": "时间", + "v": "time" + }, + { + "n": "人气", + "v": "hits" + }, + { + "n": "评分", + "v": "score" + } + ] + } + ], + "14": [ + { + "key": "year", + "name": "年份", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "2023", + "v": "2023" + }, + { + "n": "2022", + "v": "2022" + }, + { + "n": "2021", + "v": "2021" + }, + { + "n": "2020", + "v": "2020" + }, + { + "n": "2019", + "v": "2019" + }, + { + "n": "2018", + "v": "2018" + }, + { + "n": "2017", + "v": "2017" + } + ] + }, + { + "key": "by", + "name": "排序", + "value": [ + { + "n": "排序", + "v": "" + }, + { + "n": "时间", + "v": "time" + }, + { + "n": "人气", + "v": "hits" + }, + { + "n": "评分", + "v": "score" + } + ] + } + ], + "16": [ + { + "key": "year", + "name": "年份", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "2023", + "v": "2023" + }, + { + "n": "2022", + "v": "2022" + }, + { + "n": "2021", + "v": "2021" + }, + { + "n": "2020", + "v": "2020" + }, + { + "n": "2019", + "v": "2019" + }, + { + "n": "2018", + "v": "2018" + }, + { + "n": "2017", + "v": "2017" + } + ] + }, + { + "key": "by", + "name": "排序", + "value": [ + { + "n": "排序", + "v": "" + }, + { + "n": "时间", + "v": "time" + }, + { + "n": "人气", + "v": "hits" + }, + { + "n": "评分", + "v": "score" + } + ] + } + ], + "15": [ + { + "key": "year", + "name": "年份", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "2023", + "v": "2023" + }, + { + "n": "2022", + "v": "2022" + }, + { + "n": "2021", + "v": "2021" + }, + { + "n": "2020", + "v": "2020" + }, + { + "n": "2019", + "v": "2019" + }, + { + "n": "2018", + "v": "2018" + }, + { + "n": "2017", + "v": "2017" + } + ] + }, + { + "key": "by", + "name": "排序", + "value": [ + { + "n": "排序", + "v": "" + }, + { + "n": "时间", + "v": "time" + }, + { + "n": "人气", + "v": "hits" + }, + { + "n": "评分", + "v": "score" + } + ] + } + ], + "2": [ + { + "key": "cateId", + "name": "类型", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "陆剧", + "v": "13" + }, + { + "n": "日韩剧", + "v": "15" + }, + { + "n": "英美剧", + "v": "16" + }, + { + "n": "台泰剧", + "v": "14" + }, + { + "n": "港剧", + "v": "20" + } + ] + }, + { + "key": "area", + "name": "地区", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "内地", + "v": "内地" + }, + { + "n": "韩国", + "v": "韩国" + }, + { + "n": "香港", + "v": "香港" + }, + { + "n": "台湾", + "v": "台湾" + }, + { + "n": "美国", + "v": "美国" + }, + { + "n": "英国", + "v": "英国" + }, + { + "n": "巴西", + "v": "巴西" + }, + { + "n": "西班牙", + "v": "西班牙" + }, + { + "n": "泰国", + "v": "泰国" + }, + { + "n": "德国", + "v": "德国" + }, + { + "n": "法国", + "v": "法国" + }, + { + "n": "日本", + "v": "日本" + }, + { + "n": "荷兰", + "v": "荷兰" + } + ] + }, + { + "key": "year", + "name": "年份", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "2023", + "v": "2023" + }, + { + "n": "2022", + "v": "2022" + }, + { + "n": "2021", + "v": "2021" + }, + { + "n": "2020", + "v": "2020" + }, + { + "n": "2019", + "v": "2019" + }, + { + "n": "2018", + "v": "2018" + }, + { + "n": "2017", + "v": "2017" + } + ] + }, + { + "key": "by", + "name": "排序", + "value": [ + { + "n": "排序", + "v": "" + }, + { + "n": "时间", + "v": "time" + }, + { + "n": "人气", + "v": "hits" + }, + { + "n": "评分", + "v": "score" + } + ] + } + ], + "3": [ + { + "key": "area", + "name": "地区", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "内地", + "v": "内地" + }, + { + "n": "香港", + "v": "香港" + }, + { + "n": "台湾", + "v": "台湾" + }, + { + "n": "韩国", + "v": "韩国" + }, + { + "n": "美国", + "v": "美国" + } + ] + }, + { + "key": "year", + "name": "年份", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "2023", + "v": "2023" + }, + { + "n": "2022", + "v": "2022" + }, + { + "n": "2021", + "v": "2021" + }, + { + "n": "2020", + "v": "2020" + }, + { + "n": "2019", + "v": "2019" + } + ] + }, + { + "key": "by", + "name": "排序", + "value": [ + { + "n": "排序", + "v": "" + }, + { + "n": "时间", + "v": "time" + }, + { + "n": "人气", + "v": "hits" + }, + { + "n": "评分", + "v": "score" + } + ] + } + ], + "4": [ + { + "key": "area", + "name": "地区", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "国产", + "v": "国产" + }, + { + "n": "日本", + "v": "日本" + }, + { + "n": "美国", + "v": "美国" + }, + { + "n": "法国", + "v": "法国" + }, + { + "n": "其他", + "v": "其他" + } + ] + }, + { + "key": "year", + "name": "年份", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "2023", + "v": "2023" + }, + { + "n": "2022", + "v": "2022" + }, + { + "n": "2021", + "v": "2021" + }, + { + "n": "2020", + "v": "2020" + }, + { + "n": "2019", + "v": "2019" + }, + { + "n": "2018", + "v": "2018" + }, + { + "n": "2017", + "v": "2017" + } + ] + }, + { + "key": "by", + "name": "排序", + "value": [ + { + "n": "排序", + "v": "" + }, + { + "n": "时间", + "v": "time" + }, + { + "n": "人气", + "v": "hits" + }, + { + "n": "评分", + "v": "score" + } + ] + } + ], + "20": [ + { + "key": "year", + "name": "年份", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "2023", + "v": "2023" + }, + { + "n": "2022", + "v": "2022" + }, + { + "n": "2021", + "v": "2021" + }, + { + "n": "2020", + "v": "2020" + }, + { + "n": "2019", + "v": "2019" + }, + { + "n": "2018", + "v": "2018" + }, + { + "n": "2017", + "v": "2017" + } + ] + }, + { + "key": "by", + "name": "排序", + "value": [ + { + "n": "排序", + "v": "" + }, + { + "n": "时间", + "v": "time" + }, + { + "n": "人气", + "v": "hits" + }, + { + "n": "评分", + "v": "score" + } + ] + } + ], + "21": [ + { + "key": "year", + "name": "年份", + "value": [ + { + "n": "全部", + "v": "" + }, + { + "n": "2023", + "v": "2023" + }, + { + "n": "2022", + "v": "2022" + }, + { + "n": "2021", + "v": "2021" + }, + { + "n": "2020", + "v": "2020" + }, + { + "n": "2019", + "v": "2019" + }, + { + "n": "2018", + "v": "2018" + }, + { + "n": "2017", + "v": "2017" + } + ] + }, + { + "key": "by", + "name": "排序", + "value": [ + { + "n": "排序", + "v": "" + }, + { + "n": "时间", + "v": "time" + }, + { + "n": "人气", + "v": "hits" + }, + { + "n": "评分", + "v": "score" + } + ] + } + ] + } +} \ No newline at end of file