diff --git a/.gitignore b/.gitignore index bd8b3b4d..4e7a58af 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ *build *.jks *ni.java -*ar.java /local.properties \ No newline at end of file diff --git a/app/src/main/java/com/github/catvod/bean/Vod.java b/app/src/main/java/com/github/catvod/bean/Vod.java index 63f09c89..e8494501 100644 --- a/app/src/main/java/com/github/catvod/bean/Vod.java +++ b/app/src/main/java/com/github/catvod/bean/Vod.java @@ -1,5 +1,6 @@ package com.github.catvod.bean; +import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; public class Vod { @@ -33,6 +34,11 @@ public class Vod { @SerializedName("style") private Style style; + public static Vod objectFrom(String str) { + Vod item = new Gson().fromJson(str, Vod.class); + return item == null ? new Vod() : item; + } + public Vod() { } @@ -116,11 +122,11 @@ public class Vod { public void setVodPlayUrl(String vodPlayUrl) { this.vodPlayUrl = vodPlayUrl; } - + public String getVodPlayUrl() { return vodPlayUrl; } - + public void setVodTag(String vodTag) { this.vodTag = vodTag; } diff --git a/app/src/main/java/com/github/catvod/spider/Star.java b/app/src/main/java/com/github/catvod/spider/Star.java new file mode 100644 index 00000000..878e7a00 --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/Star.java @@ -0,0 +1,131 @@ +package com.github.catvod.spider; + +import android.content.Context; +import android.text.TextUtils; + +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.bean.star.Card; +import com.github.catvod.bean.star.Condition; +import com.github.catvod.bean.star.Detail; +import com.github.catvod.bean.star.Query; +import com.github.catvod.crawler.Spider; +import com.github.catvod.net.OkHttp; + +import org.json.JSONObject; +import org.jsoup.Jsoup; +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 Star extends Spider { + + private static final String apiUrl = "https://aws.ulivetv.net/v3/web/api/filter"; + private static final String siteUrl = "https://www.histar.tv/"; + private static final String detail = siteUrl + "vod/detail/"; + private static final String data = "/_next/data/"; + private LinkedHashMap map; + private String ver; + + private String getVer() { + for (Element script : Jsoup.parse(OkHttp.string(siteUrl)).select("script")) if (script.attr("src").contains("buildManifest.js")) return script.attr("src").split("/")[3]; + return ""; + } + + @Override + public void init(Context context, String extend) { + map = new LinkedHashMap<>(); + map.put("movie", "电影"); + map.put("drama", "电视剧"); + map.put("animation", "动漫"); + map.put("variety", "综艺"); + map.put("documentary", "纪录片"); + ver = getVer(); + } + + @Override + public String homeContent(boolean filter) throws Exception { + List classes = new ArrayList<>(); + LinkedHashMap> filters = new LinkedHashMap<>(); + for (Map.Entry entry : map.entrySet()) classes.add(new Class(entry.getKey(), entry.getValue())); + for (Class type : classes) { + String json = OkHttp.string(siteUrl + data + ver + "/" + type.getTypeId() + "/all/all/all.json"); + JSONObject obj = new JSONObject(json).getJSONObject("pageProps").getJSONObject("filterCondition"); + Condition item = Condition.objectFrom(obj.toString()); + filters.put(type.getTypeId(), item.getFilter()); + } + return Result.string(classes, filters); + } + + @Override + public String homeVideoContent() throws Exception { + List list = new ArrayList<>(); + Element script = Jsoup.parse(OkHttp.string(siteUrl)).select("#__NEXT_DATA__").get(0); + List cards = Card.arrayFrom(new JSONObject(script.data()).getJSONObject("props").getJSONObject("pageProps").getJSONArray("cards").toString()); + for (Card card : cards) if (!card.getName().equals("电视直播")) for (Card item : card.getCards()) list.add(item.vod()); + return Result.string(list); + } + + @Override + public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { + String year = extend.containsKey("year") ? extend.get("year") : ""; + String type = extend.containsKey("type") ? extend.get("type") : ""; + String area = extend.containsKey("area") ? extend.get("area") : ""; + Query query = new Query(); + query.setPageSize(16); + query.setChName(map.get(tid)); + query.setPage(Integer.parseInt(pg)); + if (year.length() > 0) query.setYear(year); + if (type.length() > 0) query.setLabel(type); + if (area.length() > 0) query.setCountry(area); + String body = OkHttp.postJson(apiUrl, query.toString()).getBody(); + List cards = Card.arrayFrom(new JSONObject(body).getJSONObject("data").getJSONArray("list").toString()); + List list = new ArrayList<>(); + for (Card card : cards) list.add(card.vod()); + return Result.string(list); + } + + @Override + public String detailContent(List ids) throws Exception { + Element script = Jsoup.parse(OkHttp.string(detail.concat(ids.get(0)))).select("#__NEXT_DATA__").get(0); + Detail detail = Detail.objectFrom(new JSONObject(script.data()).getJSONObject("props").getJSONObject("pageProps").getJSONObject("pageData").toString()); + Vod vod = new Vod(); + vod.setVodId(ids.get(0)); + vod.setVodPic(detail.getPicurl()); + vod.setVodYear(detail.getTime()); + vod.setVodName(detail.getName()); + vod.setVodArea(detail.getCountry()); + vod.setVodActor(detail.getActor()); + vod.setVodRemarks(detail.getCountStr()); + vod.setVodContent(detail.getDesc()); + vod.setVodDirector(detail.getDirector()); + vod.setTypeName(detail.getLabel()); + vod.setVodPlayFrom("FongMi"); + List playUrls = new ArrayList<>(); + for (Detail.Video video : detail.getVideos()) playUrls.add(video.getEporder() + "$" + video.getPurl()); + vod.setVodPlayUrl(TextUtils.join("#", playUrls)); + return Result.string(vod); + } + + @Override + public String searchContent(String key, boolean quick) throws Exception { + List list = new ArrayList<>(); + String json = OkHttp.string(siteUrl + data + ver + "/search.json?word=" + URLEncoder.encode(key)); + List items = Card.arrayFrom(new JSONObject(json).getJSONObject("pageProps").getJSONArray("initList").toString()); + for (Card item : items) list.add(item.vod()); + return Result.string(list); + } + + @Override + public String playerContent(String flag, String id, List vipFlags) throws Exception { + return Result.get().url(id).string(); + } +} + diff --git a/app/src/main/java/com/github/catvod/spider/YingShi.java b/app/src/main/java/com/github/catvod/spider/YingShi.java new file mode 100644 index 00000000..ec5f06b7 --- /dev/null +++ b/app/src/main/java/com/github/catvod/spider/YingShi.java @@ -0,0 +1,166 @@ +package com.github.catvod.spider; + +import android.content.Context; +import android.text.TextUtils; + +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.FileUtil; +import com.github.catvod.utils.Utils; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.io.File; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class YingShi extends Spider { + + private final String siteUrl = "https://www.yingshi.tv"; + private ExecutorService service; + + public File getCache() { + return FileUtil.getCacheFile("ying_shi_home"); + } + + private HashMap getHeaders() { + HashMap headers = new HashMap<>(); + headers.put("User-Agent", Utils.CHROME); + headers.put("Referer", siteUrl); + return headers; + } + + @Override + public void init(Context context, String extend) { + service = Executors.newCachedThreadPool(); + } + + @Override + public String homeContent(boolean filter) throws Exception { + if (getCache().exists()) return FileUtil.read(getCache()); + List classes = new ArrayList<>(); + classes.add(new Class("1", "電視劇")); + classes.add(new Class("2", "電影")); + classes.add(new Class("4", "動漫")); + classes.add(new Class("3", "綜藝")); + classes.add(new Class("5", "紀錄片")); + LinkedHashMap> filters = new LinkedHashMap<>(); + for (Class type : classes) filters.put(type.getTypeId(), service.submit(new Job(type.getTypeId())).get()); + String result = Result.string(classes, filters); + FileUtil.write(getCache(), result); + return result; + } + + @Override + public String homeVideoContent() { + Document doc = Jsoup.parse(OkHttp.string(siteUrl)); + List list = new ArrayList<>(); + for (Element e : doc.select("div#desktop-container").select("li.ys_show_item")) { + String id = e.select("a").attr("href").split("/")[4]; + String pic = e.select("img").attr("src"); + String name = e.select("h2.ys_show_title").text(); + String remark = e.select("span.ys_show_episode_text").text(); + if (!TextUtils.isEmpty(name)) list.add(new Vod(id, name, pic, remark)); + } + return Result.string(list); + } + + @Override + public String categoryContent(String tid, String pg, boolean filter, HashMap extend) throws Exception { + String by = extend.containsKey("by") ? extend.get("by") : "time"; + String cls = extend.containsKey("class") ? extend.get("class") : ""; + String area = extend.containsKey("area") ? extend.get("area") : ""; + String lang = extend.containsKey("lang") ? extend.get("lang") : ""; + String year = extend.containsKey("year") ? extend.get("year") : ""; + Map params = new HashMap<>(); + params.put("mid", "1"); + params.put("by", by); + params.put("tid", tid); + params.put("page", pg); + params.put("class", cls); + params.put("year", year); + params.put("lang", lang); + params.put("area", area); + params.put("limit", "35"); + return OkHttp.get(siteUrl + "/ajax/data", params, getHeaders()); + } + + @Override + public String detailContent(List ids) throws Exception { + Document doc = Jsoup.parse(OkHttp.string(siteUrl + "/vod/play/id/" + ids.get(0) + "/sid/1/nid/1.html")); + String json = doc.html().split("let data = ")[1].split(";")[0]; + Vod vod = Vod.objectFrom(json); + return Result.string(vod); + } + + @Override + public String playerContent(String flag, String id, List vipFlags) throws Exception { + return Result.get().url(id).m3u8().string(); + } + + @Override + public String searchContent(String key, boolean quick) throws Exception { + return searchContent(key, "1"); + } + + @Override + public String searchContent(String key, boolean quick, String pg) throws Exception { + return searchContent(key, pg); + } + + private String searchContent(String key, String pg) { + Map params = new HashMap<>(); + params.put("mid", "1"); + params.put("page", pg); + params.put("limit", "18"); + params.put("wd", URLEncoder.encode(key)); + return OkHttp.get(siteUrl + "/ajax/search.html", params, getHeaders()); + } + + private static class Job implements Callable> { + + private final String typeId; + + public Job(String typeId) { + this.typeId = typeId; + } + + @Override + public List call() { + List items = new ArrayList<>(); + String url = "https://www.yingshi.tv/vod/show/by/hits_day/id/%s/order/desc.html"; + Document doc = Jsoup.parse(OkHttp.string(String.format(url, typeId))); + items.add(filter(doc.select("div.ys_filter_list_show_types").get(0).select("div.ys_filter.flex").get(1).select("div > div"), "by", "排序", 4)); + items.add(filter(doc.select("div#ys_filter_by_class").get(0).select("div > div"), "class", "類型", 6)); + items.add(filter(doc.select("div#ys_filter_by_country").get(0).select("div > div"), "area", "地區", 4)); + items.add(filter(doc.select("div#ys_filter_by_lang").get(0).select("div > div"), "lang", "語言", 8)); + items.add(filter(doc.select("div#ys_filter_by_year").get(0).select("div > div"), "year", "時間", 10)); + return items; + } + + private Filter filter(Elements elements, String key, String name, int index) { + List values = new ArrayList<>(); + for (Element e : elements) { + String n = e.select("p").text(); + boolean all = n.contains("全部"); + String v = all ? "" : e.select("a").attr("href").split("/")[index].replace(".html", ""); + values.add(new Filter.Value(n, v)); + } + return new Filter(key, name, values); + } + } +} diff --git a/jar/custom_spider.jar b/jar/custom_spider.jar index 60c0b8a9..3eac881d 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 898a4231..754d278b 100644 --- a/jar/custom_spider.jar.md5 +++ b/jar/custom_spider.jar.md5 @@ -1 +1 @@ -bb25b79fe383dfe57c8d984824e700e2 +d5b7a7db38a22a734f298a4e5b876ff3