diff --git a/app/src/main/java/com/github/catvod/bean/Result.java b/app/src/main/java/com/github/catvod/bean/Result.java index d27673d7..84a572d5 100644 --- a/app/src/main/java/com/github/catvod/bean/Result.java +++ b/app/src/main/java/com/github/catvod/bean/Result.java @@ -58,7 +58,9 @@ public class Result { public static String string(List classes, List list, LinkedHashMap> filters) { return Result.get().classes(classes).vod(list).filters(filters).string(); } - + public static String string(Integer page,Integer pagecount,Integer limit,Integer total,List list){ + return Result.get().page(page,pagecount,limit,total).vod(list).string(); + } public static String string(List classes, List list, JSONObject filters) { return Result.get().classes(classes).vod(list).filters(filters).string(); } diff --git a/app/src/main/java/com/github/catvod/debug/MainActivity.java b/app/src/main/java/com/github/catvod/debug/MainActivity.java index 98c1fa6b..ac48f5a6 100644 --- a/app/src/main/java/com/github/catvod/debug/MainActivity.java +++ b/app/src/main/java/com/github/catvod/debug/MainActivity.java @@ -8,6 +8,7 @@ import com.github.catvod.R; import com.github.catvod.crawler.Spider; import com.github.catvod.spider.Init; import com.github.catvod.spider.PTT; +import com.github.catvod.spider.Zxzj; import com.orhanobut.logger.AndroidLogAdapter; import com.orhanobut.logger.Logger; @@ -46,7 +47,7 @@ public class MainActivity extends Activity { private void initSpider() { try { Init.init(getApplicationContext()); - spider = new PTT(); + spider = new Zxzj(); spider.init(this, ""); } catch (Throwable e) { e.printStackTrace(); @@ -74,7 +75,7 @@ public class MainActivity extends Activity { HashMap extend = new HashMap<>(); extend.put("c", "19"); extend.put("year", "2024"); - Logger.t("categoryContent").d(spider.categoryContent("3", "2", true, extend)); + Logger.t("categoryContent").d(spider.categoryContent("/list/1.html", "2", true, extend)); } catch (Throwable e) { e.printStackTrace(); } @@ -82,7 +83,7 @@ public class MainActivity extends Activity { public void detailContent() { try { - Logger.t("detailContent").d(spider.detailContent(Arrays.asList("245424"))); + Logger.t("detailContent").d(spider.detailContent(Arrays.asList("/detail/4463.html"))); } catch (Throwable e) { e.printStackTrace(); } @@ -90,7 +91,7 @@ public class MainActivity extends Activity { public void playerContent() { try { - Logger.t("playerContent").d(spider.playerContent("", "382044/1/78", new ArrayList<>())); + Logger.t("playerContent").d(spider.playerContent("", "/video/4463-1-1.html", new ArrayList<>())); } catch (Throwable e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/github/catvod/spider/DaGongRen.java b/app/src/main/java/com/github/catvod/spider/DaGongRen.java new file mode 100644 index 00000000..d9265df5 --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/DaGongRen.java @@ -0,0 +1,194 @@ +package com.github.catvod.spider; + +import com.github.catvod.bean.Class; +import com.github.catvod.bean.Result; +import com.github.catvod.bean.Vod; +import com.github.catvod.crawler.Spider; +import com.github.catvod.net.OkHttp; +import com.github.catvod.utils.AESEncryption; +import com.github.catvod.utils.Util; +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DaGongRen extends Spider { + + private static final String siteUrl = "https://dagongren1.com"; + private static final String cateUrl = siteUrl + "/list/"; + private static final String detailUrl = siteUrl + "/play/"; + private static final String playUrl = siteUrl + "/play/"; + private static final String searchUrl = siteUrl + "/search--------------.html?wd="; + + private HashMap getHeaders() { + HashMap headers = new HashMap<>(); + headers.put("User-Agent", Util.CHROME); + return headers; + } + + @Override + public String homeContent(boolean filter) throws Exception { + List list = new ArrayList<>(); + List classes = new ArrayList<>(); + String[] typeIdList = {"dianying","dianshiju","zongyi","dongman","jilupian","lunlipian"}; + String[] typeNameList = {"电影","连续剧","综艺","动漫","纪录片","福利"}; + for (int i = 0; i < typeNameList.length; i++) { + classes.add(new Class(typeIdList[i], typeNameList[i])); + } + Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders())); + for (Element element : doc.select("a.vodlist_thumb")) { + try { + String pic = element.attr("data-original"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + return Result.string(classes, list); + } + + public String MD5(String string) { + // 创建 MD5 实例 + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + // 计算 MD5 哈希值 + byte[] hashBytes = md.digest(string.getBytes()); + + // 将字节数组转换为十六进制字符串表示 + StringBuilder hexString = new StringBuilder(); + for (byte hashByte : hashBytes) { + String hex = Integer.toHexString(0xff & hashByte); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + + // 输出加密后的 MD5 字符串 + System.out.println("MD5 加密: " + hexString.toString()); + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return ""; + } + + @Override + public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { + List list = new ArrayList<>(); + tid = "/show-" + tid + "--------" + pg + "---.html"; + String target = siteUrl + tid; + Document doc = Jsoup.parse(OkHttp.string(target, getHeaders())); + for (Element element : doc.select("a.vodlist_thumb")) { + try { + String pic = element.attr("data-original"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + + Integer total = (Integer.parseInt(pg) + 1) * 20; + return Result.string(Integer.parseInt(pg), Integer.parseInt(pg) + 1, 20, total, list); + } + + @Override + public String detailContent(List ids) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)), getHeaders())); + String name = doc.select("h2.title.margin_0").text(); + String pic = doc.select("div.play_vlist_thumb").get(0).attr("data-original"); + // 播放源 + Elements tabs = doc.select("li.tab-play"); + Elements list = doc.select("ul.content_playlist"); + String PlayFrom = ""; + String PlayUrl = ""; + for (int i = 0; i < tabs.size(); i++) { + String tabName = tabs.get(i).text(); + if (!"".equals(PlayFrom)) { + PlayFrom = PlayFrom + "$$$" + tabName; + } else { + PlayFrom = PlayFrom + tabName; + } + Elements li = list.get(i).select("a"); + String liUrl = ""; + for (int i1 = 0; i1 < li.size(); i1++) { + if (!"".equals(liUrl)) { + liUrl = liUrl + "#" + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/play/",""); + } else { + liUrl = liUrl + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/play/",""); + } + } + if (!"".equals(PlayUrl)) { + PlayUrl = PlayUrl + "$$$" + liUrl; + } else { + PlayUrl = PlayUrl + liUrl; + } + } + + Vod vod = new Vod(); + vod.setVodId(ids.get(0)); + vod.setVodPic(siteUrl + pic); + vod.setVodName(name); + vod.setVodPlayFrom(PlayFrom); + vod.setVodPlayUrl(PlayUrl); + return Result.string(vod); + } + + @Override + public String searchContent(String key, boolean quick) throws Exception { + List list = new ArrayList<>(); + Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)), getHeaders())); + for (Element element : doc.select("div.searchlist_img")) { + try { + String pic = element.select("a").attr("data-original"); + String url = element.select("a").attr("href"); + String name = element.select("a").attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.replace("/video/","").replace(".html","-1-1.html"); + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + return Result.string(list); + } + + @Override + public String playerContent(String flag, String id, List vipFlags) throws Exception { + String target = playUrl.concat(id); + Document doc = Jsoup.parse(OkHttp.string(target)); + String regex = "\"url\\\":\\\"(.*?)\\\",\\\"url_next\\\":"; + + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(doc.html()); + String url = ""; + if (matcher.find()) { + url = URLDecoder.decode(matcher.group(1), "UTF-8").split("&")[0]; + } + return Result.get().url(url).header(getHeaders()).string(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/HkTv.java b/app/src/main/java/com/github/catvod/spider/HkTv.java new file mode 100644 index 00000000..3dfb8096 --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/HkTv.java @@ -0,0 +1,201 @@ +package com.github.catvod.spider; + +import android.os.Build; +import android.util.Base64; + +import com.github.catvod.bean.Class; +import com.github.catvod.bean.Result; +import com.github.catvod.bean.Vod; +import com.github.catvod.crawler.Spider; +import com.github.catvod.net.OkHttp; +import com.github.catvod.utils.Util; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; + +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class HkTv extends Spider { + + private static final String siteUrl = "http://www.tvyb04.com"; + private static final String cateUrl = siteUrl + "/vod/type/id/"; + private static final String detailUrl = siteUrl + "/vod/detail/id/"; + private static final String playUrl = siteUrl + "/vod/play/id/"; + private static final String searchUrl = siteUrl + "/search--------------.html?wd="; + + private HashMap getHeaders() { + HashMap headers = new HashMap<>(); + headers.put("User-Agent", Util.CHROME); + return headers; + } + + @Override + public String homeContent(boolean filter) throws Exception { + List list = new ArrayList<>(); + List classes = new ArrayList<>(); + String[] typeIdList = {"1", "2", "3", "4", "19"}; + String[] typeNameList = {"电影", "电视剧", "综艺", "动漫", "短片"}; + for (int i = 0; i < typeNameList.length; i++) { + classes.add(new Class(typeIdList[i], typeNameList[i])); + } + Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders())); + for (Element element : doc.select("a.myui-vodlist__thumb")) { + try { + String pic = element.attr("data-original"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[4]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + return Result.string(classes, list); + } + + @Override + public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { + List list = new ArrayList<>(); + String target = cateUrl + tid + ".html"; + if (!"1".equals(pg)) { + target = pg + "/page/" + tid + ".html"; + } + Document doc = Jsoup.parse(OkHttp.string(target, getHeaders())); + for (Element element : doc.select("ul.myui-vodlist li a.myui-vodlist__thumb")) { + try { + String pic = element.attr("data-original"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[4]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + + Integer total = (Integer.parseInt(pg) + 1) * 20; + return Result.string(Integer.parseInt(pg), Integer.parseInt(pg) + 1, 20, total, list); + } + + @Override + public String detailContent(List ids) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)), getHeaders())); + String name = doc.select("h1.title").text(); + String pic = doc.select("a.myui-vodlist__thumb.picture img").attr("data-original"); + // 播放源 + Elements tabs = doc.select("div.myui-panel__head.bottom-line.active.clearfix h3"); + Elements list = doc.select("ul.myui-content__list"); + String PlayFrom = ""; + String PlayUrl = ""; + for (int i = 1; i < tabs.size() - 1; i++) { + String tabName = tabs.get(i).text(); + if (!"".equals(PlayFrom)) { + PlayFrom = PlayFrom + "$$$" + tabName; + } else { + PlayFrom = PlayFrom + tabName; + } + Elements li = list.get(i - 1).select("a"); + String liUrl = ""; + for (int i1 = 0; i1 < li.size(); i1++) { + if (!"".equals(liUrl)) { + liUrl = liUrl + "#" + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/vod/play/id/", ""); + } else { + liUrl = liUrl + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/vod/play/id/", ""); + } + } + if (!"".equals(PlayUrl)) { + PlayUrl = PlayUrl + "$$$" + liUrl; + } else { + PlayUrl = PlayUrl + liUrl; + } + } + + Vod vod = new Vod(); + vod.setVodId(ids.get(0)); + vod.setVodPic(siteUrl + pic); + vod.setVodName(name); + vod.setVodPlayFrom(PlayFrom); + vod.setVodPlayUrl(PlayUrl); + return Result.string(vod); + } + + @Override + // 需要验证码 + public String searchContent(String key, boolean quick) throws Exception { + List list = new ArrayList<>(); + Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)), getHeaders())); + for (Element element : doc.select("div.searchlist_img")) { + try { + String pic = element.select("a").attr("data-original"); + String url = element.select("a").attr("href"); + String name = element.select("a").attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.replace("/video/", "").replace(".html", "-1-1.html"); + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + return Result.string(list); + } + + @Override + public String playerContent(String flag, String id, List vipFlags) throws Exception { + String target = playUrl.concat(id); + Document doc = Jsoup.parse(OkHttp.string(target, getHeaders())); + String regex = "\"url\\\":\\\"(.*?)\\\",\\\"url_next\\\":"; + + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(doc.html()); + String url = doc.html(); + if (matcher.find()) { + String encryptedData = matcher.group(1); + String decodedString = new String(Base64.decode(encryptedData, Base64.DEFAULT)); + url = decodeURL(decodedString); + } + return Result.get().url(url).header(getHeaders()).string(); + } + + public static String decodeURL(String encodedURL) { + StringBuilder sb = new StringBuilder(); + int index = 0; + while (index < encodedURL.length()) { + if (encodedURL.charAt(index) == '%') { + if (index + 2 < encodedURL.length()) { + if (encodedURL.charAt(index + 1) == 'u') { + String unicodeStr = encodedURL.substring(index + 2, index + 6); + char unicodeChar = (char) Integer.parseInt(unicodeStr, 16); + sb.append(unicodeChar); + index += 6; + } else { + String hexStr = encodedURL.substring(index + 1, index + 3); + char hexChar = (char) Integer.parseInt(hexStr, 16); + sb.append(hexChar); + index += 3; + } + } else { + sb.append(encodedURL.charAt(index)); + index++; + } + } else { + sb.append(encodedURL.charAt(index)); + index++; + } + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/NCat.java b/app/src/main/java/com/github/catvod/spider/NCat.java new file mode 100644 index 00000000..5e92f6fa --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/NCat.java @@ -0,0 +1,174 @@ +package com.github.catvod.spider; + +import com.github.catvod.bean.Class; +import com.github.catvod.bean.Result; +import com.github.catvod.bean.Vod; +import com.github.catvod.crawler.Spider; +import com.github.catvod.net.OkHttp; +import com.github.catvod.utils.Util; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class NCat extends Spider { + + private static final String siteUrl = "https://www.ncat3.com:51111"; + private static final String picUrl = "https://vres.a357899.cn"; + private static final String cateUrl = siteUrl + "/show/"; + private static final String detailUrl = siteUrl + "/detail/"; + private static final String searchUrl = siteUrl + "/search?k="; + private static final String playUrl = siteUrl + "/play/"; + + private HashMap getHeaders() { + HashMap headers = new HashMap<>(); + headers.put("User-Agent", Util.CHROME); + return headers; + } + + @Override + public String homeContent(boolean filter) throws Exception { + List list = new ArrayList<>(); + List classes = new ArrayList<>(); + String[] typeIdList = {"1", "2", "3", "4", "6"}; + String[] typeNameList = {"电影", "连续剧", "动漫", "综艺", "短剧"}; + for (int i = 0; i < typeNameList.length; i++) { + classes.add(new Class(typeIdList[i], typeNameList[i])); + } + Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders())); + for (Element element : doc.select("div.module-item")) { + try { + String pic = element.select("img").attr("data-original"); + String url = element.select("a").attr("href"); + String name = element.select("img").attr("title"); + if (!pic.startsWith("http")) { + pic = picUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + + } + } + return Result.string(classes, list); + } + + @Override + public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { + List list = new ArrayList<>(); + String target = cateUrl + tid + "-----3-" + pg + ".html"; + Document doc = Jsoup.parse(OkHttp.string(target, getHeaders())); + for (Element element : doc.select("div.module-item")) { + try { + String pic = element.select("img").attr("data-original"); + String url = element.select("a").attr("href"); + String name = element.select("img").attr("title"); + if (!pic.startsWith("http")) { + pic = picUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + + } + } + Integer total = (Integer.parseInt(pg) + 1) * 20; + return Result.string(Integer.parseInt(pg), Integer.parseInt(pg) + 1, 20, total, list); + } + + @Override + public String detailContent(List ids) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)), getHeaders())); + String name = doc.select("div.detail-title strong").text(); + String pic = doc.select(".detail-pic img").attr("data-original"); + String year = doc.select("a.detail-tags-item").get(0).text(); + String desc = doc.select("div.detail-desc p").text(); + + // 播放源 + Elements tabs = doc.select("a.source-item span"); + Elements list = doc.select("div.episode-list"); + String PlayFrom = ""; + String PlayUrl = ""; + for (int i = 0; i < tabs.size(); i++) { + String tabName = tabs.get(i).text(); + if (!"".equals(PlayFrom)) { + PlayFrom = PlayFrom + "$$$" + tabName; + } else { + PlayFrom = PlayFrom + tabName; + } + Elements li = list.get(i).select("a"); + String liUrl = ""; + for (int i1 = 0; i1 < li.size(); i1++) { + if (!"".equals(liUrl)) { + liUrl = liUrl + "#" + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/play/", ""); + } else { + liUrl = liUrl + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/play/", ""); + } + } + if (!"".equals(PlayUrl)) { + PlayUrl = PlayUrl + "$$$" + liUrl; + } else { + PlayUrl = PlayUrl + liUrl; + } + } + + Vod vod = new Vod(); + vod.setVodId(ids.get(0)); + vod.setVodPic(picUrl + pic); + vod.setVodYear(year); + vod.setVodName(name); + vod.setVodContent(desc); + vod.setVodPlayFrom(PlayFrom); + vod.setVodPlayUrl(PlayUrl); + return Result.string(vod); + } + + @Override + public String searchContent(String key, boolean quick) throws Exception { + List list = new ArrayList<>(); + Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)).concat(".html"), getHeaders())); + for (Element element : doc.select("a.search-result-item")) { + try { + String pic = element.select("img").attr("data-original"); + String url = element.attr("href"); + String name = element.select("img").attr("title"); + if (!pic.startsWith("http")) { + pic = picUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + return Result.string(list); + } + + @Override + public String playerContent(String flag, String id, List vipFlags) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(playUrl.concat(id), getHeaders())); + String regex = "src: \"(.*?)m3u8\","; + + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(doc.html()); + String url = ""; + if (matcher.find()) { + url = matcher.group(1); + url = url.replace("\\/", "/") + "m3u8"; + } + return Result.get().url(url).header(getHeaders()).string(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/Proxy.java b/app/src/main/java/com/github/catvod/spider/Proxy.java index 8c1d2eb3..2cc4c3f7 100644 --- a/app/src/main/java/com/github/catvod/spider/Proxy.java +++ b/app/src/main/java/com/github/catvod/spider/Proxy.java @@ -1,10 +1,18 @@ package com.github.catvod.spider; +import android.util.Base64; + import com.github.catvod.crawler.Spider; import com.github.catvod.crawler.SpiderDebug; import com.github.catvod.net.OkHttp; +import com.github.catvod.utils.ProxyVideo; +import com.google.gson.Gson; import java.io.ByteArrayInputStream; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; import java.util.Map; public class Proxy extends Spider { @@ -21,10 +29,23 @@ public class Proxy extends Spider { return Bili.proxy(params); case "webdav": return WebDAV.vod(params); + case "proxy": + return commonProxy(params); default: return null; } } + private static final List keys = Arrays.asList("url", "header", "do", "Content-Type", "User-Agent", "Host"); + + private static Object[] commonProxy(Map params) throws Exception { + String url = new String(Base64.decode(params.get("url"),Base64.DEFAULT), Charset.defaultCharset()); + Map header = new Gson().fromJson(new String(Base64.decode(params.get("header"),Base64.DEFAULT), Charset.defaultCharset()), Map.class); + if (header == null) header = new HashMap<>(); + for (Map.Entry entry : params.entrySet()) { + if (!keys.contains(entry.getKey())) header.put(entry.getKey(), entry.getValue()); + } + return new Object[]{ProxyVideo.proxy(url, header)}; + } static void adjustPort() { if (Proxy.port > 0) return; diff --git a/app/src/main/java/com/github/catvod/spider/QxiTv.java b/app/src/main/java/com/github/catvod/spider/QxiTv.java new file mode 100644 index 00000000..4b8ba079 --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/QxiTv.java @@ -0,0 +1,210 @@ +package com.github.catvod.spider; + +import com.github.catvod.bean.Class; +import com.github.catvod.bean.Result; +import com.github.catvod.bean.Vod; +import com.github.catvod.crawler.Spider; +import com.github.catvod.net.OkHttp; +import com.github.catvod.utils.Util; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.orhanobut.logger.Logger; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class QxiTv extends Spider { + + private static final String siteUrl = "https://7xi.tv"; + private static final String cateUrl = siteUrl + "/index.php/api/vod"; + private static final String detailUrl = siteUrl + "/voddetail/"; + private static final String searchUrl = siteUrl + "/vodsearch/page/1/wd/"; + + private HashMap getHeaders() { + HashMap headers = new HashMap<>(); + headers.put("User-Agent", Util.CHROME); + return headers; + } + + @Override + public String homeContent(boolean filter) throws Exception { + List list = new ArrayList<>(); + List classes = new ArrayList<>(); + Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders())); + int index = 1; + for (Element element : doc.select("h4.title-h")) { + String typeId = element.select("a").attr("href"); + String typeName = element.select("span").text(); + if (!"".equals(typeName) && index != 1 && index != 6) { + classes.add(new Class(typeId, typeName.replace(" 查看更多",""))); + } + index++; + } + for (Element element : doc.select("a.public-list-exp")) { + try { + String pic = element.select("img").attr("data-src"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + + } + + } + return Result.string(classes, list); + } + + public String MD5(String string) { + // 创建 MD5 实例 + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + // 计算 MD5 哈希值 + byte[] hashBytes = md.digest(string.getBytes()); + + // 将字节数组转换为十六进制字符串表示 + StringBuilder hexString = new StringBuilder(); + for (byte hashByte : hashBytes) { + String hex = Integer.toHexString(0xff & hashByte); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + + // 输出加密后的 MD5 字符串 + System.out.println("MD5 加密: " + hexString.toString()); + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return ""; + } + + @Override + public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { + List list = new ArrayList<>(); + String target = cateUrl + tid; + HashMap params = new HashMap<>(); + params.put("type", tid.split("/")[2].replace(".html", "")); + params.put("page", pg); + String time = String.valueOf(System.currentTimeMillis()); + params.put("time", time); + String string = "DS" + time + "DCC147D11943AF75"; + params.put("key", MD5(string)); + String data = OkHttp.post(target, params); + Gson gson = new Gson(); + JsonObject jsonObject = gson.fromJson(data, JsonObject.class); + JsonArray jsonArray = jsonObject.getAsJsonArray("list"); + for (JsonElement element : jsonArray) { + String id = String.valueOf(element.getAsJsonObject().get("vod_id")); + String name = String.valueOf(element.getAsJsonObject().get("vod_name")).replace("\"", ""); + String pic = String.valueOf(element.getAsJsonObject().get("vod_pic")).replace("\"", ""); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + list.add(new Vod(id, name, pic)); + } + Integer total = (Integer.parseInt(pg) + 1) * 20; + return Result.string(Integer.parseInt(pg), Integer.parseInt(pg) + 1, 20, total, list); + } + + @Override + public String detailContent(List ids) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)).concat(".html"), getHeaders())); + String name = doc.select("div.this-desc-title").text(); + String pic = doc.select("div.this-pic-bj").attr("style").replace("background-image: url('", "").replace("')", ""); + String year = doc.select("div.this-desc-info > span").get(1).text(); + + // 播放源 + Elements tabs = doc.select("a.swiper-slide"); + Elements list = doc.select("div.anthology-list-box.none"); + String PlayFrom = ""; + String PlayUrl = ""; + for (int i = 0; i < tabs.size(); i++) { + String tabName = tabs.get(i).text(); + if (!"".equals(PlayFrom)) { + PlayFrom = PlayFrom + "$$$" + tabName; + } else { + PlayFrom = PlayFrom + tabName; + } + Elements li = list.get(i).select("a"); + String liUrl = ""; + for (int i1 = 0; i1 < li.size(); i1++) { + if (!"".equals(liUrl)){ + liUrl = liUrl + "#" + li.get(i1).text() + "$" + li.get(i1).attr("href"); + }else { + liUrl = liUrl + li.get(i1).text() + "$" + li.get(i1).attr("href"); + } + } + if (!"".equals(PlayUrl)) { + PlayUrl = PlayUrl + "$$$" + liUrl; + }else { + PlayUrl = PlayUrl + liUrl; + } + } + + Vod vod = new Vod(); + vod.setVodId(ids.get(0)); + vod.setVodPic(pic); + vod.setVodYear(year); + vod.setVodName(name); + vod.setVodPlayFrom(PlayFrom); + vod.setVodPlayUrl(PlayUrl); + return Result.string(vod); + } + + @Override + public String searchContent(String key, boolean quick) throws Exception { + List list = new ArrayList<>(); + Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)).concat(".html"), getHeaders())); + for (Element element : doc.select("a.public-list-exp")) { + try { + String pic = element.select("img").attr("data-src"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + return Result.string(list); + } + + @Override + public String playerContent(String flag, String id, List vipFlags) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(siteUrl.concat(id),getHeaders())); + String regex = "\"url\":\"(.*?)m3u8\","; + + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(doc.html()); + String url = ""; + if (matcher.find()) { + url = matcher.group(1); + url = url.replace("\\/","/") + "m3u8"; + } + return Result.get().url(url).header(getHeaders()).string(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/TvDy.java b/app/src/main/java/com/github/catvod/spider/TvDy.java new file mode 100644 index 00000000..2cc10fc0 --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/TvDy.java @@ -0,0 +1,172 @@ +package com.github.catvod.spider; + +import com.github.catvod.bean.Class; +import com.github.catvod.bean.Result; +import com.github.catvod.bean.Vod; +import com.github.catvod.crawler.Spider; +import com.github.catvod.net.OkHttp; +import com.github.catvod.utils.Util; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import android.util.Base64; + +public class TvDy extends Spider { + + private static final String siteUrl = "https://www.tvdy.xyz"; + private static final String cateUrl = siteUrl + "/search.php?tid="; + private static final String detailUrl = siteUrl + "/movie/"; + private static final String searchUrl = siteUrl + "/search.php?searchword="; + private static final String playUrl = siteUrl + "/play/"; + + private HashMap getHeaders() { + HashMap headers = new HashMap<>(); + headers.put("User-Agent", Util.CHROME); + return headers; + } + + @Override + public String homeContent(boolean filter) throws Exception { + List list = new ArrayList<>(); + List classes = new ArrayList<>(); + String[] typeIdList = {"1", "2", "3", "4", "5", "34"}; + String[] typeNameList = {"电影", "电视剧", "综艺", "动漫", "福利", "纪录片"}; + for (int i = 0; i < typeNameList.length; i++) { + classes.add(new Class(typeIdList[i], typeNameList[i])); + } + Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders())); + for (Element element : doc.select("div.stui-vodlist__box a")) { + try { + String pic = element.attr("data-original"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + + } + } + return Result.string(classes, list); + } + + @Override + public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { + List list = new ArrayList<>(); + String target = cateUrl + tid + "&searchtype=5&order=commend&page=" + pg; + Document doc = Jsoup.parse(OkHttp.string(target, getHeaders())); + for (Element element : doc.select("div.stui-vodlist__box a")) { + try { + String pic = element.attr("data-original"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + + } + } + Integer total = (Integer.parseInt(pg) + 1) * 20; + return Result.string(Integer.parseInt(pg), Integer.parseInt(pg) + 1, 20, total, list); + } + + @Override + public String detailContent(List ids) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)), getHeaders())); + String name = doc.select("h1.title").text(); + String pic = doc.select("a.pic img").attr("data-original"); + String year = doc.select("p.data").get(4).text().replace("年份:",""); + String desc = doc.select("span.detail-content").text(); + + // 播放源 + Elements tabs = doc.select("div.stui-vodlist__head h4"); + Elements list = doc.select("div.stui-vodlist__head ul"); + String PlayFrom = ""; + String PlayUrl = ""; + for (int i = 0; i < tabs.size(); i++) { + String tabName = tabs.get(i).text(); + if (!"".equals(PlayFrom)) { + PlayFrom = PlayFrom + "$$$" + tabName; + } else { + PlayFrom = PlayFrom + tabName; + } + Elements li = list.get(i).select("a"); + String liUrl = ""; + for (int i1 = 0; i1 < li.size(); i1++) { + if (!"".equals(liUrl)) { + liUrl = liUrl + "#" + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/play/", ""); + } else { + liUrl = liUrl + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/play/", ""); + } + } + if (!"".equals(PlayUrl)) { + PlayUrl = PlayUrl + "$$$" + liUrl; + } else { + PlayUrl = PlayUrl + liUrl; + } + } + + Vod vod = new Vod(); + vod.setVodId(ids.get(0)); + vod.setVodPic(siteUrl + pic); + vod.setVodYear(year); + vod.setVodName(name); + vod.setVodContent(desc); + vod.setVodPlayFrom(PlayFrom); + vod.setVodPlayUrl(PlayUrl); + return Result.string(vod); + } + + @Override + public String searchContent(String key, boolean quick) throws Exception { + List list = new ArrayList<>(); + Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)), getHeaders())); + for (Element element : doc.select("div.stui-vodlist__box a")) { + try { + String pic = element.attr("data-original"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + + } + } + return Result.string(list); + } + + @Override + public String playerContent(String flag, String id, List vipFlags) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(playUrl.concat(id), getHeaders())); + String regex = "var now=base64decode(.*?);var"; + + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(doc.html()); + String url = doc.html(); + if (matcher.find()) { + url = decodeBase64(matcher.group(1).replace("(\\\"","").replace("\\\")","")); + } + return Result.get().url(url).header(getHeaders()).string(); + } + + public static String decodeBase64(String encodedString) { + return new String(Base64.decode(encodedString, Base64.DEFAULT)); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/W55Movie.java b/app/src/main/java/com/github/catvod/spider/W55Movie.java new file mode 100644 index 00000000..c199d918 --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/W55Movie.java @@ -0,0 +1,229 @@ +package com.github.catvod.spider; + +import com.github.catvod.bean.Class; +import com.github.catvod.bean.Result; +import com.github.catvod.bean.Vod; +import com.github.catvod.crawler.Spider; +import com.github.catvod.net.OkHttp; +import com.github.catvod.utils.AESEncryption; +import com.github.catvod.utils.Util; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.net.URLEncoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class W55Movie extends Spider { + + private static final String siteUrl = "https://55flix.com"; + private static final String cateUrl = siteUrl + "/index.php/api/vod"; + private static final String detailUrl = siteUrl + "/voddetail/"; + private static final String playUrl = siteUrl + "/vodplay/"; + private static final String searchUrl = siteUrl + "/vodsearch/page/1/wd/"; + + private HashMap getHeaders() { + HashMap headers = new HashMap<>(); + headers.put("User-Agent", Util.CHROME); + return headers; + } + + @Override + public String homeContent(boolean filter) throws Exception { + List list = new ArrayList<>(); + List classes = new ArrayList<>(); + String[] typeIdList = {"/label/netflix/page/","/vodshow/1","/vodshow/2","/vodshow/124","/vodshow/4","/vodshow/3"}; + String[] typeNameList = {"Netflix","电影","连续剧","福利","动漫","综艺"}; + for (int i = 0; i < typeNameList.length; i++) { + classes.add(new Class(typeIdList[i], typeNameList[i])); + } + Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders())); + for (Element element : doc.select("a.module-poster-item")) { + try { + String pic = element.select("img").attr("data-original"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + return Result.string(classes, list); + } + + public String MD5(String string) { + // 创建 MD5 实例 + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + // 计算 MD5 哈希值 + byte[] hashBytes = md.digest(string.getBytes()); + + // 将字节数组转换为十六进制字符串表示 + StringBuilder hexString = new StringBuilder(); + for (byte hashByte : hashBytes) { + String hex = Integer.toHexString(0xff & hashByte); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + + // 输出加密后的 MD5 字符串 + System.out.println("MD5 加密: " + hexString.toString()); + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return ""; + } + + @Override + public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { + List list = new ArrayList<>(); + if (tid.startsWith("/label/")){ + tid = tid + pg + ".html"; + }else { + tid = tid + "--------" + pg + "---.html"; + } + String target = siteUrl + tid; + Document doc = Jsoup.parse(OkHttp.string(target, getHeaders())); + for (Element element : doc.select("a.module-poster-item")) { + try { + String pic = element.select("img").attr("data-original"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + + Integer total = (Integer.parseInt(pg) + 1) * 20; + return Result.string(Integer.parseInt(pg), Integer.parseInt(pg) + 1, 20, total, list); + } + + @Override + public String detailContent(List ids) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)), getHeaders())); + String name = doc.select("h1").text(); + String pic = doc.select("img.ls-is-cached").attr("data-original"); + Elements desc = doc.select("div.module-info-tag-link"); + String year = desc.get(0).select("a").text(); + String area = desc.get(1).select("a").text(); + String tags = desc.get(2).select("a").text(); + String content = doc.select("meta[name=description]").attr("content"); + + // 播放源 + Elements tabs = doc.select("div.module-tab-item"); + Elements list = doc.select("div.module-play-list-content"); + String PlayFrom = ""; + String PlayUrl = ""; + for (int i = 0; i < tabs.size(); i++) { + String tabName = tabs.get(i).text(); + if (!"".equals(PlayFrom)) { + PlayFrom = PlayFrom + "$$$" + tabName; + } else { + PlayFrom = PlayFrom + tabName; + } + Elements li = list.get(i).select("a"); + String liUrl = ""; + for (int i1 = 0; i1 < li.size(); i1++) { + if (!"".equals(liUrl)) { + liUrl = liUrl + "#" + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/vodplay/",""); + } else { + liUrl = liUrl + li.get(i1).text() + "$" + li.get(i1).attr("href").replace("/vodplay/",""); + } + } + if (!"".equals(PlayUrl)) { + PlayUrl = PlayUrl + "$$$" + liUrl; + } else { + PlayUrl = PlayUrl + liUrl; + } + } + + Vod vod = new Vod(); + vod.setVodId(ids.get(0)); + vod.setVodPic(pic); + vod.setVodYear(year); + vod.setVodArea(area); + vod.setVodTag(tags); + vod.setVodContent(content); + vod.setVodName(name); + vod.setVodPlayFrom(PlayFrom); + vod.setVodPlayUrl(PlayUrl); + return Result.string(vod); + } + + @Override + public String searchContent(String key, boolean quick) throws Exception { + List list = new ArrayList<>(); + Document doc = Jsoup.parse(OkHttp.string(searchUrl.concat(URLEncoder.encode(key)).concat(".html"), getHeaders())); + for (Element element : doc.select("a.public-list-exp")) { + try { + String pic = element.select("img").attr("data-src"); + String url = element.attr("href"); + String name = element.attr("title"); + if (!pic.startsWith("http")) { + pic = siteUrl + pic; + } + String id = url.split("/")[2]; + list.add(new Vod(id, name, pic)); + } catch (Exception e) { + } + } + return Result.string(list); + } + + @Override + public String playerContent(String flag, String id, List vipFlags) throws Exception { + String target = playUrl.concat(id); + Document doc = Jsoup.parse(OkHttp.string(target)); + String regex = "\"url\\\":\\\"(.*?)\\\",\\\"url_next\\\":\\\"(.*?)\\\""; + + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(doc.html()); + String url = ""; + String url_next = ""; + if (matcher.find()) { + url = matcher.group(1); + url_next = matcher.group(2); + } + String encrytStr = "{\"url\":\"" + url + "\",\"next_url\":\"" + url_next + "\"}"; + // 加密 + String encrypt = AESEncryption.encrypt(encrytStr); + String encodeURI = AESEncryption.encodeURIComponent(encrypt); + // 请求获取url + String data = OkHttp.string("https://player.ddzyku.com:3653/getUrls?data=" + encodeURI); + // 解密 + String decrypted = AESEncryption.decrypt(data); + Gson gson = new Gson(); + JsonObject jsonObject = gson.fromJson(decrypted, JsonObject.class); + JsonObject dataObject = jsonObject.getAsJsonObject("data"); + String url1 = ""; + // Ensure the field exists before accessing it + if (dataObject != null && dataObject.has("url")) { + url1 = dataObject.get("url").getAsString(); + } else { + System.out.println("Invalid JSON format or missing 'url' field."); + } + return Result.get().url(url1).header(getHeaders()).string(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/spider/Zxzj.java b/app/src/main/java/com/github/catvod/spider/Zxzj.java new file mode 100644 index 00000000..1476a77c --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/Zxzj.java @@ -0,0 +1,199 @@ +package com.github.catvod.spider;/* +/** + +@auther lushunming +*/ + + +import com.github.catvod.bean.Class; +import com.github.catvod.bean.Filter; +import com.github.catvod.bean.Result; +import com.github.catvod.bean.Vod; +import com.github.catvod.crawler.Spider; +import com.github.catvod.net.OkHttp; +import com.github.catvod.utils.Notify; +import com.github.catvod.utils.ProxyVideo; + +import org.apache.commons.lang3.StringUtils; +import org.json.JSONObject; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Zxzj extends Spider { + + private final String siteUrl = "https://www.zxzja.com"; + + private Map getHeader() { + Map header = new HashMap<>(); + header.put("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/100.0.4896.77 Mobile/15E148 Safari/604.1"); + header.put("Connection", "keep-alive"); + header.put("Referer", "https://www.zxzj.com/"); + header.put("sec-fetch-dest", "iframe"); + header.put("sec-fetch-mode", "navigate"); + header.put("sec-fetch-site", "cross-site"); + return header; + } + + private Map getVideoHeader() { + Map header = new HashMap<>(); + + header.put("Accept", "*/*"); + header.put("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,de;q=0.6"); + header.put("Cache-Control", "no-cache"); + header.put("Connection", "keep-alive"); + header.put("Pragma", "no-cache"); + + header.put("Sec-Fetch-Dest", "video"); + header.put("Sec-Fetch-Mode", "no-cors"); + header.put("Sec-Fetch-Site", "cross-site"); + header.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"); + /* header.put("sec-ch-ua", "\"Chromium\";v=\"124\", \"Google Chrome\";v=\"124\", \"Not-A.Brand\";v=\"99\""); + header.put("sec-ch-ua-mobile", "?0"); + header.put("sec-ch-ua-platform", "\"Windows\"");*/ + return header; + } + + @Override + public String homeContent(boolean filter) throws Exception { + + List list = new ArrayList<>(); + List classes = new ArrayList<>(); + LinkedHashMap> filters = new LinkedHashMap<>(); + Document doc = Jsoup.parse(OkHttp.string(siteUrl)); + + for (Element div : doc.select(".stui-header__menu > li ")) { + classes.add(new Class(div.select(" a").attr("href"), div.select(" a").text())); + } + + getVods(list, doc); + + return Result.string(classes, list); + } + + private void getVods(List list, Document doc) { + for (Element div : doc.select(".stui-vodlist >li")) { + String id = div.select(".stui-vodlist__box > a.stui-vodlist__thumb").attr("href"); + String name = div.select(".stui-vodlist__detail >h4.title > a").text(); + String pic = div.select(".stui-vodlist__box > a.stui-vodlist__thumb").attr("data-original"); + if (pic.isEmpty()) pic = div.select("img").attr("src"); + String remark = div.select(".stui-vodlist__box > a.stui-vodlist__thumb > span").text(); + + list.add(new Vod(id, name, pic, remark)); + } + } + + @Override + public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { + List list = new ArrayList<>(); + String[] arr = tid.split("\\."); + String target = siteUrl + arr[0] + "-" + pg + ".html"; + //String filters = extend.get("filters"); + String html = OkHttp.string(target); + Document doc = Jsoup.parse(html); + getVods(list, doc); + String total = "" + Integer.MAX_VALUE; + + + return Result.get().vod(list).page(Integer.parseInt(pg), Integer.parseInt(total) / 12 + ((Integer.parseInt(total) % 12) > 0 ? 1 : 0), 12, Integer.parseInt(total)).string(); + } + + @Override + public String detailContent(List ids) throws Exception { + + Document doc = Jsoup.parse(OkHttp.string(this.siteUrl + ids.get(0), getHeader())); + + Elements sources = Objects.requireNonNull(doc.select("ul.stui-content__playlist").first()).children(); + StringBuilder vod_play_url = new StringBuilder(); + StringBuilder vod_play_from = new StringBuilder("在线之家").append("$$$"); + + for (int i = 0; i < sources.size(); i++) { + String href = sources.get(i).select("a").attr("href"); + String text = sources.get(i).text(); + vod_play_url.append(text).append("$").append(href); + boolean notLastEpisode = i < sources.size() - 1; + vod_play_url.append(notLastEpisode ? "#" : "$$$"); + } + + String title = doc.select(" .stui-content__detail > h1").text(); + String classifyName = doc.select(".stui-content__detail > p:nth-child(1)").text(); + String year = doc.select(".stui-content__detail > p:nth-child(1)").text(); + String area = doc.select(".stui-content__detail > p:nth-child(1)").text(); + String remark = doc.select(".stui-content__detail > p:nth-child(1)").text(); + String vodPic = doc.select(" div.stui-content__thumb > a > img").attr("data-original"); + + String director = doc.select(".stui-content__detail > p:nth-child(3)").text(); + + String actor = doc.select(".stui-content__detail > p:nth-child(2)").text(); + + String brief = doc.select(".detail-sketch").text(); + Vod vod = new Vod(); + vod.setVodId(ids.get(0)); + vod.setVodYear(year); + vod.setVodName(title); + vod.setVodArea(area); + vod.setVodActor(actor); + vod.setVodPic(vodPic); + vod.setVodRemarks(remark); + vod.setVodContent(brief); + vod.setVodDirector(director); + vod.setTypeName(classifyName); + vod.setVodPlayFrom(vod_play_from.toString()); + vod.setVodPlayUrl(vod_play_url.toString()); + return Result.string(vod); + } + + @Override + public String searchContent(String key, boolean quick) throws Exception { + String searchUrl = siteUrl + "/vodsearch/-------------.html?wd=" + key + "&submit="; + String html = OkHttp.string(searchUrl); + if (html.contains("Just a moment")) { + + Notify.show("在线之家资源需要人机验证"); + } + Document document = Jsoup.parse(html); + List list = new ArrayList<>(); + getVods(list, document); + + return Result.string(list); + } + + + @Override + public String playerContent(String flag, String id, List vipFlags) throws Exception { + String content = OkHttp.string(this.siteUrl + id, getHeader()); + Matcher matcher = Pattern.compile("player_aaaa=(.*?)").matcher(content); + String json = matcher.find() ? matcher.group(1) : ""; + org.json.JSONObject player = new JSONObject(json); + String realUrl = player.getString("url"); + String videoContent = OkHttp.string(realUrl, getHeader()); + Matcher matcher2 = Pattern.compile("result_v2 =(.*?);").matcher(videoContent); + String json2 = matcher2.find() ? matcher2.group(1) : ""; + org.json.JSONObject jsonObject = new JSONObject(json2); + String encodedStr = jsonObject.getString("data"); + realUrl = new String(new BigInteger(StringUtils.reverse(encodedStr), 16).toByteArray()); + Map header = getVideoHeader(); + String temp = decodeStr(realUrl); + return Result.get().url(ProxyVideo.buildCommonProxyUrl(temp, header)).header(getVideoHeader()).string(); + } + + String decodeStr(String _0x267828) { + int _0x5cd2b5 = (_0x267828.length() - 7) / 2; + String _0x2191ed = _0x267828.substring(0, _0x5cd2b5); + String _0x35a256 = _0x267828.substring(_0x5cd2b5 + 7); + return _0x2191ed + _0x35a256; + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/utils/AESEncryption.java b/app/src/main/java/com/github/catvod/utils/AESEncryption.java new file mode 100644 index 00000000..aa8e781b --- /dev/null +++ b/app/src/main/java/com/github/catvod/utils/AESEncryption.java @@ -0,0 +1,78 @@ +package com.github.catvod.utils; + +import android.util.Base64; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class AESEncryption { + + private static final String keyString = "a67e9a3a85049339"; + private static final String ivString = "86ad9b37cc9f5b9501b3cecc7dc6377c"; + + public static String encrypt(String word) { + try { + byte[] keyBytes = keyString.getBytes("UTF-8"); + SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); + + byte[] ivBytes = hexStringToByteArray(ivString); + IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); + + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); + cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); + + byte[] encrypted = cipher.doFinal(word.getBytes("UTF-8")); + + return Base64.encodeToString(encrypted, Base64.DEFAULT); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static String decrypt(String word) { + try { + byte[] keyBytes = keyString.getBytes("UTF-8"); + SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); + + byte[] ivBytes = hexStringToByteArray(ivString); + IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); + + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); + cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); + + byte[] decoded = Base64.decode(word, Base64.DEFAULT); + byte[] decrypted = cipher.doFinal(decoded); + + return new String(decrypted, "UTF-8"); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private static byte[] hexStringToByteArray(String hexString) { + int len = hexString.length(); + byte[] data = new byte[len / 2]; + + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + + Character.digit(hexString.charAt(i + 1), 16)); + } + + return data; + } + + public static String encodeURIComponent(String value) { + try { + return URLEncoder.encode(value, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Error encoding URL component", e); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/utils/ProxyVideo.java b/app/src/main/java/com/github/catvod/utils/ProxyVideo.java index d1ddfcf3..11e4b3ad 100644 --- a/app/src/main/java/com/github/catvod/utils/ProxyVideo.java +++ b/app/src/main/java/com/github/catvod/utils/ProxyVideo.java @@ -2,13 +2,16 @@ package com.github.catvod.utils; import android.os.SystemClock; import android.text.TextUtils; +import android.util.Base64; import com.github.catvod.net.OkHttp; import com.github.catvod.spider.Proxy; +import com.google.gson.Gson; import org.json.JSONObject; import java.net.URLEncoder; +import java.nio.charset.Charset; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -19,6 +22,10 @@ public class ProxyVideo { private static final String GO_SERVER = "http://127.0.0.1:7777/"; + public static String buildCommonProxyUrl(String url, Map headers) { + return Proxy.getUrl() + "?do=proxy&url=" + Base64.encode(url.getBytes(Charset.defaultCharset()), Base64.DEFAULT) + "&header=" + Base64.encode((new Gson().toJson(headers)).getBytes(Charset.defaultCharset()), Base64.DEFAULT); + } + public static void go() { boolean close = OkHttp.string(GO_SERVER).isEmpty(); if (close) OkHttp.string("http://127.0.0.1:" + Proxy.getPort() + "/go"); @@ -46,7 +53,8 @@ public class ProxyVideo { String contentDisposition = response.headers().get("Content-Disposition"); if (contentDisposition != null) contentType = getMimeType(contentDisposition); Map respHeaders = new HashMap<>(); - for (String key : response.headers().names()) respHeaders.put(key, response.headers().get(key)); + for (String key : response.headers().names()) + respHeaders.put(key, response.headers().get(key)); return new Object[]{206, contentType, response.body().byteStream(), respHeaders}; } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4f9aeb89..839ab030 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -7,8 +7,10 @@ + android:padding="150dp" + android:visibility="visible">