旋风影视

This commit is contained in:
lushunming 2024-08-14 16:30:27 +08:00
parent 33797895e2
commit e225de096e
6 changed files with 272 additions and 3 deletions

View File

@ -0,0 +1,165 @@
package com.github.catvod.spider;
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.net.OkResult;
import com.github.catvod.utils.Json;
import com.github.catvod.utils.Util;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class XuanFeng extends Spider {
private static final String siteUrl = "https://miao101.com";
private static final String apiUrl = siteUrl + "/api";
private HashMap<String, String> getHeaders() {
return Util.webHeaders(siteUrl);
}
@Override
public String homeContent(boolean filter) throws Exception {
List<Vod> list = new ArrayList<>();
List<Class> classes = new ArrayList<>();
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
Document doc = Jsoup.parse(OkHttp.string(siteUrl, getHeaders()));
for (Element element : doc.select("#navbarSupportedContent > ul > li ")) {
if (element.select("a.nav-link").attr("href").startsWith("/")) {
classes.add(new Class(element.select("a.nav-link").attr("href"), element.text()));
} else {
for (Element element1 : element.select("ul > li > a")) {
classes.add(new Class(element1.attr("href"), element1.text()));
}
}
}
for (Element element : doc.select("#container > div.row > div.col-md-2.col-6")) {
try {
String pic = element.select("img").attr("src");
String url = element.select("div.cover-wrap > a").attr("href");
String name = element.select("div.card-title").text();
list.add(new Vod(url, name, pic));
} catch (Exception ignored) {
}
}
return Result.string(classes, list);
}
@Override
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
List<Vod> list = new ArrayList<>();
tid = tid.replaceAll("1", "");
String target = apiUrl + tid + "load.json";
OkResult result = OkHttp.post(target, Map.of("page", pg), getHeaders());
if (result.getCode() == 200) {
String body = result.getBody();
Map<String, ArrayList<Map<String, Object>>> obj = new HashMap<>();
obj = Json.parseSafe(body, obj.getClass());
ArrayList<Map<String, Object>> videos = obj.get("videos");
for (Map<String, Object> video : videos) {
list.add(new Vod("/video/" + video.get("ID").toString(), video.get("Title").toString(), video.get("Cover").toString()));
}
Integer total = Integer.MAX_VALUE;
return Result.string(Integer.parseInt(pg), Integer.parseInt(pg) + 1, list.size(), total, list);
}
return null;
}
@Override
public String detailContent(List<String> ids) throws Exception {
Document doc = Jsoup.parse(OkHttp.string(siteUrl.concat(ids.get(0)), getHeaders()));
String name = doc.select("#container > div.row.phone > div.col-md-8 > div:nth-child(3) > div.col-md-8 > h1").text();
String pic = doc.select("#container > div.row.phone > div.col-md-8 > div.d-flex.mb-3 > div.flex-shrink-0 > img").attr("src");
String year = doc.select("#container > div.row.phone > div.col-md-8 > div.d-flex.mb-3 > div.flex-grow-1 > p:nth-child(11)").text();
String desc = doc.select("#container > div.row.phone > div.col-md-8 > div.text-break.ft14").text();
String jsonStr = Util.findByRegex("JSON.parse\\(\"(.*?)\"\\)", doc.html(), 1);
Map<String, Object> map = Json.parseSafe(jsonStr.replaceAll("\\\\u0022", "\""), Map.class);
List<Map<String, Object>> headers = (List<Map<String, Object>>) map.get("headers");
List<List<String>> clips = (List<List<String>>) map.get("clips");
// 播放源
String PlayFrom = "";
String PlayUrl = "";
for (int i = 0; i < headers.size(); i++) {
String tabName = (String) headers.get(i).get("Name");
if (!"".equals(PlayFrom)) {
PlayFrom = PlayFrom + "$$$" + tabName;
} else {
PlayFrom = PlayFrom + tabName;
}
String liUrl = "";
for (List<String> clip : clips) {
if (!"".equals(liUrl)) {
liUrl = liUrl + "#" + clip.get(0) + "$" + clip.get(1);
} else {
liUrl = liUrl + clip.get(0) + "$" + clip.get(1);
}
}
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.setVodContent(desc);
vod.setVodPlayFrom(PlayFrom);
vod.setVodPlayUrl(PlayUrl);
return Result.string(vod);
}
@Override
public String searchContent(String key, boolean quick) throws Exception {
List<Vod> list = new ArrayList<>();
Document doc = Jsoup.parse(OkHttp.string(siteUrl.concat("/search?q=").concat(URLEncoder.encode(key, "UTF-8")), getHeaders()));
for (Element element : doc.select("#container > div.row > div.col-md-2.col-6")) {
try {
String pic = element.select("img").attr("src");
String url = element.select("div.cover-wrap > a").attr("href");
String name = element.select("h6").text();
list.add(new Vod(url, name, pic));
} catch (Exception ignored) {
}
}
return Result.string(list);
}
@Override
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
return Result.get().url(id).header(getHeaders()).string();
}
}

View File

@ -0,0 +1,96 @@
import android.app.Application;
import com.github.catvod.spider.ChangZhang;
import com.github.catvod.spider.Init;
import com.github.catvod.spider.XuanFeng;
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;
@RunWith(RobolectricTestRunner.class)
public class XuanFengTest {
// @Mock
private Application mockContext;
private XuanFeng spider;
@org.junit.Before
public void setUp() throws Exception {
mockContext = RuntimeEnvironment.application;
Init.init(mockContext);
spider = new XuanFeng();
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("/tag/悬疑片/1", "2", true, null);
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("/video/8dFoErWcVsJJLsJd7sFPMQ"));
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 = "量子$$$淘片";
String urls ="第01集$https://v.cdnlz3.com/20240731/25186_490331f6/index.m3u8#第02集$https://v.cdnlz3.com/20240731/25187_c7e06160/index.m3u8#第03集$https://v.cdnlz3.com/20240731/25189_28570e77/index.m3u8#第04集$https://v.cdnlz3.com/20240731/25188_a0d85819/index.m3u8#第05集$https://v.cdnlz3.com/20240801/25231_ffa23109/index.m3u8#第06集$https://v.cdnlz3.com/20240801/25232_7cdfc398/index.m3u8#第07集$https://v.cdnlz12.com/20240802/16173_42dcc85e/index.m3u8#第08集$https://v.cdnlz12.com/20240802/16174_ff0b89d2/index.m3u8#第09集$https://v.cdnlz3.com/20240803/25279_d5059500/index.m3u8#第10集$https://v.cdnlz3.com/20240803/25280_cda61290/index.m3u8#第11集$https://v.cdnlz12.com/20240804/16205_5bc22654/index.m3u8#第12集$https://v.cdnlz12.com/20240804/16206_3bcaf472/index.m3u8#第13集$https://v.cdnlz3.com/20240805/25321_bc51b2b3/index.m3u8#第14集$https://v.cdnlz3.com/20240805/25322_cadf8e24/index.m3u8#第15集$https://v.cdnlz12.com/20240806/16229_bee0732e/index.m3u8#第16集$https://v.cdnlz12.com/20240806/16228_a9b865e1/index.m3u8#第17集$https://v.cdnlz3.com/20240807/25396_52a2dde7/index.m3u8#第18集$https://v.cdnlz3.com/20240807/25397_4bf5838a/index.m3u8#第19集$https://v.cdnlz3.com/20240808/25421_08a90c9a/index.m3u8#第20集$https://v.cdnlz3.com/20240808/25422_d6341248/index.m3u8#第21集$https://v.cdnlz3.com/20240809/25447_34159679/index.m3u8#第22集$https://v.cdnlz3.com/20240809/25448_66e070eb/index.m3u8#第23集$https://v.cdnlz3.com/20240810/25478_d1ef4ec0/index.m3u8#第24集$https://v.cdnlz3.com/20240810/25479_c7db7c2b/index.m3u8#第25集$https://v.cdnlz3.com/20240811/25518_08a2d2dd/index.m3u8#第26集$https://v.cdnlz3.com/20240811/25519_dfeb62f9/index.m3u8#第27集$https://v.cdnlz3.com/20240812/25553_fc7bd8f6/index.m3u8#第28集$https://v.cdnlz3.com/20240812/25554_20b4b783/index.m3u8#第29集$https://v.cdnlz3.com/20240813/25575_7df14a3e/index.m3u8#第30集$https://v.cdnlz3.com/20240813/25576_a012c969/index.m3u8$$$第01集$https://v.cdnlz3.com/20240731/25186_490331f6/index.m3u8#第02集$https://v.cdnlz3.com/20240731/25187_c7e06160/index.m3u8#第03集$https://v.cdnlz3.com/20240731/25189_28570e77/index.m3u8#第04集$https://v.cdnlz3.com/20240731/25188_a0d85819/index.m3u8#第05集$https://v.cdnlz3.com/20240801/25231_ffa23109/index.m3u8#第06集$https://v.cdnlz3.com/20240801/25232_7cdfc398/index.m3u8#第07集$https://v.cdnlz12.com/20240802/16173_42dcc85e/index.m3u8#第08集$https://v.cdnlz12.com/20240802/16174_ff0b89d2/index.m3u8#第09集$https://v.cdnlz3.com/20240803/25279_d5059500/index.m3u8#第10集$https://v.cdnlz3.com/20240803/25280_cda61290/index.m3u8#第11集$https://v.cdnlz12.com/20240804/16205_5bc22654/index.m3u8#第12集$https://v.cdnlz12.com/20240804/16206_3bcaf472/index.m3u8#第13集$https://v.cdnlz3.com/20240805/25321_bc51b2b3/index.m3u8#第14集$https://v.cdnlz3.com/20240805/25322_cadf8e24/index.m3u8#第15集$https://v.cdnlz12.com/20240806/16229_bee0732e/index.m3u8#第16集$https://v.cdnlz12.com/20240806/16228_a9b865e1/index.m3u8#第17集$https://v.cdnlz3.com/20240807/25396_52a2dde7/index.m3u8#第18集$https://v.cdnlz3.com/20240807/25397_4bf5838a/index.m3u8#第19集$https://v.cdnlz3.com/20240808/25421_08a90c9a/index.m3u8#第20集$https://v.cdnlz3.com/20240808/25422_d6341248/index.m3u8#第21集$https://v.cdnlz3.com/20240809/25447_34159679/index.m3u8#第22集$https://v.cdnlz3.com/20240809/25448_66e070eb/index.m3u8#第23集$https://v.cdnlz3.com/20240810/25478_d1ef4ec0/index.m3u8#第24集$https://v.cdnlz3.com/20240810/25479_c7db7c2b/index.m3u8#第25集$https://v.cdnlz3.com/20240811/25518_08a2d2dd/index.m3u8#第26集$https://v.cdnlz3.com/20240811/25519_dfeb62f9/index.m3u8#第27集$https://v.cdnlz3.com/20240812/25553_fc7bd8f6/index.m3u8#第28集$https://v.cdnlz3.com/20240812/25554_20b4b783/index.m3u8#第29集$https://v.cdnlz3.com/20240813/25575_7df14a3e/index.m3u8#第30集$https://v.cdnlz3.com/20240813/25576_a012c969/index.m3u8";
for (int i = 0; i < urls.split("\\$\\$\\$").length; i++) {
String content = spider.playerContent(froms.split("\\$\\$\\$")[i], urls.split("\\$\\$\\$")[i].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 @@
1f2e3362ef4ccefef998a9f4ea525924
0dcb7bdf2bfb2e77fdea1d66f53d1d60

View File

@ -1,5 +1,5 @@
{
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;1f2e3362ef4ccefef998a9f4ea525924",
"spider": "https://androidcatvodspider.pages.dev/jar/custom_spider.jar;md5;0dcb7bdf2bfb2e77fdea1d66f53d1d60",
"lives": [
{
"name": "直播ipv6",
@ -51,6 +51,14 @@
"searchable": 1,
"changeable": 1,
"ext": {}
},{
"key": "XuanFeng",
"name": "旋风影视",
"type": 3,
"api": "csp_XuanFeng",
"searchable": 1,
"changeable": 1,
"ext": {}
},
{
"key": "NCat",

View File

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