Clean code
This commit is contained in:
parent
7b76dc4523
commit
f9e9b80ba2
|
|
@ -42,7 +42,7 @@ android {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.squareup.okhttp3:okhttp:' + okhttpVersion
|
implementation 'com.squareup.okhttp3:okhttp:' + okhttpVersion
|
||||||
implementation 'com.github.thegrizzlylabs:sardine-android:0.9'
|
implementation 'com.github.thegrizzlylabs:sardine-android:0.9'
|
||||||
implementation 'wang.harlon.quickjs:wrapper-android:2.4.4'
|
implementation 'wang.harlon.quickjs:wrapper-android:2.4.5'
|
||||||
implementation 'com.google.code.gson:gson:2.11.0'
|
implementation 'com.google.code.gson:gson:2.11.0'
|
||||||
implementation 'cn.wanghaomiao:JsoupXpath:2.5.1'
|
implementation 'cn.wanghaomiao:JsoupXpath:2.5.1'
|
||||||
implementation 'com.orhanobut:logger:2.2.0'
|
implementation 'com.orhanobut:logger:2.2.0'
|
||||||
|
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
package com.github.catvod.bean.uvod;
|
|
||||||
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import com.github.catvod.bean.Vod;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Data {
|
|
||||||
|
|
||||||
@SerializedName("video_fragment_list")
|
|
||||||
private List<VideoFragmentList> videoFragmentList;
|
|
||||||
@SerializedName(value = "video_latest_list", alternate = {"video_list"})
|
|
||||||
private List<VideoLatest> videolatestlist;
|
|
||||||
@SerializedName(value = "video", alternate = {"video_soruce"})
|
|
||||||
private Video video;
|
|
||||||
|
|
||||||
public static Data objectFrom(String str) {
|
|
||||||
JsonObject jsonObject = JsonParser.parseString(str).getAsJsonObject();
|
|
||||||
if (jsonObject.has("data")) return new Gson().fromJson(jsonObject.get("data"), Data.class);
|
|
||||||
return new Data();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<VideoFragmentList> getVideoFragmentList() {
|
|
||||||
return videoFragmentList == null ? Collections.emptyList() : videoFragmentList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<VideoLatest> getVideoLatest() {
|
|
||||||
return videolatestlist == null ? Collections.emptyList() : videolatestlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Video getVideo() {
|
|
||||||
return video == null ? new Video() : video;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Vod> getList() {
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
for (Data.VideoLatest video : getVideoLatest()) list.add(video.vod());
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class VideoLatest {
|
|
||||||
|
|
||||||
@SerializedName("id")
|
|
||||||
private String id;
|
|
||||||
@SerializedName("title")
|
|
||||||
private String title;
|
|
||||||
@SerializedName("pic")
|
|
||||||
private String pic;
|
|
||||||
@SerializedName("state")
|
|
||||||
private String state;
|
|
||||||
@SerializedName("last_fragment_symbol")
|
|
||||||
private String lastfragment;
|
|
||||||
@SerializedName("year")
|
|
||||||
private String year;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return TextUtils.isEmpty(id) ? "" : id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return TextUtils.isEmpty(title) ? "" : title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPic() {
|
|
||||||
return TextUtils.isEmpty(pic) ? "" : pic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getState() {
|
|
||||||
return TextUtils.isEmpty(state) ? "" : state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastFragment() {
|
|
||||||
return TextUtils.isEmpty(lastfragment) ? "" : lastfragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getYear() {
|
|
||||||
return TextUtils.isEmpty(year) ? "" : year;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vod vod() {
|
|
||||||
return new Vod(getId(), getTitle(), getPic(), getState() + getLastFragment());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Video {
|
|
||||||
|
|
||||||
@SerializedName("year")
|
|
||||||
private String year;
|
|
||||||
@SerializedName("region")
|
|
||||||
private String region;
|
|
||||||
@SerializedName("starring")
|
|
||||||
private String starring;
|
|
||||||
@SerializedName("state")
|
|
||||||
private String state;
|
|
||||||
@SerializedName("description")
|
|
||||||
private String description;
|
|
||||||
@SerializedName("director")
|
|
||||||
private String director;
|
|
||||||
@SerializedName("language")
|
|
||||||
private String language;
|
|
||||||
@SerializedName("url")
|
|
||||||
private String url;
|
|
||||||
|
|
||||||
public String getYear() {
|
|
||||||
return TextUtils.isEmpty(year) ? "" : year;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRegion() {
|
|
||||||
return TextUtils.isEmpty(region) ? "" : region;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStarring() {
|
|
||||||
return TextUtils.isEmpty(starring) ? "" : starring;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return TextUtils.isEmpty(description) ? "" : description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getState() {
|
|
||||||
return TextUtils.isEmpty(state) ? "" : state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDirector() {
|
|
||||||
return TextUtils.isEmpty(director) ? "" : director;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLanguage() {
|
|
||||||
return TextUtils.isEmpty(language) ? "" : language;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return TextUtils.isEmpty(url) ? "" : url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class VideoFragmentList {
|
|
||||||
|
|
||||||
@SerializedName("id")
|
|
||||||
private String id;
|
|
||||||
@SerializedName("symbol")
|
|
||||||
private String symbol;
|
|
||||||
@SerializedName("qualities")
|
|
||||||
private List<Integer> qualities;
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return TextUtils.isEmpty(id) ? "" : id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSymbol() {
|
|
||||||
return TextUtils.isEmpty(symbol) ? "" : symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Integer> getQualities() {
|
|
||||||
if (qualities == null || qualities.isEmpty()) return Collections.emptyList();
|
|
||||||
Collections.sort(qualities, Collections.reverseOrder());
|
|
||||||
return qualities;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -7,7 +7,7 @@ import android.widget.Button;
|
||||||
import com.github.catvod.R;
|
import com.github.catvod.R;
|
||||||
import com.github.catvod.crawler.Spider;
|
import com.github.catvod.crawler.Spider;
|
||||||
import com.github.catvod.spider.Init;
|
import com.github.catvod.spider.Init;
|
||||||
import com.github.catvod.spider.Uvod;
|
import com.github.catvod.spider.PTT;
|
||||||
import com.orhanobut.logger.AndroidLogAdapter;
|
import com.orhanobut.logger.AndroidLogAdapter;
|
||||||
import com.orhanobut.logger.Logger;
|
import com.orhanobut.logger.Logger;
|
||||||
|
|
||||||
|
|
@ -46,7 +46,7 @@ public class MainActivity extends Activity {
|
||||||
private void initSpider() {
|
private void initSpider() {
|
||||||
try {
|
try {
|
||||||
Init.init(getApplicationContext());
|
Init.init(getApplicationContext());
|
||||||
spider = new Uvod();
|
spider = new PTT();
|
||||||
spider.init(this, "");
|
spider.init(this, "");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
||||||
|
|
@ -122,14 +122,13 @@ public class AList extends Spider {
|
||||||
String path = id.substring(0, id.lastIndexOf("/"));
|
String path = id.substring(0, id.lastIndexOf("/"));
|
||||||
String name = path.substring(path.lastIndexOf("/") + 1);
|
String name = path.substring(path.lastIndexOf("/") + 1);
|
||||||
Drive drive = getDrive(key);
|
Drive drive = getDrive(key);
|
||||||
List<Item> parents = getList(path, false);
|
|
||||||
Sorter.sort("name", "asc", parents);
|
|
||||||
Vod vod = new Vod();
|
Vod vod = new Vod();
|
||||||
vod.setVodPlayFrom(key);
|
vod.setVodPlayFrom(key);
|
||||||
vod.setVodId(id);
|
vod.setVodId(id);
|
||||||
vod.setVodName(name);
|
vod.setVodName(name);
|
||||||
vod.setVodPic(vodPic);
|
vod.setVodPic(vodPic);
|
||||||
List<String> playUrls = new ArrayList<>();
|
List<String> playUrls = new ArrayList<>();
|
||||||
|
List<Item> parents = getList(path, false);
|
||||||
for (Item item : parents) if (item.isMedia(drive.isNew())) playUrls.add(item.getName() + "$" + item.getVodId(path) + findSubs(path, parents));
|
for (Item item : parents) if (item.isMedia(drive.isNew())) playUrls.add(item.getName() + "$" + item.getVodId(path) + findSubs(path, parents));
|
||||||
vod.setVodPlayUrl(TextUtils.join("#", playUrls));
|
vod.setVodPlayUrl(TextUtils.join("#", playUrls));
|
||||||
return Result.string(vod);
|
return Result.string(vod);
|
||||||
|
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
package com.github.catvod.spider;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import com.github.catvod.bean.Class;
|
|
||||||
import com.github.catvod.bean.Result;
|
|
||||||
import com.github.catvod.bean.Vod;
|
|
||||||
import com.github.catvod.crawler.Spider;
|
|
||||||
import com.github.catvod.net.OkHttp;
|
|
||||||
import com.github.catvod.utils.Crypto;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author leospring
|
|
||||||
* 星牙短剧
|
|
||||||
*/
|
|
||||||
public class AppXY extends Spider {
|
|
||||||
|
|
||||||
private String auth;
|
|
||||||
|
|
||||||
private Map<String, String> getHeader() {
|
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
map.put("User-Agent", "okhttp/4.10.0");
|
|
||||||
if (!TextUtils.isEmpty(auth)) map.put("Authorization", auth);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Context context, String extend) throws Exception {
|
|
||||||
String s = System.currentTimeMillis() + "";
|
|
||||||
Map<String, String> map = new HashMap<>();
|
|
||||||
map.put("device", Crypto.md5(s));
|
|
||||||
map.put("install_first_open", "true");
|
|
||||||
map.put("first_install_time", s);
|
|
||||||
map.put("last_update_time", s);
|
|
||||||
auth = new JSONObject(OkHttp.post("https://app.whjzjx.cn/v1/account/login", map, getHeader()).getBody()).optJSONObject("data").optString("token");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String homeContent(boolean filter) throws Exception {
|
|
||||||
ArrayList<Class> classes = new ArrayList<>();
|
|
||||||
JSONArray array = new JSONObject(OkHttp.string("https://app.whjzjx.cn/cloud/v2/theater/classes", getHeader())).optJSONObject("data").optJSONArray("list");
|
|
||||||
for (int i = 0; i < array.length(); ++i) {
|
|
||||||
JSONObject object = array.optJSONObject(i);
|
|
||||||
if (!object.optString("show_type").contains("Bookstore")) {
|
|
||||||
classes.add(new Class(object.optString("id"), object.optString("class_name")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result.string(classes, new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
|
||||||
List<Vod> videos = new ArrayList<>();
|
|
||||||
String class2Id = extend.get("class2_id");
|
|
||||||
if (class2Id == null) class2Id = "0";
|
|
||||||
JSONArray array = new JSONObject(OkHttp.string(("https://app.whjzjx.cn/cloud/v2/theater/home_page?theater_class_id=" + tid + "&class2_ids=" + class2Id + "&type=1&page_num=" + pg + "&page_size=24"), getHeader())).optJSONObject("data").optJSONArray("list");
|
|
||||||
for (int v = 0; v < array.length(); ++v) {
|
|
||||||
JSONObject object = array.optJSONObject(v).optJSONObject("theater");
|
|
||||||
videos.add(new Vod(object.optString("id"), object.optString("title"), object.optString("cover_url"), object.optString("total") + "集"));
|
|
||||||
}
|
|
||||||
return Result.string(videos);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String detailContent(List<String> ids) throws Exception {
|
|
||||||
Vod vod = new Vod();
|
|
||||||
JSONObject object = new JSONObject(OkHttp.string(("https://app.whjzjx.cn/v2/theater_parent/detail?theater_parent_id=" + ids.get(0)), getHeader())).optJSONObject("data");
|
|
||||||
vod.setVodId(ids.get(0));
|
|
||||||
vod.setVodName(object.optString("title"));
|
|
||||||
vod.setVodPic(object.optString("cover_url"));
|
|
||||||
vod.setTypeName(object.optJSONArray("desc_tags").join(",").replace("\"", ""));
|
|
||||||
vod.setVodContent(object.optString("introduction"));
|
|
||||||
ArrayList<String> playUrls = new ArrayList<>();
|
|
||||||
ArrayList<String> playFrom = new ArrayList<>();
|
|
||||||
playFrom.add("leospring");
|
|
||||||
JSONArray array = object.optJSONArray("theaters");
|
|
||||||
ArrayList<String> urlNames = new ArrayList<>();
|
|
||||||
for (int i = 0; i < array.length(); ++i) {
|
|
||||||
object = array.optJSONObject(i);
|
|
||||||
urlNames.add(object.optString("num") + "$" + object.optString("son_video_url"));
|
|
||||||
}
|
|
||||||
playUrls.add(TextUtils.join("#", urlNames));
|
|
||||||
vod.setVodPlayFrom(TextUtils.join("$$$", playFrom));
|
|
||||||
vod.setVodPlayUrl(TextUtils.join("$$$", playUrls));
|
|
||||||
return Result.string(vod);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String playerContent(String flag, String id, List<String> flags) throws Exception {
|
|
||||||
return Result.get().url(id).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick) throws Exception {
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
JSONArray array = new JSONObject(OkHttp.post("https://app.whjzjx.cn/v3/search", new JSONObject().put("text", key).toString(), getHeader()).getBody()).optJSONObject("data").optJSONObject("theater").optJSONArray("search_data");
|
|
||||||
for (int i = 0; i < array.length(); ++i) {
|
|
||||||
JSONObject object = array.optJSONObject(i);
|
|
||||||
list.add(new Vod(object.optString("id"), object.optString("title"), object.optString("cover_url"), object.optString("score_str")));
|
|
||||||
}
|
|
||||||
return Result.string(list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,179 +0,0 @@
|
||||||
package com.github.catvod.spider;
|
|
||||||
|
|
||||||
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.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.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author FongMi
|
|
||||||
*/
|
|
||||||
public class Dm84 extends Spider {
|
|
||||||
|
|
||||||
private static final String siteUrl = "https://dm84.tv";
|
|
||||||
|
|
||||||
private HashMap<String, String> getHeaders() {
|
|
||||||
HashMap<String, String> headers = new HashMap<>();
|
|
||||||
headers.put("User-Agent", Util.CHROME);
|
|
||||||
headers.put("Accept", Util.ACCEPT);
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Filter getFilter(String name, String key, List<String> texts) {
|
|
||||||
List<Filter.Value> values = new ArrayList<>();
|
|
||||||
for (String text : texts) {
|
|
||||||
if (text.isEmpty()) continue;
|
|
||||||
String n = text.replace("按", "");
|
|
||||||
String v = key.equals("by") ? replaceBy(text) : text;
|
|
||||||
values.add(new Filter.Value(n, v));
|
|
||||||
}
|
|
||||||
return new Filter(key, name, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String replaceBy(String text) {
|
|
||||||
return text.replace("按时间", "time").replace("按人气", "hits").replace("按评分", "score");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String homeContent(boolean filter) {
|
|
||||||
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("ul.nav_row > li > a")) {
|
|
||||||
if (element.attr("href").startsWith("/list")) {
|
|
||||||
String id = element.attr("href").split("-")[1].substring(0, 1);
|
|
||||||
String name = element.text().substring(0, 2);
|
|
||||||
classes.add(new Class(id, name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Class item : classes) {
|
|
||||||
doc = Jsoup.parse(OkHttp.string(siteUrl + "/list-" + item.getTypeId() + ".html", getHeaders()));
|
|
||||||
Elements elements = doc.select("ul.list_filter > li > div");
|
|
||||||
List<Filter> array = new ArrayList<>();
|
|
||||||
array.add(getFilter("類型", "type", elements.get(0).select("a").eachText()));
|
|
||||||
array.add(getFilter("時間", "year", elements.get(1).select("a").eachText()));
|
|
||||||
array.add(getFilter("排序", "by", elements.get(2).select("a").eachText()));
|
|
||||||
filters.put(item.getTypeId(), array);
|
|
||||||
}
|
|
||||||
for (Element element : doc.select("div.item")) {
|
|
||||||
String img = element.select("a.cover").attr("data-bg");
|
|
||||||
String url = element.select("a.title").attr("href");
|
|
||||||
String name = element.select("a.title").text();
|
|
||||||
String remark = element.select("span.desc").text();
|
|
||||||
String id = url.split("/")[2];
|
|
||||||
list.add(new Vod(id, name, img, remark));
|
|
||||||
}
|
|
||||||
return Result.string(classes, list, filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
if (extend.get("type") == null) extend.put("type", "");
|
|
||||||
if (extend.get("year") == null) extend.put("year", "");
|
|
||||||
if (extend.get("by") == null) extend.put("by", "time");
|
|
||||||
String by = extend.get("by");
|
|
||||||
String type = URLEncoder.encode(extend.get("type"));
|
|
||||||
String year = extend.get("year");
|
|
||||||
String target = siteUrl + String.format("/show-%s--%s-%s--%s-%s.html", tid, by, type, year, pg);
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
|
||||||
for (Element element : doc.select("div.item")) {
|
|
||||||
String img = element.select("a.cover").attr("data-bg");
|
|
||||||
String url = element.select("a.title").attr("href");
|
|
||||||
String name = element.select("a.title").text();
|
|
||||||
String remark = element.select("span.desc").text();
|
|
||||||
String id = url.split("/")[2];
|
|
||||||
list.add(new Vod(id, name, img, remark));
|
|
||||||
}
|
|
||||||
return Result.string(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String detailContent(List<String> ids) {
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl.concat("/v/").concat(ids.get(0)), getHeaders()));
|
|
||||||
String name = doc.select("h1.v_title").text();
|
|
||||||
String remarks = doc.select("p.v_desc > span.desc").text();
|
|
||||||
String img = doc.select("meta[property=og:image]").attr("content");
|
|
||||||
String area = doc.select("meta[name=og:video:area]").attr("content");
|
|
||||||
String type = doc.select("meta[name=og:video:class]").attr("content");
|
|
||||||
String actor = doc.select("meta[name=og:video:actor]").attr("content");
|
|
||||||
String content = doc.select("meta[property=og:description]").attr("content");
|
|
||||||
String year = doc.select("meta[name=og:video:release_date]").attr("content");
|
|
||||||
String director = doc.select("meta[name=og:video:director]").attr("content");
|
|
||||||
|
|
||||||
Vod vod = new Vod();
|
|
||||||
vod.setVodId(ids.get(0));
|
|
||||||
vod.setVodPic(img);
|
|
||||||
vod.setVodYear(year);
|
|
||||||
vod.setVodName(name);
|
|
||||||
vod.setVodArea(area);
|
|
||||||
vod.setVodActor(actor);
|
|
||||||
vod.setVodRemarks(remarks);
|
|
||||||
vod.setVodContent(content);
|
|
||||||
vod.setVodDirector(director);
|
|
||||||
vod.setTypeName(type);
|
|
||||||
|
|
||||||
Map<String, String> sites = new LinkedHashMap<>();
|
|
||||||
Elements sources = doc.select("ul.tab_control > li");
|
|
||||||
Elements sourceList = doc.select("ul.play_list");
|
|
||||||
for (int i = 0; i < sources.size(); i++) {
|
|
||||||
Element source = sources.get(i);
|
|
||||||
String sourceName = source.text();
|
|
||||||
Elements playList = sourceList.get(i).select("a");
|
|
||||||
List<String> vodItems = new ArrayList<>();
|
|
||||||
for (int j = 0; j < playList.size(); j++) {
|
|
||||||
Element e = playList.get(j);
|
|
||||||
vodItems.add(e.text() + "$" + e.attr("href"));
|
|
||||||
}
|
|
||||||
if (vodItems.size() > 0) {
|
|
||||||
sites.put(sourceName, TextUtils.join("#", vodItems));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sites.size() > 0) {
|
|
||||||
vod.setVodPlayFrom(TextUtils.join("$$$", sites.keySet()));
|
|
||||||
vod.setVodPlayUrl(TextUtils.join("$$$", sites.values()));
|
|
||||||
}
|
|
||||||
return Result.string(vod);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick) {
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
String target = siteUrl.concat("/s----------.html?wd=").concat(key);
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
|
||||||
for (Element element : doc.select("div.item")) {
|
|
||||||
String img = element.select("a.cover").attr("data-bg");
|
|
||||||
String url = element.select("a.title").attr("href");
|
|
||||||
String name = element.select("a.title").text();
|
|
||||||
String remark = element.select("span.desc").text();
|
|
||||||
String id = url.split("/")[2];
|
|
||||||
list.add(new Vod(id, name, img, remark));
|
|
||||||
}
|
|
||||||
return Result.string(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(siteUrl.concat(id), getHeaders()));
|
|
||||||
String url = doc.select("iframe").attr("src");
|
|
||||||
return Result.get().url(url).parse().header(getHeaders()).string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
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 org.jsoup.Jsoup;
|
|
||||||
import org.jsoup.nodes.Document;
|
|
||||||
import org.jsoup.nodes.Element;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Doll extends Spider {
|
|
||||||
|
|
||||||
private final String url = "https://hongkongdollvideo.com/";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String homeContent(boolean filter) throws Exception {
|
|
||||||
List<Class> classes = new ArrayList<>();
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(url));
|
|
||||||
for (Element a : doc.select("ul.menu").get(0).select("li > a")) {
|
|
||||||
String typeName = a.text();
|
|
||||||
String typeId = a.attr("href");
|
|
||||||
if (typeId.contains(url)) classes.add(new Class(typeId.replace(url, ""), typeName));
|
|
||||||
}
|
|
||||||
for (Element div : doc.select("div.video-item")) {
|
|
||||||
String id = div.select("a.video-title").attr("href").replace(url, "");
|
|
||||||
String name = div.select("a.video-title").text();
|
|
||||||
String pic = div.select("div.thumb > a > img").attr("data-src");
|
|
||||||
String remark = div.select("div.date").text();
|
|
||||||
list.add(new Vod(id, name, pic, remark));
|
|
||||||
}
|
|
||||||
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<>();
|
|
||||||
String target = pg.equals("1") ? url + tid : url + tid + "/" + pg + ".html";
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(target));
|
|
||||||
for (Element div : doc.select("div.video-item")) {
|
|
||||||
String id = div.select("a.video-title").attr("href").replace(url, "");
|
|
||||||
String name = div.select("a.video-title").text();
|
|
||||||
String pic = div.select("div.thumb > a > img").attr("data-src");
|
|
||||||
String remark = div.select("div.date").text();
|
|
||||||
list.add(new Vod(id, name, pic, remark));
|
|
||||||
}
|
|
||||||
return Result.string(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String detailContent(List<String> ids) throws Exception {
|
|
||||||
String html = OkHttp.string(url + ids.get(0));
|
|
||||||
Document doc = Jsoup.parse(html);
|
|
||||||
String pic = doc.select("meta[property=og:image]").attr("content");
|
|
||||||
String name = doc.select("meta[property=og:title]").attr("content");
|
|
||||||
Vod vod = new Vod();
|
|
||||||
vod.setVodId(ids.get(0));
|
|
||||||
vod.setVodPic(pic);
|
|
||||||
vod.setVodName(name);
|
|
||||||
vod.setVodPlayFrom("玩偶姐姐");
|
|
||||||
vod.setVodPlayUrl("播放$" + url + ids.get(0));
|
|
||||||
return Result.string(vod);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
|
||||||
return Result.get().url(id).parse().click("document.getElementById('player-wrapper').click()").string();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean manualVideoCheck() throws Exception {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isVideoFormat(String url) throws Exception {
|
|
||||||
return !url.contains("afcdn.net") && url.contains(".m3u8");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick) throws Exception {
|
|
||||||
return searchContent("search/" + key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
|
||||||
return searchContent("search/" + key + "/" + pg + ".html");
|
|
||||||
}
|
|
||||||
|
|
||||||
private String searchContent(String query) {
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(url + query));
|
|
||||||
for (Element div : doc.select("div.video-item")) {
|
|
||||||
String id = div.select("a.video-title").attr("href").replace(url, "");
|
|
||||||
String name = div.select("a.video-title").text();
|
|
||||||
String pic = div.select("div.thumb > a > img").attr("data-src");
|
|
||||||
String remark = div.select("div.date").text();
|
|
||||||
list.add(new Vod(id, name, pic, remark));
|
|
||||||
}
|
|
||||||
return Result.string(list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
package com.github.catvod.spider;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.github.catvod.crawler.Spider;
|
|
||||||
import com.whl.quickjs.android.QuickJSLoader;
|
|
||||||
import com.whl.quickjs.wrapper.QuickJSContext;
|
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
public class JSDemo extends Spider {
|
|
||||||
|
|
||||||
private ExecutorService executor;
|
|
||||||
private QuickJSContext ctx;
|
|
||||||
|
|
||||||
private void submit(Runnable runnable) {
|
|
||||||
executor.submit(runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> Future<T> submit(Callable<T> callable) {
|
|
||||||
return executor.submit(callable);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initJS() {
|
|
||||||
if (ctx != null) return;
|
|
||||||
ctx = QuickJSContext.create();
|
|
||||||
QuickJSLoader.initConsoleLog(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Context context, String extend) {
|
|
||||||
this.executor = Executors.newSingleThreadExecutor();
|
|
||||||
submit(this::initJS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String homeContent(boolean filter) throws Exception {
|
|
||||||
return submit(() -> {
|
|
||||||
ctx.evaluate("var text = 'homeContent';");
|
|
||||||
return ctx.getGlobalObject().getString("text");
|
|
||||||
}).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void destroy() {
|
|
||||||
submit(() -> {
|
|
||||||
executor.shutdownNow();
|
|
||||||
ctx.destroy();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
package com.github.catvod.spider;
|
|
||||||
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import com.github.catvod.bean.Class;
|
|
||||||
import com.github.catvod.bean.Result;
|
|
||||||
import com.github.catvod.bean.Vod;
|
|
||||||
import com.github.catvod.crawler.Spider;
|
|
||||||
import com.github.catvod.net.OkHttp;
|
|
||||||
import com.github.catvod.utils.Util;
|
|
||||||
|
|
||||||
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.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Qile
|
|
||||||
*/
|
|
||||||
public class Kugou extends Spider {
|
|
||||||
|
|
||||||
private Map<String, String> getHeader() {
|
|
||||||
Map<String, String> header = new HashMap<>();
|
|
||||||
header.put("User-Agent", Util.CHROME);
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String homeContent(boolean filter) throws Exception {
|
|
||||||
List<Class> classes = new ArrayList<>();
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
List<String> typeIds = Arrays.asList("6666|0", "33162|1", "4681|2");
|
|
||||||
List<String> typeNames = Arrays.asList("热门榜单", "特色音乐榜", "全球榜");
|
|
||||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
|
||||||
return Result.string(classes, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
|
||||||
HashMap<String, String> ext = new HashMap<>();
|
|
||||||
if (extend != null && extend.size() > 0) ext.putAll(extend);
|
|
||||||
String[] item = tid.split("\\|");
|
|
||||||
String id = item[0];
|
|
||||||
String digit = item[1];
|
|
||||||
int digitValue = Integer.parseInt(digit);
|
|
||||||
String cateId = ext.get("cateId") == null ? id : ext.get("cateId");
|
|
||||||
String cateUrl = String.format("https://www.kugou.com/yy/rank/home/1-%s.html?from=rank", cateId);
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(cateUrl, getHeader()));
|
|
||||||
Elements lis = doc.select(".pc_rank_sidebar").eq(digitValue).select("ul li a");
|
|
||||||
JSONArray videos = new JSONArray();
|
|
||||||
for (Element li : lis) {
|
|
||||||
String vid = li.attr("href");
|
|
||||||
String name = li.attr("title");
|
|
||||||
JSONObject vod = new JSONObject().put("vod_id", vid).put("vod_name", name);
|
|
||||||
videos.put(vod);
|
|
||||||
}
|
|
||||||
JSONObject result = new JSONObject().put("total", lis.size()).put("pagecount", 1).put("list", videos);
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String detailContent(List<String> ids) throws Exception {
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(ids.get(0), getHeader()));
|
|
||||||
Elements playlist = doc.select(".pc_temp_songlist ul li");
|
|
||||||
List<String> vodItems = new ArrayList<>();
|
|
||||||
for (int j = 0; j < playlist.size(); j++) {
|
|
||||||
Element a = playlist.get(j);
|
|
||||||
String href = a.select("a.pc_temp_songname").attr("href");
|
|
||||||
String text = a.select("a.pc_temp_songname").text();
|
|
||||||
vodItems.add(text + "$" + href);
|
|
||||||
}
|
|
||||||
String title = doc.select(".pc_temp_title h3").text();
|
|
||||||
String remark = doc.select(".rank_update").text();
|
|
||||||
String vod_play_from = "Qile";
|
|
||||||
String vod_play_url = TextUtils.join("#", vodItems);
|
|
||||||
Vod vod = new Vod();
|
|
||||||
vod.setVodId(ids.get(0));
|
|
||||||
vod.setVodName(title);
|
|
||||||
vod.setVodRemarks(remark);
|
|
||||||
vod.setVodPlayFrom(vod_play_from);
|
|
||||||
vod.setVodPlayUrl(vod_play_url);
|
|
||||||
return Result.string(vod);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
|
||||||
return Result.get().url(id).parse().header(getHeader()).string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,256 +0,0 @@
|
||||||
package com.github.catvod.spider;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Base64;
|
|
||||||
|
|
||||||
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.Crypto;
|
|
||||||
import com.github.catvod.utils.LZString;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author leospring
|
|
||||||
* 聚合直播
|
|
||||||
*/
|
|
||||||
public class Living extends Spider {
|
|
||||||
|
|
||||||
private String host = "https://lemonlive.deno.dev";
|
|
||||||
private String cookie;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Context context, String extend) throws Exception {
|
|
||||||
if (!TextUtils.isEmpty(extend)) {
|
|
||||||
host = extend;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String homeContent(boolean filter) throws Exception {
|
|
||||||
List<Class> classList = new ArrayList<>();
|
|
||||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
classList.add(new Class("huya", "虎牙"));
|
|
||||||
classList.add(new Class("douyu", "斗鱼"));
|
|
||||||
classList.add(new Class("douyin", "抖音"));
|
|
||||||
classList.add(new Class("bilibili", "哔哩哔哩"));
|
|
||||||
classList.add(new Class("cc", "网易CC"));
|
|
||||||
|
|
||||||
List<Filter> huyaFilterList = new ArrayList<>();
|
|
||||||
List<Filter.Value> huyaVals = new ArrayList<>();
|
|
||||||
huyaVals.add(new Filter.Value("网游", "1"));
|
|
||||||
huyaVals.add(new Filter.Value("手游", "3"));
|
|
||||||
huyaVals.add(new Filter.Value("娱乐", "8"));
|
|
||||||
huyaVals.add(new Filter.Value("单机", "2"));
|
|
||||||
huyaFilterList.add(new Filter("type", "分类", huyaVals));
|
|
||||||
filters.put("huya", huyaFilterList);
|
|
||||||
|
|
||||||
List<Filter> douyuFilterList = new ArrayList<>();
|
|
||||||
List<Filter.Value> douyuVals = new ArrayList<>();
|
|
||||||
douyuVals.add(new Filter.Value("网游竞技", "PCgame"));
|
|
||||||
douyuVals.add(new Filter.Value("单机热游", "djry"));
|
|
||||||
douyuVals.add(new Filter.Value("手游休闲", "syxx"));
|
|
||||||
douyuVals.add(new Filter.Value("娱乐天地", "yl"));
|
|
||||||
douyuVals.add(new Filter.Value("颜值", "yz"));
|
|
||||||
douyuVals.add(new Filter.Value("科技文化", "kjwh"));
|
|
||||||
douyuVals.add(new Filter.Value("语言互动", "yp"));
|
|
||||||
douyuFilterList.add(new Filter("type", "分类", douyuVals));
|
|
||||||
filters.put("douyu", douyuFilterList);
|
|
||||||
|
|
||||||
List<Filter> douyinFilterList = new ArrayList<>();
|
|
||||||
List<Filter.Value> douyinVals = new ArrayList<>();
|
|
||||||
douyinVals.add(new Filter.Value("竞技游戏", "2"));
|
|
||||||
douyinVals.add(new Filter.Value("射击游戏", "1"));
|
|
||||||
douyinVals.add(new Filter.Value("单机游戏", "3"));
|
|
||||||
douyinVals.add(new Filter.Value("棋牌游戏", "4"));
|
|
||||||
douyinVals.add(new Filter.Value("休闲益智", "5"));
|
|
||||||
douyinVals.add(new Filter.Value("角色扮演", "6"));
|
|
||||||
douyinVals.add(new Filter.Value("策略卡牌", "7"));
|
|
||||||
douyinVals.add(new Filter.Value("娱乐天地", "10000"));
|
|
||||||
douyinVals.add(new Filter.Value("科技文化", "10001"));
|
|
||||||
douyinFilterList.add(new Filter("type", "分类", douyinVals));
|
|
||||||
filters.put("douyin", douyinFilterList);
|
|
||||||
|
|
||||||
List<Filter> biliFilterList = new ArrayList<>();
|
|
||||||
List<Filter.Value> biliVals = new ArrayList<>();
|
|
||||||
biliVals.add(new Filter.Value("网游", "2"));
|
|
||||||
biliVals.add(new Filter.Value("手游", "3"));
|
|
||||||
biliVals.add(new Filter.Value("单机游戏", "6"));
|
|
||||||
biliVals.add(new Filter.Value("娱乐", "1"));
|
|
||||||
biliVals.add(new Filter.Value("电台", "5"));
|
|
||||||
biliVals.add(new Filter.Value("虚拟主播", "9"));
|
|
||||||
biliVals.add(new Filter.Value("聊天室", "14"));
|
|
||||||
biliVals.add(new Filter.Value("生活", "10"));
|
|
||||||
biliVals.add(new Filter.Value("知识", "11"));
|
|
||||||
biliVals.add(new Filter.Value("赛事", "13"));
|
|
||||||
biliVals.add(new Filter.Value("互动玩法", "15"));
|
|
||||||
biliFilterList.add(new Filter("type", "分类", biliVals));
|
|
||||||
filters.put("bilibili", biliFilterList);
|
|
||||||
|
|
||||||
List<Filter> ccFilterList = new ArrayList<>();
|
|
||||||
List<Filter.Value> ccVals = new ArrayList<>();
|
|
||||||
ccVals.add(new Filter.Value("网游", "1"));
|
|
||||||
ccVals.add(new Filter.Value("手游", "2"));
|
|
||||||
ccVals.add(new Filter.Value("竞技", "4"));
|
|
||||||
ccVals.add(new Filter.Value("综艺", "5"));
|
|
||||||
ccFilterList.add(new Filter("type", "分类", ccVals));
|
|
||||||
filters.put("cc", ccFilterList);
|
|
||||||
return Result.string(classList, filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
|
||||||
if (!tid.contains("_")) {
|
|
||||||
String url = host + "/api/" + tid + "/getCategories";
|
|
||||||
JSONObject json = request(url);
|
|
||||||
String type = extend.get("type");
|
|
||||||
if (TextUtils.isEmpty(type)) type = json.optJSONArray("data").optJSONObject(0).optString("id");
|
|
||||||
List<Vod> vodList = new ArrayList<>();
|
|
||||||
for (int i = 0; i < json.optJSONArray("data").length(); i++) {
|
|
||||||
JSONObject data = json.optJSONArray("data").optJSONObject(i);
|
|
||||||
if (type.equals(data.optString("id"))) {
|
|
||||||
for (int j = 0; j < data.optJSONArray("list").length(); j++) {
|
|
||||||
JSONObject item = data.optJSONArray("list").optJSONObject(j);
|
|
||||||
vodList.add(new Vod(tid + "_" + item.optString("cid"), item.optString("name"), item.optString("pic"), data.optString("name"), true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Result.string(vodList);
|
|
||||||
} else {
|
|
||||||
String[] split = tid.split("_");
|
|
||||||
String url = host + "/api/" + split[0] + "/getCategoryRooms?id=" + split[1] + "&pid=" + (split[0].equals("bilibili") ? "2" : "1") + "&page=" + pg;
|
|
||||||
if (!TextUtils.isEmpty(cookie)) {
|
|
||||||
url = url + "&cookie=" + URLDecoder.decode(cookie, "UTF-8");
|
|
||||||
}
|
|
||||||
JSONObject json = request(url);
|
|
||||||
if (!TextUtils.isEmpty(json.optJSONObject("data").optString("cookie"))) {
|
|
||||||
cookie = json.optJSONObject("data").optString("cookie");
|
|
||||||
}
|
|
||||||
List<Vod> vodList = new ArrayList<>();
|
|
||||||
for (int i = 0; i < json.optJSONObject("data").optJSONArray("list").length(); i++) {
|
|
||||||
JSONObject data = json.optJSONObject("data").optJSONArray("list").optJSONObject(i);
|
|
||||||
vodList.add(new Vod(split[0] + "_" + data.optString("roomId"), data.optString("title"), data.optString("cover"), data.optString("nickname")));
|
|
||||||
}
|
|
||||||
return Result.string(vodList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String detailContent(List<String> ids) throws Exception {
|
|
||||||
String[] split = ids.get(0).split("_");
|
|
||||||
String url = host + "/api/" + split[0] + "/getRoomDetail?id=" + split[1];
|
|
||||||
JSONObject json = request(url).optJSONObject("data");
|
|
||||||
Vod vod = new Vod();
|
|
||||||
vod.setVodId(json.optString("roomId"));
|
|
||||||
vod.setVodName(json.optString("title"));
|
|
||||||
vod.setVodArea(json.optString("online"));
|
|
||||||
vod.setVodDirector(json.optString("siteId"));
|
|
||||||
vod.setVodActor(json.optString("nickname"));
|
|
||||||
vod.setVodPic(json.optString("cover"));
|
|
||||||
vod.setVodContent(json.optString("url"));
|
|
||||||
vod.setTypeName(json.optString("category"));
|
|
||||||
JSONObject info = json.optJSONObject("info");
|
|
||||||
String params = "";
|
|
||||||
if (info != null) {
|
|
||||||
params = getHuyaParam(info.optString("name"), info.optString("code"));
|
|
||||||
}
|
|
||||||
List<String> fromList = new ArrayList<>();
|
|
||||||
List<String> playList = new ArrayList<>();
|
|
||||||
for (int i = 0; i < json.optJSONArray("stream").length(); i++) {
|
|
||||||
JSONObject data = json.optJSONArray("stream").optJSONObject(i);
|
|
||||||
fromList.add(data.optString("name"));
|
|
||||||
List<String> nameUrls = new ArrayList<>();
|
|
||||||
for (int j = 0; j < data.optJSONArray("lines").length(); j++) {
|
|
||||||
JSONObject urls = data.optJSONArray("lines").optJSONObject(j);
|
|
||||||
String playUrl = urls.optString("url") + params;
|
|
||||||
nameUrls.add(urls.optString("name") + "$" + playUrl);
|
|
||||||
}
|
|
||||||
playList.add(TextUtils.join("#", nameUrls));
|
|
||||||
}
|
|
||||||
vod.setVodPlayFrom(TextUtils.join("$$$", fromList));
|
|
||||||
vod.setVodPlayUrl(TextUtils.join("$$$", playList));
|
|
||||||
return Result.string(vod);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
|
||||||
if (!id.startsWith("http")) id = "https:" + id;
|
|
||||||
return Result.get().url(id).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick) throws Exception {
|
|
||||||
return searchContent(key, quick, "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
|
||||||
List<Vod> vodList = new ArrayList<>();
|
|
||||||
vodList.addAll(searchWithSite("huya", key, pg));
|
|
||||||
vodList.addAll(searchWithSite("douyu", key, pg));
|
|
||||||
vodList.addAll(searchWithSite("douyin", key, pg));
|
|
||||||
vodList.addAll(searchWithSite("bilibili", key, pg));
|
|
||||||
return Result.string(vodList);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getSiteNameByEn(String en) {
|
|
||||||
return Objects.equals(en, "huya") ? "虎牙"
|
|
||||||
: Objects.equals(en, "douyu") ? "斗鱼"
|
|
||||||
: Objects.equals(en, "douyin") ? "抖音"
|
|
||||||
: Objects.equals(en, "bilibili") ? "哔哩哔哩"
|
|
||||||
: Objects.equals(en, "cc") ? "网易CC" : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Vod> searchWithSite(String site, String key, String pg) {
|
|
||||||
try {
|
|
||||||
List<Vod> vodList = new ArrayList<>();
|
|
||||||
String url = host + "/api/" + site + "/searchRooms?page=" + pg + "&kw=" + key;
|
|
||||||
JSONArray jsonArray = request(url).optJSONObject("data").optJSONArray("list");
|
|
||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
|
||||||
JSONObject item = jsonArray.getJSONObject(i);
|
|
||||||
vodList.add(new Vod(site + "_" + item.optString("roomId"), item.optString("nickname"), item.optString("cover"), getSiteNameByEn(site) + "/" + item.optString("category") + "/" + item.optString("title"), false));
|
|
||||||
}
|
|
||||||
return vodList;
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getHuyaParam(String name, String code) throws UnsupportedEncodingException {
|
|
||||||
String N = "1063681129617";
|
|
||||||
long currentTimeMillis = System.currentTimeMillis();
|
|
||||||
String i = String.valueOf(currentTimeMillis % 10000000000L * 1000 + (long) (Math.random() * 4294967295L));
|
|
||||||
String r = code.split("fs=")[1].split("&")[0];
|
|
||||||
String s = Long.toHexString((currentTimeMillis / 1000) | 21600);
|
|
||||||
String f = String.valueOf(currentTimeMillis + Long.parseLong(N));
|
|
||||||
String fmPart = code.split("fm=")[1].split("&")[0];
|
|
||||||
String c = new String(Base64.decode(URLDecoder.decode(fmPart, "UTF-8"), Base64.NO_WRAP)).split("_")[0];
|
|
||||||
String u = Crypto.md5(f + "|tars_mp|102");
|
|
||||||
return String.format("&wsSecret=%s&uuid=%s&wsTime=%s&uid=%s&seqid=%s&fs=%s&ctype=tars_mp&t=102&ver=1&sv=2401310321", Crypto.md5(c + "_" + N + "_" + name + "_" + u + "_" + s), i, s, N, f, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JSONObject request(String url) throws JSONException {
|
|
||||||
HashMap<String, String> map = new HashMap<>();
|
|
||||||
map.put("sec-fetch-site", "same-origin");
|
|
||||||
String str = OkHttp.string(url, map);
|
|
||||||
String result = LZString.decompressFromBase64(str.replaceAll(" ", ""));
|
|
||||||
return new JSONObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -27,7 +27,7 @@ import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class PTT extends Spider {
|
public class PTT extends Spider {
|
||||||
|
|
||||||
private String url = "https://ptt.red/";
|
private final String url = "https://ptt.red/";
|
||||||
private String extend;
|
private String extend;
|
||||||
|
|
||||||
private Map<String, String> getHeader() {
|
private Map<String, String> getHeader() {
|
||||||
|
|
|
||||||
|
|
@ -1,189 +0,0 @@
|
||||||
package com.github.catvod.spider;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.github.catvod.bean.Class;
|
|
||||||
import com.github.catvod.bean.Result;
|
|
||||||
import com.github.catvod.bean.Vod;
|
|
||||||
import com.github.catvod.bean.uvod.Data;
|
|
||||||
import com.github.catvod.crawler.Spider;
|
|
||||||
import com.github.catvod.net.OkHttp;
|
|
||||||
import com.github.catvod.utils.Crypto;
|
|
||||||
import com.github.catvod.utils.Util;
|
|
||||||
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Qile
|
|
||||||
* @date 2024/11/15
|
|
||||||
*/
|
|
||||||
public class Uvod extends Spider {
|
|
||||||
|
|
||||||
private static String siteUrl = "https://api-h5.uvod.tv";
|
|
||||||
private static final String latest = siteUrl + "/video/latest";
|
|
||||||
private static final String list = siteUrl + "/video/list";
|
|
||||||
private static final String detail = siteUrl + "/video/info";
|
|
||||||
private static final String play = siteUrl + "/video/source";
|
|
||||||
private static final String publicKeyPem = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeBQWotWOpsuPn3PAA+bcmM8YD\n" + "fEOzPz7hb/vItV43vBJV2FcM72Hdcv3DccIFuEV9LQ8vcmuetld98eksja9vQ1Ol\n" + "8rTnjpTpMbd4HedevSuIhWidJdMAOJKDE3AgGFcQvQePs80uXY2JhTLkRn2ICmDR\n" + "/fb32OwWY3QGOvLcuQIDAQAB\n" + "-----END PUBLIC KEY-----";
|
|
||||||
private static final String privateKeyPem = "-----BEGIN PRIVATE KEY-----\n" + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ4FBai1Y6my4+fc\n" + "8AD5tyYzxgN8Q7M/PuFv+8i1Xje8ElXYVwzvYd1y/cNxwgW4RX0tDy9ya562V33x\n" + "6SyNr29DU6XytOeOlOkxt3gd5169K4iFaJ0l0wA4koMTcCAYVxC9B4+zzS5djYmF\n" + "MuRGfYgKYNH99vfY7BZjdAY68ty5AgMBAAECgYB1rbvHJj5wVF7Rf4Hk2BMDCi9+\n" + "zP4F8SW88Y6KrDbcPt1QvOonIea56jb9ZCxf4hkt3W6foRBwg86oZo2FtoZcpCJ+\n" + "rFqUM2/wyV4CuzlL0+rNNSq7bga7d7UVld4hQYOCffSMifyF5rCFNH1py/4Dvswm\n" + "pi5qljf+dPLSlxXl2QJBAMzPJ/QPAwcf5K5nngQtbZCD3nqDFpRixXH4aUAIZcDz\n" + "S1RNsHrT61mEwZ/thQC2BUJTQNpGOfgh5Ecd1MnURwsCQQDFhAFfmvK7svkygoKX\n" + "t55ARNZy9nmme0StMOfdb4Q2UdJjfw8+zQNtKFOM7VhB7ijHcfFuGsE7UeXBe20n\n" + "g/XLAkEAv9SoT2hgJaQxxUk4MCF8pgddstJlq8Z3uTA7JMa4x+kZfXTm/6TOo6I8\n" + "2VbXZLsYYe8op0lvsoHMFvBSBljV0QJBAKhxyoYRa98dZB5qZRskciaXTlge0WJk\n" + "kA4vvh3/o757izRlQMgrKTfng1GVfIZFqKtnBiIDWTXQw2N9cnqXtH8CQAx+CD5t\n" + "l1iT0cMdjvlMg2two3SnpOjpo7gALgumIDHAmsUWhocLtcrnJI032VQSUkNnLq9z\n" + "EIfmHDz0TPVNHBQ=\n" + "-----END PRIVATE KEY-----";
|
|
||||||
|
|
||||||
private Map<String, String> getHeader(String url) {
|
|
||||||
String[] item = url.split("\\|");
|
|
||||||
String URL = item[0];
|
|
||||||
String tid = item.length > 1 ? item[1] : "";
|
|
||||||
String pg = item.length > 2 ? item[2] : "";
|
|
||||||
String quality = item.length > 3 ? item[3] : "";
|
|
||||||
String hm = String.valueOf(System.currentTimeMillis());
|
|
||||||
String text = "";
|
|
||||||
if (URL.equals(latest)) {
|
|
||||||
text = String.format("-parent_category_id=101-%s", hm);
|
|
||||||
} else if (URL.equals(list)) {
|
|
||||||
if (pg != null && !pg.isEmpty()) {
|
|
||||||
text = String.format("-page=%s&pagesize=42&parent_category_id=%s&sort_type=asc-%s", pg, tid, hm);
|
|
||||||
} else {
|
|
||||||
text = String.format("-keyword=%s&need_fragment=1&page=1&pagesize=42&sort_type=asc-%s", URLEncoder.encode(tid).toLowerCase(), hm);
|
|
||||||
}
|
|
||||||
} else if (URL.equals(detail)) {
|
|
||||||
text = String.format("-id=%s-%s", tid, hm);
|
|
||||||
} else if (URL.equals(play)) {
|
|
||||||
text = String.format("-quality=%s&video_fragment_id=%s&video_id=%s-%s", quality, pg, tid, hm);
|
|
||||||
}
|
|
||||||
String sign = Crypto.md5(text);
|
|
||||||
Map<String, String> header = new HashMap<>();
|
|
||||||
header.put("User-Agent", Util.CHROME);
|
|
||||||
header.put("referer", "https://www.uvod.tv/");
|
|
||||||
header.put("origin", "https://www.uvod.tv");
|
|
||||||
header.put("content-type", "application/json");
|
|
||||||
header.put("accept", "*/*");
|
|
||||||
header.put("x-signature", sign);
|
|
||||||
header.put("x-timestamp", hm);
|
|
||||||
header.put("x-token", "");
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> playHeader() {
|
|
||||||
Map<String, String> header = new HashMap<>();
|
|
||||||
header.put("User-Agent", Util.CHROME);
|
|
||||||
header.put("referer", "https://www.uvod.tv/");
|
|
||||||
header.put("origin", "https://www.uvod.tv");
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Context context, String extend) throws Exception {
|
|
||||||
if (!extend.isEmpty()) siteUrl = extend;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String encrypt(String data) throws Exception {
|
|
||||||
String aesKey = Crypto.randomKey(32);
|
|
||||||
String aesEncryptedData = Crypto.aesEncrypt(data, aesKey, "abcdefghijklmnop");
|
|
||||||
String rsaEncryptedKey = Crypto.rsaEncrypt(aesKey, publicKeyPem);
|
|
||||||
return aesEncryptedData + "." + rsaEncryptedKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String decrypt(String encryptedData) throws Exception {
|
|
||||||
encryptedData = encryptedData.replaceAll("\\s", "");
|
|
||||||
String[] parts = encryptedData.split("\\.");
|
|
||||||
if (parts.length != 2) return null;
|
|
||||||
String rsaEncryptedKey = parts[1];
|
|
||||||
String decryptedKey = Crypto.rsaDecrypt(rsaEncryptedKey, privateKeyPem);
|
|
||||||
String aesEncryptedData = parts[0];
|
|
||||||
return Crypto.CBC(aesEncryptedData, decryptedKey, "abcdefghijklmnop");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String homeContent(boolean filter) throws Exception {
|
|
||||||
List<Class> classes = new ArrayList<>();
|
|
||||||
List<String> typeIds = Arrays.asList("101", "100", "106", "102", "103", "104", "105");
|
|
||||||
List<String> typeNames = Arrays.asList("电视剧", "电影", "粤台专区", "综艺", "动漫", "体育", "纪录片");
|
|
||||||
for (int i = 0; i < typeIds.size(); i++) classes.add(new Class(typeIds.get(i), typeNames.get(i)));
|
|
||||||
String param = "{\"parent_category_id\":101}";
|
|
||||||
String encryptData = encrypt(param);
|
|
||||||
String content = OkHttp.post(latest, encryptData, getHeader(latest)).getBody();
|
|
||||||
String decryptData = decrypt(content);
|
|
||||||
Data data = Data.objectFrom(decryptData);
|
|
||||||
return Result.string(classes, data.getList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
|
||||||
String param = String.format("{\"parent_category_id\":\"%s\",\"category_id\":null,\"language\":null,\"year\":null,\"region\":null,\"state\":null,\"keyword\":\"\",\"paid\":null,\"page\":%s,\"pagesize\":42,\"sort_field\":\"\",\"sort_type\":\"asc\"}", tid, pg);
|
|
||||||
String encryptData = encrypt(param);
|
|
||||||
String content = OkHttp.post(list, encryptData, getHeader(list + "|" + tid + "|" + pg)).getBody();
|
|
||||||
String decryptData = decrypt(content);
|
|
||||||
Data data = Data.objectFrom(decryptData);
|
|
||||||
return Result.string(data.getList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String detailContent(List<String> ids) throws Exception {
|
|
||||||
String param = String.format("{\"id\":\"%s\"}", ids.get(0));
|
|
||||||
String encryptData = encrypt(param);
|
|
||||||
String content = OkHttp.post(detail, encryptData, getHeader(detail + "|" + ids.get(0))).getBody();
|
|
||||||
String decryptData = decrypt(content);
|
|
||||||
Data data = Data.objectFrom(decryptData);
|
|
||||||
StringBuilder vod_play_url = new StringBuilder();
|
|
||||||
List<Data.VideoFragmentList> videoFragmentList = data.getVideoFragmentList();
|
|
||||||
for (int j = 0; j < videoFragmentList.size(); j++) {
|
|
||||||
Data.VideoFragmentList videoList = videoFragmentList.get(j);
|
|
||||||
String name = videoList.getSymbol();
|
|
||||||
String nid = videoList.getId();
|
|
||||||
List<Integer> Qualities = videoList.getQualities();
|
|
||||||
nid = ids.get(0) + "|" + nid + "|" + Qualities;
|
|
||||||
vod_play_url.append(name).append("$").append(nid);
|
|
||||||
boolean notLastEpisode = j < videoFragmentList.size() - 1;
|
|
||||||
vod_play_url.append(notLastEpisode ? "#" : "$$$");
|
|
||||||
}
|
|
||||||
Data.Video video = data.getVideo();
|
|
||||||
Vod vod = new Vod();
|
|
||||||
vod.setVodId(ids.get(0));
|
|
||||||
vod.setVodYear(video.getYear());
|
|
||||||
vod.setVodArea(video.getRegion());
|
|
||||||
vod.setVodActor(video.getStarring());
|
|
||||||
vod.setVodRemarks(video.getState());
|
|
||||||
vod.setVodContent(video.getDescription());
|
|
||||||
vod.setVodDirector(video.getDirector());
|
|
||||||
vod.setTypeName(video.getLanguage());
|
|
||||||
vod.setVodPlayFrom("Qile");
|
|
||||||
vod.setVodPlayUrl(vod_play_url.toString());
|
|
||||||
return Result.string(vod);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick) throws Exception {
|
|
||||||
String param = String.format("{\"parent_category_id\":null,\"category_id\":null,\"language\":null,\"year\":null,\"region\":null,\"state\":null,\"keyword\":\"%s\",\"paid\":null,\"page\":1,\"pagesize\":42,\"sort_field\":\"\",\"sort_type\":\"asc\",\"need_fragment\":1}", key);
|
|
||||||
String encryptData = encrypt(param);
|
|
||||||
String content = OkHttp.post(list, encryptData, getHeader(list + "|" + key)).getBody();
|
|
||||||
String decryptData = decrypt(content);
|
|
||||||
Data data = Data.objectFrom(decryptData);
|
|
||||||
return Result.string(data.getList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
|
||||||
String[] item = id.split("\\|");
|
|
||||||
String tid = item[0];
|
|
||||||
String nid = item[1];
|
|
||||||
String[] quality = item[2].replaceAll("[\\[\\]]", "").replace(" ", "").split(",");
|
|
||||||
List<String> url = new ArrayList<>();
|
|
||||||
for (String s : quality) {
|
|
||||||
if (s.equals("4")) url.add("1080p");
|
|
||||||
else if (s.equals("3")) url.add("720p");
|
|
||||||
else if (s.equals("2")) url.add("480p");
|
|
||||||
else if (s.equals("1")) url.add("360p");
|
|
||||||
else url.add(s.trim());
|
|
||||||
String param = String.format("{\"video_id\":\"%s\",\"video_fragment_id\":%s,\"quality\":%s,\"seek\":null}", tid, nid, s.trim());
|
|
||||||
String encryptData = encrypt(param);
|
|
||||||
String content = OkHttp.post(play, encryptData, getHeader(play + "|" + tid + "|" + nid + "|" + s.trim())).getBody();
|
|
||||||
String decryptData = decrypt(content);
|
|
||||||
Data data = Data.objectFrom(decryptData);
|
|
||||||
url.add(data.getVideo().getUrl());
|
|
||||||
}
|
|
||||||
return Result.get().url(url).header(playHeader()).string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -41,7 +41,7 @@ public class XPath extends Spider {
|
||||||
fetchRule();
|
fetchRule();
|
||||||
List<Vod> list = new ArrayList<>();
|
List<Vod> list = new ArrayList<>();
|
||||||
List<Class> classes = new ArrayList<>();
|
List<Class> classes = new ArrayList<>();
|
||||||
if (rule.getCateManual().size() > 0) {
|
if (!rule.getCateManual().isEmpty()) {
|
||||||
Set<String> keys = rule.getCateManual().keySet();
|
Set<String> keys = rule.getCateManual().keySet();
|
||||||
for (String k : keys) {
|
for (String k : keys) {
|
||||||
classes.add(new Class(rule.getCateManual().get(k), k));
|
classes.add(new Class(rule.getCateManual().get(k), k));
|
||||||
|
|
@ -49,7 +49,7 @@ public class XPath extends Spider {
|
||||||
}
|
}
|
||||||
String webUrl = rule.getHomeUrl();
|
String webUrl = rule.getHomeUrl();
|
||||||
JXDocument doc = JXDocument.create(fetch(webUrl));
|
JXDocument doc = JXDocument.create(fetch(webUrl));
|
||||||
if (rule.getCateManual().size() == 0) {
|
if (rule.getCateManual().isEmpty()) {
|
||||||
List<JXNode> navNodes = doc.selN(rule.getCateNode());
|
List<JXNode> navNodes = doc.selN(rule.getCateNode());
|
||||||
for (int i = 0; i < navNodes.size(); i++) {
|
for (int i = 0; i < navNodes.size(); i++) {
|
||||||
String name = navNodes.get(i).selOne(rule.getCateName()).asString().trim();
|
String name = navNodes.get(i).selOne(rule.getCateName()).asString().trim();
|
||||||
|
|
@ -220,7 +220,7 @@ public class XPath extends Spider {
|
||||||
vodItems.add(name + "$" + id);
|
vodItems.add(name + "$" + id);
|
||||||
}
|
}
|
||||||
// 排除播放列表為空的播放源
|
// 排除播放列表為空的播放源
|
||||||
if (vodItems.size() == 0 && playFrom.size() > i) {
|
if (vodItems.isEmpty() && playFrom.size() > i) {
|
||||||
playFrom.set(i, "");
|
playFrom.set(i, "");
|
||||||
}
|
}
|
||||||
playList.add(TextUtils.join("#", vodItems));
|
playList.add(TextUtils.join("#", vodItems));
|
||||||
|
|
@ -246,8 +246,8 @@ public class XPath extends Spider {
|
||||||
String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id);
|
String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id);
|
||||||
SpiderDebug.log(webUrl);
|
SpiderDebug.log(webUrl);
|
||||||
HashMap<String, String> headers = new HashMap<>();
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
if (rule.getPlayUa().length() > 0) headers.put("User-Agent", rule.getPlayUa());
|
if (!rule.getPlayUa().isEmpty()) headers.put("User-Agent", rule.getPlayUa());
|
||||||
if (rule.getPlayReferer().length() > 0) headers.put("Referer", rule.getPlayReferer());
|
if (!rule.getPlayReferer().isEmpty()) headers.put("Referer", rule.getPlayReferer());
|
||||||
return Result.get().parse().url(webUrl).header(headers).string();
|
return Result.get().parse().url(webUrl).header(headers).string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.github.catvod.spider;
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
@ -15,10 +17,10 @@ public class XPathFilter extends XPath {
|
||||||
@Override
|
@Override
|
||||||
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
String cateUrl = rule.getCateUrl();
|
String cateUrl = rule.getCateUrl();
|
||||||
if (filter && extend != null && extend.size() > 0) {
|
if (filter && extend != null && !extend.isEmpty()) {
|
||||||
for (String key : extend.keySet()) {
|
for (String key : extend.keySet()) {
|
||||||
String value = extend.get(key);
|
String value = extend.get(key);
|
||||||
if (value.length() > 0) {
|
if (!TextUtils.isEmpty(value)) {
|
||||||
cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value));
|
cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ public class XPathMac extends XPath {
|
||||||
@Override
|
@Override
|
||||||
public String homeContent(boolean filter) {
|
public String homeContent(boolean filter) {
|
||||||
String result = super.homeContent(filter);
|
String result = super.homeContent(filter);
|
||||||
if (result.length() > 0 && playerConfigJs.length() > 0) { // 嘗試通過playerConfigJs獲取展示和flag匹配關系
|
if (!result.isEmpty() && !playerConfigJs.isEmpty()) { // 嘗試通過playerConfigJs獲取展示和flag匹配關系
|
||||||
String webContent = fetch(playerConfigJs);
|
String webContent = fetch(playerConfigJs);
|
||||||
Matcher matcher = Pattern.compile(playerConfigJsRegex).matcher(webContent);
|
Matcher matcher = Pattern.compile(playerConfigJsRegex).matcher(webContent);
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
|
|
@ -94,7 +94,7 @@ public class XPathMac extends XPath {
|
||||||
@Override
|
@Override
|
||||||
public String detailContent(List<String> ids) {
|
public String detailContent(List<String> ids) {
|
||||||
String result = super.detailContent(ids);
|
String result = super.detailContent(ids);
|
||||||
if (decodeVipFlag && result.length() > 0) {
|
if (decodeVipFlag && !result.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
JSONObject jsonObject = new JSONObject(result);
|
JSONObject jsonObject = new JSONObject(result);
|
||||||
String[] playFrom = jsonObject.optJSONArray("list").getJSONObject(0).optString("vod_play_from").split("\\$\\$\\$");
|
String[] playFrom = jsonObject.optJSONArray("list").getJSONObject(0).optString("vod_play_from").split("\\$\\$\\$");
|
||||||
|
|
@ -181,8 +181,8 @@ public class XPathMac extends XPath {
|
||||||
result.put("playUrl", "");
|
result.put("playUrl", "");
|
||||||
result.put("url", videoUrl);
|
result.put("url", videoUrl);
|
||||||
HashMap<String, String> headers = new HashMap<>();
|
HashMap<String, String> headers = new HashMap<>();
|
||||||
if (rule.getPlayUa().length() > 0) headers.put("User-Agent", rule.getPlayUa());
|
if (!rule.getPlayUa().isEmpty()) headers.put("User-Agent", rule.getPlayUa());
|
||||||
if (rule.getPlayReferer().length() > 0) headers.put("Referer", rule.getPlayReferer());
|
if (!rule.getPlayReferer().isEmpty()) headers.put("Referer", rule.getPlayReferer());
|
||||||
result.put("header", new Gson().toJson(headers));
|
result.put("header", new Gson().toJson(headers));
|
||||||
return result.toString();
|
return result.toString();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.github.catvod.spider;
|
package com.github.catvod.spider;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
@ -10,10 +12,10 @@ public class XPathMacFilter extends XPathMac {
|
||||||
@Override
|
@Override
|
||||||
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
protected String categoryUrl(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||||
String cateUrl = rule.getCateUrl();
|
String cateUrl = rule.getCateUrl();
|
||||||
if (filter && extend != null && extend.size() > 0) {
|
if (filter && extend != null && !extend.isEmpty()) {
|
||||||
for (String key : extend.keySet()) {
|
for (String key : extend.keySet()) {
|
||||||
String value = extend.get(key);
|
String value = extend.get(key);
|
||||||
if (value.length() > 0) {
|
if (!TextUtils.isEmpty(value)) {
|
||||||
cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value));
|
cateUrl = cateUrl.replace("{" + key + "}", URLEncoder.encode(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,244 +0,0 @@
|
||||||
package com.github.catvod.spider;
|
|
||||||
|
|
||||||
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.Util;
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup;
|
|
||||||
import org.jsoup.nodes.Document;
|
|
||||||
import org.jsoup.nodes.Element;
|
|
||||||
import org.jsoup.select.Elements;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import okhttp3.FormBody;
|
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.RequestBody;
|
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author zhixc
|
|
||||||
* 新版6V电影网
|
|
||||||
*/
|
|
||||||
public class Xb6v extends Spider {
|
|
||||||
|
|
||||||
private final String siteUrl = "https://www.xb6v.com";
|
|
||||||
private String nextSearchUrlPrefix;
|
|
||||||
private String nextSearchUrlSuffix;
|
|
||||||
|
|
||||||
private Map<String, String> getHeader() {
|
|
||||||
Map<String, String> header = new HashMap<>();
|
|
||||||
header.put("User-Agent", Util.CHROME);
|
|
||||||
header.put("Referer", siteUrl + "/");
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> getDetailHeader() {
|
|
||||||
Map<String, String> header = new HashMap<>();
|
|
||||||
header.put("User-Agent", Util.CHROME);
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String homeContent(boolean filter) throws Exception {
|
|
||||||
List<Class> classes = new ArrayList<>();
|
|
||||||
String html = OkHttp.string(siteUrl, getHeader());
|
|
||||||
Document doc = Jsoup.parse(html);
|
|
||||||
Elements elements = doc.select("#menus > li > a");
|
|
||||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
|
||||||
for (int i = 0; i < elements.size(); i++) {
|
|
||||||
if (i < 2 || i == elements.size() - 1) continue;
|
|
||||||
Element e = elements.get(i);
|
|
||||||
String typeId = e.attr("href");
|
|
||||||
String typeName = e.text();
|
|
||||||
if (typeName.equals("电视剧")) {
|
|
||||||
List<Filter.Value> values = new ArrayList<>();
|
|
||||||
values.add(new Filter.Value("不限", ""));
|
|
||||||
for (Element a : e.nextElementSibling().select("a")) {
|
|
||||||
values.add(new Filter.Value(a.text(), a.attr("href").replaceAll(typeId, "")));
|
|
||||||
}
|
|
||||||
List<Filter> filterList = new ArrayList<>();
|
|
||||||
filterList.add(new Filter("cateId", "类型", values));
|
|
||||||
filters.put(typeId, filterList);
|
|
||||||
}
|
|
||||||
classes.add(new Class(typeId, typeName));
|
|
||||||
}
|
|
||||||
return Result.string(classes, parseVodListFromDoc(doc), filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Vod> parseVodListFromDoc(String html) {
|
|
||||||
return parseVodListFromDoc(Jsoup.parse(html));
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Vod> parseVodListFromDoc(Document doc) {
|
|
||||||
Elements items = doc.select("#post_container .post_hover");
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
for (Element item : items) {
|
|
||||||
Element element = item.select("[class=zoom]").get(0);
|
|
||||||
String vodId = element.attr("href");
|
|
||||||
String name = element.attr("title").replaceAll("</?[^>]+>", "");
|
|
||||||
String pic = element.select("img").attr("src");
|
|
||||||
String remark = item.select("[rel=category tag]").text();
|
|
||||||
list.add(new Vod(vodId, name, pic, remark));
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {
|
|
||||||
String cateId = extend.get("cateId") == null ? "" : extend.get("cateId");
|
|
||||||
String cateUrl = siteUrl + tid + cateId;
|
|
||||||
if (!pg.equals("1")) cateUrl += "index_" + pg + ".html";
|
|
||||||
String html = OkHttp.string(cateUrl, getHeader());
|
|
||||||
Document doc = Jsoup.parse(html);
|
|
||||||
String href = doc.select(".pagination > a").last().attr("href");
|
|
||||||
int page = Integer.parseInt(pg);
|
|
||||||
int count = Integer.parseInt(getStrByRegex(Pattern.compile("index_(.*?).html"), href));
|
|
||||||
int limit = 18;
|
|
||||||
Elements items = doc.select("#post_container .post_hover");
|
|
||||||
int total = page == count ? (page - 1) * limit + items.size() : count * limit;
|
|
||||||
return Result.get().vod(parseVodListFromDoc(doc)).page(page, count, limit, total).string();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String detailContent(List<String> ids) throws Exception {
|
|
||||||
String vodId = ids.get(0);
|
|
||||||
String detailUrl = siteUrl + vodId;
|
|
||||||
String html = OkHttp.string(detailUrl, getDetailHeader());
|
|
||||||
Document doc = Jsoup.parse(html);
|
|
||||||
Elements sourceList = doc.select("#post_content");
|
|
||||||
|
|
||||||
String circuitName = "磁力线路";
|
|
||||||
Map<String, String> playMap = new LinkedHashMap<>();
|
|
||||||
int i = 0;
|
|
||||||
for (Element source : sourceList) {
|
|
||||||
Elements aList = source.select("table a");
|
|
||||||
List<String> vodItems = new ArrayList<>();
|
|
||||||
for (Element a : aList) {
|
|
||||||
String episodeUrl = a.attr("href");
|
|
||||||
String episodeName = a.text();
|
|
||||||
if (!episodeUrl.toLowerCase().startsWith("magnet")) continue;
|
|
||||||
vodItems.add(episodeName + "$" + episodeUrl);
|
|
||||||
}
|
|
||||||
if (vodItems.size() > 0) {
|
|
||||||
i++;
|
|
||||||
playMap.put(circuitName + i, TextUtils.join("#", vodItems));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String partHTML = doc.select(".context").html();
|
|
||||||
String name = doc.select(".article_container > h1").text();
|
|
||||||
String pic = doc.select("#post_content img").attr("src");
|
|
||||||
String typeName = getStrByRegex(Pattern.compile("◎类 别 (.*?)<br>"), partHTML);
|
|
||||||
if (typeName.equals("")) typeName = doc.select("[rel=category tag]").text();
|
|
||||||
String year = getStrByRegex(Pattern.compile("◎年 代 (.*?)<br>"), partHTML);
|
|
||||||
if (year.equals("")) year = getStrByRegex(Pattern.compile("首播:(.*?)<br>"), partHTML);
|
|
||||||
String area = getStrByRegex(Pattern.compile("◎产 地 (.*?)<br>"), partHTML);
|
|
||||||
if (area.equals("")) area = getStrByRegex(Pattern.compile("地区:(.*?)<br>"), partHTML);
|
|
||||||
String remark = getStrByRegex(Pattern.compile("◎上映日期 (.*?)<br>"), partHTML);
|
|
||||||
String actor = getActorOrDirector(Pattern.compile("◎演 员 (.*?)</p>"), partHTML);
|
|
||||||
if (actor.equals("")) actor = getActorOrDirector(Pattern.compile("◎主 演 (.*?)</p>"), partHTML);
|
|
||||||
if (actor.equals("")) actor = getActorOrDirector(Pattern.compile("主演:(.*?)<br>"), partHTML);
|
|
||||||
String director = getActorOrDirector(Pattern.compile("◎导 演 (.*?)<br>"), partHTML);
|
|
||||||
if (director.equals("")) director = getActorOrDirector(Pattern.compile("导演:(.*?)<br>"), partHTML);
|
|
||||||
String description = getDescription(Pattern.compile("◎简 介(.*?)<hr>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL), partHTML);
|
|
||||||
if (description.equals("")) description = getDescription(Pattern.compile("简介(.*?)</p>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL), partHTML);
|
|
||||||
|
|
||||||
Vod vod = new Vod();
|
|
||||||
vod.setVodId(ids.get(0));
|
|
||||||
vod.setVodName(name);
|
|
||||||
vod.setVodPic(pic);
|
|
||||||
vod.setTypeName(typeName);
|
|
||||||
vod.setVodYear(year);
|
|
||||||
vod.setVodArea(area);
|
|
||||||
vod.setVodRemarks(remark);
|
|
||||||
vod.setVodActor(actor);
|
|
||||||
vod.setVodDirector(director);
|
|
||||||
vod.setVodContent(description);
|
|
||||||
vod.setVodPlayFrom(TextUtils.join("$$$", playMap.keySet()));
|
|
||||||
vod.setVodPlayUrl(TextUtils.join("$$$", playMap.values()));
|
|
||||||
|
|
||||||
return Result.string(vod);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getStrByRegex(Pattern pattern, String str) {
|
|
||||||
Matcher matcher = pattern.matcher(str);
|
|
||||||
if (matcher.find()) return matcher.group(1).trim();
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getActorOrDirector(Pattern pattern, String str) {
|
|
||||||
return getStrByRegex(pattern, str)
|
|
||||||
.replaceAll("<br>", "")
|
|
||||||
.replaceAll(" ", "")
|
|
||||||
.replaceAll("&", "")
|
|
||||||
.replaceAll("middot;", "・")
|
|
||||||
.replaceAll(" ", ",")
|
|
||||||
.replaceAll(" ", ",")
|
|
||||||
.replaceAll(" ", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getDescription(Pattern pattern, String str) {
|
|
||||||
return getStrByRegex(pattern, str)
|
|
||||||
.replaceAll("</?[^>]+>", "")
|
|
||||||
.replaceAll("\n", "")
|
|
||||||
.replaceAll("&", "")
|
|
||||||
.replaceAll("middot;", "・")
|
|
||||||
.replaceAll("ldquo;", "【")
|
|
||||||
.replaceAll("rdquo;", "】")
|
|
||||||
.replaceAll(" ", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick) throws Exception {
|
|
||||||
return searchContent(key, quick, "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick, String pg) throws Exception {
|
|
||||||
String searchUrl = siteUrl + "/e/search/index.php";
|
|
||||||
if (pg.equals("1")) {
|
|
||||||
RequestBody formBody = new FormBody.Builder()
|
|
||||||
.add("show", "title")
|
|
||||||
.add("tempid", "1")
|
|
||||||
.add("tbname", "article")
|
|
||||||
.add("mid", "1")
|
|
||||||
.add("dopost", "search")
|
|
||||||
.add("submit", "")
|
|
||||||
.addEncoded("keyboard", key)
|
|
||||||
.build();
|
|
||||||
Request request = new Request.Builder().url(searchUrl)
|
|
||||||
.addHeader("User-Agent", Util.CHROME)
|
|
||||||
.addHeader("Origin", siteUrl)
|
|
||||||
.addHeader("Referer", siteUrl + "/")
|
|
||||||
.post(formBody)
|
|
||||||
.build();
|
|
||||||
Response response = OkHttp.newCall(request);
|
|
||||||
String[] split = String.valueOf(response.request().url()).split("\\?searchid=");
|
|
||||||
nextSearchUrlPrefix = split[0] + "index.php?page=";
|
|
||||||
nextSearchUrlSuffix = "&searchid=" + split[1];
|
|
||||||
return Result.string(parseVodListFromDoc(response.body().string()));
|
|
||||||
} else {
|
|
||||||
int page = Integer.parseInt(pg) - 1;
|
|
||||||
searchUrl = nextSearchUrlPrefix + page + nextSearchUrlSuffix;
|
|
||||||
return Result.string(parseVodListFromDoc(OkHttp.string(searchUrl, getHeader())));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String playerContent(String flag, String id, List<String> vipFlags) throws Exception {
|
|
||||||
return Result.get().url(id).string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -91,7 +91,6 @@ public class YHDM extends Spider {
|
||||||
Document doc = Jsoup.parse(OkHttp.string(detailUrl, getHeader()));
|
Document doc = Jsoup.parse(OkHttp.string(detailUrl, getHeader()));
|
||||||
Elements sources = doc.select(".myui-content__list.sort-list");
|
Elements sources = doc.select(".myui-content__list.sort-list");
|
||||||
Elements circuits = doc.select("a[href^=#playlist]");
|
Elements circuits = doc.select("a[href^=#playlist]");
|
||||||
|
|
||||||
StringBuilder vod_play_url = new StringBuilder();
|
StringBuilder vod_play_url = new StringBuilder();
|
||||||
StringBuilder vod_play_from = new StringBuilder();
|
StringBuilder vod_play_from = new StringBuilder();
|
||||||
for (int i = 0; i < circuits.size(); i++) {
|
for (int i = 0; i < circuits.size(); i++) {
|
||||||
|
|
@ -113,7 +112,6 @@ public class YHDM extends Spider {
|
||||||
String year = matcher(text, "年份:(.*?)更新");
|
String year = matcher(text, "年份:(.*?)更新");
|
||||||
String remark = matcher(text, "更新:(.*?)简介");
|
String remark = matcher(text, "更新:(.*?)简介");
|
||||||
String brief = doc.select(".col-pd.text-collapse .data").text();
|
String brief = doc.select(".col-pd.text-collapse .data").text();
|
||||||
|
|
||||||
Vod vod = new Vod();
|
Vod vod = new Vod();
|
||||||
vod.setVodId(ids.get(0));
|
vod.setVodId(ids.get(0));
|
||||||
vod.setVodArea(area);
|
vod.setVodArea(area);
|
||||||
|
|
@ -164,7 +162,6 @@ public class YHDM extends Spider {
|
||||||
String key = "57A891D97E332A9D";
|
String key = "57A891D97E332A9D";
|
||||||
String iv = matcher(content1, "bt_token = \"(.*?)\"");
|
String iv = matcher(content1, "bt_token = \"(.*?)\"");
|
||||||
String realUrl = Crypto.CBC(playUrl, key, iv);
|
String realUrl = Crypto.CBC(playUrl, key, iv);
|
||||||
if (realUrl == null) return Result.get().url(siteUrl + id).parse().string();
|
|
||||||
return Result.get().url(realUrl).string();
|
return Result.get().url(realUrl).string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,166 +0,0 @@
|
||||||
package com.github.catvod.spider;
|
|
||||||
|
|
||||||
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.Util;
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup;
|
|
||||||
import org.jsoup.nodes.Document;
|
|
||||||
import org.jsoup.nodes.Element;
|
|
||||||
import org.jsoup.select.Elements;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Ysj extends Spider {
|
|
||||||
|
|
||||||
private static final String siteUrl = "https://www.dmmiku.com";
|
|
||||||
private static final String cateUrl = "https://www.dmmiku.com/index.php/vod/show";
|
|
||||||
private static final String homeUrl = "https://www.dmmiku.com/index.php/vod/show/id/20.html";
|
|
||||||
private static final String detailUrl = "https://www.dmmiku.com/index.php/vod/detail/id/";
|
|
||||||
private static final String searchUrl = "https://www.dmmiku.com/index.php/vod/search.html";
|
|
||||||
private static final String playUrl = "/index.php/vod/play/id/";
|
|
||||||
|
|
||||||
private HashMap<String, String> getHeaders() {
|
|
||||||
HashMap<String, String> headers = new HashMap<>();
|
|
||||||
headers.put("User-Agent", Util.CHROME);
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Filter getFilter(String name, String key, List<String> texts) {
|
|
||||||
List<Filter.Value> values = new ArrayList<>();
|
|
||||||
for (String text : texts) {
|
|
||||||
if (text.isEmpty()) continue;
|
|
||||||
values.add(new Filter.Value(text, text.replace("全部", "")));
|
|
||||||
}
|
|
||||||
return new Filter(key, name, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String homeContent(boolean filter) {
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
List<Class> classes = new ArrayList<>();
|
|
||||||
List<Filter> array = new ArrayList<>();
|
|
||||||
LinkedHashMap<String, List<Filter>> filters = new LinkedHashMap<>();
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(homeUrl, getHeaders()));
|
|
||||||
array.add(getFilter("地區", "area", doc.select("div#hl03").select("a").eachText()));
|
|
||||||
array.add(getFilter("年份", "year", doc.select("div#hl04").select("a").eachText()));
|
|
||||||
array.add(getFilter("語言", "lang", doc.select("div#hl05").select("a").eachText()));
|
|
||||||
array.add(getFilter("字母", "letter", doc.select("div#hl06").select("a").eachText()));
|
|
||||||
for (Element element : doc.select("div#hl02").select("a")) {
|
|
||||||
String typeId = element.attr("href").split("/")[5];
|
|
||||||
typeId = typeId.contains(".html") ? "" : typeId;
|
|
||||||
String typeName = element.text().replace("BD", "");
|
|
||||||
classes.add(new Class(typeId, typeName));
|
|
||||||
filters.put(typeId, array);
|
|
||||||
}
|
|
||||||
for (Element element : doc.select("li.vodlist_item")) {
|
|
||||||
String id = element.select("a").attr("href").split("/")[5];
|
|
||||||
String name = element.select("a").attr("title");
|
|
||||||
String pic = siteUrl + element.select("a").attr("data-original");
|
|
||||||
String remark = element.select("span.pic_text").text();
|
|
||||||
list.add(new Vod(id, name, pic, remark));
|
|
||||||
}
|
|
||||||
return Result.string(classes, list, filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
|
||||||
StringBuilder sb = new StringBuilder(cateUrl);
|
|
||||||
if (extend.containsKey("area")) sb.append("/area/").append(extend.get("area"));
|
|
||||||
if (tid.length() > 0) sb.append("/class/").append(tid);
|
|
||||||
sb.append("/id/20");
|
|
||||||
if (extend.containsKey("lang")) sb.append("/lang/").append(extend.get("lang"));
|
|
||||||
if (extend.containsKey("letter")) sb.append("/letter/").append(extend.get("letter"));
|
|
||||||
if (extend.containsKey("year")) sb.append("/year/").append(extend.get("year"));
|
|
||||||
if (!pg.equals("1")) sb.append("/page/").append(pg);
|
|
||||||
sb.append(".html");
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(sb.toString(), getHeaders()));
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
for (Element element : doc.select("li.vodlist_item")) {
|
|
||||||
String id = element.select("a").attr("href").split("/")[5];
|
|
||||||
String name = element.select("a").attr("title");
|
|
||||||
String pic = siteUrl + element.select("a").attr("data-original");
|
|
||||||
String remark = element.select("span.pic_text").text();
|
|
||||||
list.add(new Vod(id, name, pic, remark));
|
|
||||||
}
|
|
||||||
return Result.string(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String detailContent(List<String> ids) {
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(detailUrl.concat(ids.get(0)), getHeaders()));
|
|
||||||
String name = doc.select("h2.title").text();
|
|
||||||
String pic = siteUrl + doc.select("a.vodlist_thumb").attr("data-original");
|
|
||||||
String year = doc.select("li.data").get(0).select("a").get(0).text();
|
|
||||||
String area = doc.select("li.data").get(0).select("a").get(1).text();
|
|
||||||
String type = doc.select("li.data").get(0).select("a").get(2).text();
|
|
||||||
String actor = doc.select("li.data").get(2).text().replace("主演:", "");
|
|
||||||
String director = doc.select("li.data").get(3).text().replace("导演:", "");
|
|
||||||
String content = doc.select("div.content_desc > span").text();
|
|
||||||
|
|
||||||
Vod vod = new Vod();
|
|
||||||
vod.setVodId(ids.get(0));
|
|
||||||
vod.setVodPic(pic);
|
|
||||||
vod.setVodYear(year);
|
|
||||||
vod.setVodName(name);
|
|
||||||
vod.setVodArea(area);
|
|
||||||
vod.setVodActor(actor);
|
|
||||||
vod.setVodContent(content);
|
|
||||||
vod.setVodDirector(director);
|
|
||||||
vod.setTypeName(type);
|
|
||||||
|
|
||||||
Map<String, String> sites = new LinkedHashMap<>();
|
|
||||||
Elements sources = doc.select("div.play_source_tab > a");
|
|
||||||
Elements sourceList = doc.select("ul.content_playlist");
|
|
||||||
for (int i = 0; i < sources.size(); i++) {
|
|
||||||
Element source = sources.get(i);
|
|
||||||
String sourceName = source.attr("alt");
|
|
||||||
Elements playList = sourceList.get(i).select("a");
|
|
||||||
List<String> vodItems = new ArrayList<>();
|
|
||||||
for (int j = 0; j < playList.size(); j++) {
|
|
||||||
Element e = playList.get(j);
|
|
||||||
String href = e.attr("href").replace(playUrl, "");
|
|
||||||
vodItems.add(e.text() + "$" + href);
|
|
||||||
}
|
|
||||||
if (vodItems.size() > 0) {
|
|
||||||
sites.put(sourceName, TextUtils.join("#", vodItems));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sites.size() > 0) {
|
|
||||||
vod.setVodPlayFrom(TextUtils.join("$$$", sites.keySet()));
|
|
||||||
vod.setVodPlayUrl(TextUtils.join("$$$", sites.values()));
|
|
||||||
}
|
|
||||||
return Result.string(vod);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String searchContent(String key, boolean quick) {
|
|
||||||
List<Vod> list = new ArrayList<>();
|
|
||||||
String target = searchUrl.concat("?wd=").concat(key).concat("&submit=");
|
|
||||||
Document doc = Jsoup.parse(OkHttp.string(target, getHeaders()));
|
|
||||||
if (doc.html().contains("很抱歉,暂无相关视频")) return Result.string(list);
|
|
||||||
for (Element element : doc.select("li.searchlist_item")) {
|
|
||||||
String id = element.select("a").attr("href").split("/")[5];
|
|
||||||
String name = element.select("a").attr("title");
|
|
||||||
String pic = siteUrl + element.select("a").attr("data-original");
|
|
||||||
String remark = element.select("span.pic_text").text();
|
|
||||||
list.add(new Vod(id, name, pic, remark));
|
|
||||||
}
|
|
||||||
return Result.string(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
|
||||||
return Result.get().url(siteUrl + playUrl + id).parse().header(getHeaders()).string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,220 +0,0 @@
|
||||||
package com.github.catvod.utils;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LZString4Java By Rufus Huang
|
|
||||||
* https://github.com/rufushuang/lz-string4java
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Port from original JavaScript version by pieroxy
|
|
||||||
* https://github.com/pieroxy/lz-string
|
|
||||||
*/
|
|
||||||
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class LZString {
|
|
||||||
|
|
||||||
private static final char[] keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
|
|
||||||
private static final Map<char[], Map<Character, Integer>> baseReverseDic = new HashMap<>();
|
|
||||||
|
|
||||||
private static char getBaseValue(char[] alphabet, Character character) {
|
|
||||||
Map<Character, Integer> map = baseReverseDic.get(alphabet);
|
|
||||||
if (map == null) {
|
|
||||||
map = new HashMap<>();
|
|
||||||
baseReverseDic.put(alphabet, map);
|
|
||||||
for (int i = 0; i < alphabet.length; i++) {
|
|
||||||
map.put(alphabet[i], i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (char) map.get(character).intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String decompressFromBase64(final String inputStr) {
|
|
||||||
if (TextUtils.isEmpty(inputStr)) return "";
|
|
||||||
return _decompress(inputStr.length(), 32, new DecompressFunctionWrapper() {
|
|
||||||
@Override
|
|
||||||
public char doFunc(int index) {
|
|
||||||
return getBaseValue(keyStrBase64, inputStr.charAt(index));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static abstract class DecompressFunctionWrapper {
|
|
||||||
public abstract char doFunc(int i);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static class DecData {
|
|
||||||
public char val;
|
|
||||||
public int position;
|
|
||||||
public int index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String f(int i) {
|
|
||||||
return String.valueOf((char) i);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String _decompress(int length, int resetValue, DecompressFunctionWrapper getNextValue) {
|
|
||||||
List<String> dictionary = new ArrayList<>();
|
|
||||||
int enlargeIn = 4;
|
|
||||||
int dictSize = 4;
|
|
||||||
int numBits = 3;
|
|
||||||
String entry;
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
String w;
|
|
||||||
int bits, resb;
|
|
||||||
int maxpower, power;
|
|
||||||
String c = null;
|
|
||||||
DecData data = new DecData();
|
|
||||||
data.val = getNextValue.doFunc(0);
|
|
||||||
data.position = resetValue;
|
|
||||||
data.index = 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i += 1) {
|
|
||||||
dictionary.add(i, f(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
bits = 0;
|
|
||||||
maxpower = powerOf2(2);
|
|
||||||
power = 1;
|
|
||||||
while (power != maxpower) {
|
|
||||||
resb = data.val & data.position;
|
|
||||||
data.position >>= 1;
|
|
||||||
if (data.position == 0) {
|
|
||||||
data.position = resetValue;
|
|
||||||
data.val = getNextValue.doFunc(data.index++);
|
|
||||||
}
|
|
||||||
bits |= (resb > 0 ? 1 : 0) * power;
|
|
||||||
power <<= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (bits) {
|
|
||||||
case 0:
|
|
||||||
maxpower = powerOf2(8);
|
|
||||||
power = 1;
|
|
||||||
while (power != maxpower) {
|
|
||||||
resb = data.val & data.position;
|
|
||||||
data.position >>= 1;
|
|
||||||
if (data.position == 0) {
|
|
||||||
data.position = resetValue;
|
|
||||||
data.val = getNextValue.doFunc(data.index++);
|
|
||||||
}
|
|
||||||
bits |= (resb > 0 ? 1 : 0) * power;
|
|
||||||
power <<= 1;
|
|
||||||
}
|
|
||||||
c = f(bits);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
bits = 0;
|
|
||||||
maxpower = powerOf2(16);
|
|
||||||
power = 1;
|
|
||||||
while (power != maxpower) {
|
|
||||||
resb = data.val & data.position;
|
|
||||||
data.position >>= 1;
|
|
||||||
if (data.position == 0) {
|
|
||||||
data.position = resetValue;
|
|
||||||
data.val = getNextValue.doFunc(data.index++);
|
|
||||||
}
|
|
||||||
bits |= (resb > 0 ? 1 : 0) * power;
|
|
||||||
power <<= 1;
|
|
||||||
}
|
|
||||||
c = f(bits);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
dictionary.add(3, c);
|
|
||||||
w = c;
|
|
||||||
result.append(w);
|
|
||||||
while (true) {
|
|
||||||
if (data.index > length) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
bits = 0;
|
|
||||||
maxpower = powerOf2(numBits);
|
|
||||||
power = 1;
|
|
||||||
while (power != maxpower) {
|
|
||||||
resb = data.val & data.position;
|
|
||||||
data.position >>= 1;
|
|
||||||
if (data.position == 0) {
|
|
||||||
data.position = resetValue;
|
|
||||||
data.val = getNextValue.doFunc(data.index++);
|
|
||||||
}
|
|
||||||
bits |= (resb > 0 ? 1 : 0) * power;
|
|
||||||
power <<= 1;
|
|
||||||
}
|
|
||||||
int cc;
|
|
||||||
switch (cc = bits) {
|
|
||||||
case 0:
|
|
||||||
maxpower = powerOf2(8);
|
|
||||||
power = 1;
|
|
||||||
while (power != maxpower) {
|
|
||||||
resb = data.val & data.position;
|
|
||||||
data.position >>= 1;
|
|
||||||
if (data.position == 0) {
|
|
||||||
data.position = resetValue;
|
|
||||||
data.val = getNextValue.doFunc(data.index++);
|
|
||||||
}
|
|
||||||
bits |= (resb > 0 ? 1 : 0) * power;
|
|
||||||
power <<= 1;
|
|
||||||
}
|
|
||||||
dictionary.add(dictSize++, f(bits));
|
|
||||||
cc = dictSize - 1;
|
|
||||||
enlargeIn--;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
bits = 0;
|
|
||||||
maxpower = powerOf2(16);
|
|
||||||
power = 1;
|
|
||||||
while (power != maxpower) {
|
|
||||||
resb = data.val & data.position;
|
|
||||||
data.position >>= 1;
|
|
||||||
if (data.position == 0) {
|
|
||||||
data.position = resetValue;
|
|
||||||
data.val = getNextValue.doFunc(data.index++);
|
|
||||||
}
|
|
||||||
bits |= (resb > 0 ? 1 : 0) * power;
|
|
||||||
power <<= 1;
|
|
||||||
}
|
|
||||||
dictionary.add(dictSize++, f(bits));
|
|
||||||
cc = dictSize - 1;
|
|
||||||
enlargeIn--;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
return result.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enlargeIn == 0) {
|
|
||||||
enlargeIn = powerOf2(numBits);
|
|
||||||
numBits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cc < dictionary.size() && dictionary.get(cc) != null) {
|
|
||||||
entry = dictionary.get(cc);
|
|
||||||
} else {
|
|
||||||
if (cc == dictSize) {
|
|
||||||
entry = w + w.charAt(0);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.append(entry);
|
|
||||||
|
|
||||||
// Add w+entry[0] to the dictionary.
|
|
||||||
dictionary.add(dictSize++, w + entry.charAt(0));
|
|
||||||
enlargeIn--;
|
|
||||||
|
|
||||||
w = entry;
|
|
||||||
|
|
||||||
if (enlargeIn == 0) {
|
|
||||||
enlargeIn = powerOf2(numBits);
|
|
||||||
numBits++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int powerOf2(int power) {
|
|
||||||
return 1 << power;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -13,9 +13,6 @@ import android.webkit.WebViewClient;
|
||||||
|
|
||||||
import com.github.catvod.spider.Init;
|
import com.github.catvod.spider.Init;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
@ -26,7 +23,6 @@ public class Util {
|
||||||
public static final Pattern RULE = Pattern.compile("http((?!http).){12,}?\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac)|http((?!http).)*?video/tos*");
|
public static final Pattern RULE = Pattern.compile("http((?!http).){12,}?\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac)|http((?!http).)*?video/tos*");
|
||||||
public static final Pattern THUNDER = Pattern.compile("(magnet|thunder|ed2k):.*");
|
public static final Pattern THUNDER = Pattern.compile("(magnet|thunder|ed2k):.*");
|
||||||
public static final String CHROME = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
public static final String CHROME = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
||||||
public static final String ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7";
|
|
||||||
public static final List<String> MEDIA = Arrays.asList("mp4", "mkv", "wmv", "flv", "avi", "iso", "mpg", "ts", "mp3", "aac", "flac", "m4a", "ape", "ogg");
|
public static final List<String> MEDIA = Arrays.asList("mp4", "mkv", "wmv", "flv", "avi", "iso", "mpg", "ts", "mp3", "aac", "flac", "m4a", "ape", "ogg");
|
||||||
public static final List<String> SUB = Arrays.asList("srt", "ass", "ssa", "vtt");
|
public static final List<String> SUB = Arrays.asList("srt", "ass", "ssa", "vtt");
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1 +1 @@
|
||||||
5e53c8f9ddd4ede5359c16bee091db93
|
2f4edf2bed2c6bfc906049428f875e5b
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue