金牌影视java

This commit is contained in:
lushunming 2024-08-27 10:34:51 +08:00
parent 83e200663c
commit daf80eed19
9 changed files with 374 additions and 4 deletions

View File

@ -3,6 +3,9 @@ package com.github.catvod.bean;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class Vod { public class Vod {
@SerializedName("type_name") @SerializedName("type_name")
@ -171,4 +174,46 @@ public class Vod {
this.ratio = ratio; this.ratio = ratio;
} }
} }
public static class VodPlayBuilder{
private List<String> vodPlayFrom = new ArrayList<String>();
private List<String> vodPlayUrl = new ArrayList<String>();
/**
* 格式 from name1$$$name2$$$name3
* url name$url#name2$url2$$$(分类2)$$分类3
* @param playFrom
* @param playUrl
*/
public VodPlayBuilder append(String playFrom, List<PlayUrl> playUrl){
vodPlayFrom.add(playFrom);
vodPlayUrl.add(toPlayUrlStr(playUrl));
return this;
}
public BuildResult build(){
BuildResult buildResult = new BuildResult();
buildResult.vodPlayFrom = String.join("$$$", vodPlayFrom);
buildResult.vodPlayUrl = String.join("$$$", vodPlayUrl);
return buildResult;
}
private String toPlayUrlStr(List<PlayUrl> playUrl) {
List<String> list = new ArrayList<>();
for (PlayUrl url : playUrl) {
list.add(url.name.replace("m3u8", "") + '$' + url.url);
}
return String.join("#", list);
}
public static class BuildResult{
public String vodPlayFrom;
public String vodPlayUrl;
}
public static class PlayUrl {
public String flag; // 线路标志
public String name;
public String url;
}
}
} }

View File

@ -0,0 +1,184 @@
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.crawler.SpiderDebug
import com.github.catvod.net.OkHttp
import com.github.catvod.utils.Json
import com.github.catvod.utils.Util
import com.google.gson.JsonArray
import org.apache.commons.lang3.time.DateFormatUtils
import org.apache.commons.lang3.time.DateUtils
import org.jsoup.Jsoup
import java.util.*
class Glod : Spider() {
private val host = Util.base64Decode("aHR0cHM6Ly93d3cuY2Zrajg2LmNvbS8=")
private val epUrl = "/api/mw-movie/anonymous/v1/video/episode/url?id=%s&nid=%s"
private val deviceId = UUID.randomUUID().toString();
private val classList = listOf(Class("1", "电影"), Class("2", "电视剧"), Class("4", "动漫"), Class("3", "综艺"))
override fun homeContent(filter: Boolean): String {
val string = OkHttp.string(host, Util.webHeaders("https://www.bing.com"))
val vodList = parseFromJson(string, "home")
// val vodList = parseVodList(string)
return Result.string(classList, vodList)
}
override fun detailContent(ids: MutableList<String>): String {
val url = host + ids[0]
val string = OkHttp.string(url, Util.webHeaders(host))
val parse = Jsoup.parse(string)
val name = parse.select("h1.title").text()
val img = parse.select("div[class^=detail__CardImg] img").attr("src")
val tag = parse.select("div.tags > a.tag").eachText().joinToString(" ")
val vod = Vod(ids[0], name, img, tag)
val director = parse.select("div.director")
val d = director[0].select("a").text()
val actor = director[1].select("a").eachText().joinToString(" ")
vod.setVodActor(actor)
vod.setVodDirector(d)
val desc = parse.select("div.intro div.wrapper_more_text").text()
vod.vodContent = desc
val linkList = parse.select("div.listitem > a")
val playUrlList = mutableListOf<Vod.VodPlayBuilder.PlayUrl>()
for (element in linkList) {
val u = element.attr("href")
val n = element.text()
playUrlList.add(Vod.VodPlayBuilder.PlayUrl().also {
it.name = n
it.url = u
})
}
val buildResult = Vod.VodPlayBuilder().append("glod", playUrlList).build()
val time = parse.select("div.item:contains(上映时间)").select(".item-top").text()
vod.setVodYear(DateFormatUtils.format(DateUtils.parseDate(time, "yyyy-MM-dd"), "yyyy"))
vod.setVodPlayFrom(buildResult.vodPlayFrom)
vod.vodPlayUrl = buildResult.vodPlayUrl
return Result.string(vod)
}
/**
* 请求头
* t 时间戳
* sign 签名
* deviceId
* authorization 空的
* 还有cookie
*/
override fun playerContent(flag: String, id: String, vipFlags: MutableList<String>): String {
val list = id.split("/")
val i = list[3]
val nid = list[5]
val webHeaders = Util.webHeaders(host)
val time = Date().time.toString()
val sign = Util.sha1Hex(
Util.MD5("id=${i}&nid=${nid}&key=cb808529bae6b6be45ecfab29a4889bc&t=${time}")
)
webHeaders["t"] = time
webHeaders["deviceId"] = deviceId
webHeaders["Sign"] = sign
val string = OkHttp.string(host + String.format(epUrl, i, nid), webHeaders)
val parse = Json.parse(string).asJsonObject
if (parse.get("code").asInt != 200) {
SpiderDebug.log("glod 获取播放链接失败:$string")
return Result.error("获取播放链接失败")
}
val url = parse.get("data").asJsonObject.get("playUrl").asString
return Result.get().url(url).string()
}
override fun categoryContent(tid: String, pg: String, filter: Boolean, extend: HashMap<String, String>): String {
val url = "$host/type/$tid"
val string = OkHttp.string(url, Util.webHeaders(host))
val vodList = parseFromJson(string, "cate")
return Result.string(classList, vodList)
}
override fun searchContent(key: String, quick: Boolean): String {
val string = OkHttp.string("${host}vod/search/$key", Util.webHeaders(host))
val vodList = parseFromJson(string, "search")
return Result.string(vodList)
}
private fun parseFromJson(string: String, type: String): List<Vod> {
val vodList = mutableListOf<Vod>()
val parse = Jsoup.parse(string)
val select = parse.select("script")
val data = select.find {
it.html().contains("操作成功")
}
if (data == null) {
SpiderDebug.log("glod 找不到json")
return vodList
}
val json = data.html().replace("self.__next_f.push(", "").replace(")", "")
val gson = Json.parse(json).asJsonArray.get(1).asString.replace("6:", "")
val resp = Json.parse(gson).asJsonArray.get(3).asJsonObject
if (type == "home") {
val element = resp.get("children").asJsonArray.get(3).asJsonObject.get("data").asJsonObject.get("data")
var vList = element.asJsonObject.get("homeNewMoviePageData").asJsonObject.get("list").asJsonArray
getVodList(vList, vodList)
vList = element.asJsonObject.get("homeBroadcastPageData").asJsonObject.get("list").asJsonArray
getVodList(vList, vodList)
vList = element.asJsonObject.get("homeManagerPageData").asJsonObject.get("list").asJsonArray
getVodList(vList, vodList)
vList = element.asJsonObject.get("newestTvPageData").asJsonObject.get("list").asJsonArray
getVodList(vList, vodList)
vList = element.asJsonObject.get("newestCartoonPageData").asJsonObject.get("list").asJsonArray
getVodList(vList, vodList)
} else if (type == "cate") {
for (jsonElement in resp.get("children").asJsonArray.get(3).asJsonObject.get("data").asJsonArray) {
val objList = jsonElement.asJsonObject.get("vodList").asJsonObject.get("list").asJsonArray
getVodList(objList, vodList)
}
} else if (type == "search") {
val asJsonArray =
resp.get("data").asJsonObject.get("data").asJsonObject.get("result").asJsonObject.get("list").asJsonArray
getVodList(asJsonArray, vodList)
}
return vodList
}
private fun getVodList(
objList: JsonArray, vodList: MutableList<Vod>
) {
for (oj in objList) {
val obj = oj.asJsonObject
val v = Vod()
v.setVodId("/detail/" + obj.get("vodId").asString)
v.setVodName(obj.get("vodName").asString)
// v.setVodActor(obj.get("vodActor").asString)
v.setVodRemarks(obj.get("vodScore").asString)
v.setVodPic(obj.get("vodPic").asString)
vodList.add(v)
}
}
private fun parseVodList(string: String): MutableList<Vod> {
val parse = Jsoup.parse(string)
val list = parse.select("div.content-card")
val vodList = mutableListOf<Vod>()
for (element in list) {
val id = element.select("a").attr("href")
val title = element.select("div.info-title-box > div.title").text()
val score = element.select("div.bottom div[class^=score]").text()
val img = element.select("img").attr("srcset")
vodList.add(Vod(id, title, host + img, score))
}
return vodList
}
}

View File

@ -14,12 +14,15 @@ import android.webkit.WebViewClient;
import com.github.catvod.spider.Init; import com.github.catvod.spider.Init;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.mozilla.universalchardet.UniversalDetector; import org.mozilla.universalchardet.UniversalDetector;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.URI; import java.net.URI;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -338,6 +341,31 @@ public class Util {
} }
public static String sha1Hex(String input) throws NoSuchAlgorithmException {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] messageDigest = md.digest(input.getBytes(Charset.defaultCharset()));
return bytesToHex(messageDigest);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
public static class LCSResult { public static class LCSResult {
public int length; public int length;
public String sequence; public String sequence;

View File

@ -0,0 +1,95 @@
import android.app.Application;
import com.github.catvod.spider.ChangZhang;
import com.github.catvod.spider.Glod;
import com.github.catvod.spider.Init;
import com.github.catvod.utils.Json;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@RunWith(RobolectricTestRunner.class)
public class GoldTest {
// @Mock
private Application mockContext;
private Glod spider;
@org.junit.Before
public void setUp() throws Exception {
mockContext = RuntimeEnvironment.application;
Init.init(mockContext);
spider = new Glod();
spider.init(mockContext, "https://www.czzy.site/");
}
@org.junit.Test
public void homeContent() throws Exception {
String content = spider.homeContent(true);
JsonObject map = Json.safeObject(content);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println("homeContent--" + gson.toJson(map));
//Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
}
@org.junit.Test
public void homeVideoContent() throws Exception {
String content = spider.homeVideoContent();
JsonObject map = Json.safeObject(content);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println("homeVideoContent--" + gson.toJson(map));
//Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
}
@org.junit.Test
public void categoryContent() throws Exception {
String content = spider.categoryContent("2", "2", true, new HashMap<>());
JsonObject map = Json.safeObject(content);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println("categoryContent--" + gson.toJson(map));
Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
}
@org.junit.Test
public void detailContent() throws Exception {
String content = spider.detailContent(Arrays.asList("/detail/126164"));
JsonObject map = Json.safeObject(content);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println("detailContent--" + gson.toJson(map));
Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
}
@org.junit.Test
public void playerContent() throws Exception {
String froms = "glod";
String urls = "1$/vod/play/126164/sid/1057548#2$/vod/play/126164/sid/1057549#3$/vod/play/126164/sid/1057735#4$/vod/play/126164/sid/1057683";
for (int i = 0; i < urls.split("\\$\\$\\$").length; i++) {
String content = spider.playerContent(froms.split("\\$\\$\\$")[i], urls.split("\\$\\$\\$")[i].split("#")[0].split("\\$")[1], new ArrayList<>());
JsonObject map = Json.safeObject(content);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println("playerContent--" + gson.toJson(map));
Assert.assertFalse(map.getAsJsonPrimitive("url").getAsString().isEmpty());
}
}
@org.junit.Test
public void searchContent() throws Exception {
String content = spider.searchContent("", false);
JsonObject map = Json.safeObject(content);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println("searchContent--" + gson.toJson(map));
Assert.assertFalse(map.getAsJsonArray("list").isEmpty());
}
}

Binary file not shown.

View File

@ -1 +1 @@
0dcb7bdf2bfb2e77fdea1d66f53d1d60 1766329347d5e433c0983b6800348229

View File

@ -1,5 +1,5 @@
{ {
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;0dcb7bdf2bfb2e77fdea1d66f53d1d60", "spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;1766329347d5e433c0983b6800348229",
"lives": [ "lives": [
{ {
"name": "直播ipv6", "name": "直播ipv6",
@ -190,6 +190,15 @@
"changeable": 0, "changeable": 0,
"ext": {} "ext": {}
}, },
{
"key": "glod",
"name": "金牌 | 影视",
"type": 3,
"api": "csp_Glod",
"searchable": 1,
"changeable": 0,
"ext": {}
},
{ {
"key": "newvision", "key": "newvision",
"name":"(js)新视觉影院(不稳定)", "name":"(js)新视觉影院(不稳定)",

View File

@ -1,5 +1,5 @@
{ {
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;0dcb7bdf2bfb2e77fdea1d66f53d1d60", "spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;1766329347d5e433c0983b6800348229",
"lives": [ "lives": [
{ {
"name": "直播ipv6", "name": "直播ipv6",

View File

@ -1,5 +1,5 @@
{ {
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;0dcb7bdf2bfb2e77fdea1d66f53d1d60", "spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;1766329347d5e433c0983b6800348229",
"lives": [ "lives": [
{ {
"name": "直播ipv6", "name": "直播ipv6",
@ -190,6 +190,15 @@
"changeable": 0, "changeable": 0,
"ext": {} "ext": {}
}, },
{
"key": "glod",
"name": "金牌 | 影视",
"type": 3,
"api": "csp_Glod",
"searchable": 1,
"changeable": 0,
"ext": {}
},
{ {
"key": "newvision", "key": "newvision",
"name":"(js)新视觉影院(不稳定)", "name":"(js)新视觉影院(不稳定)",