add - 删除不好用的json
This commit is contained in:
@@ -1,466 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Demo for spider
|
||||
* <p>
|
||||
* Author: CatVod
|
||||
*/
|
||||
public class Aidi extends Spider {
|
||||
private static final String siteUrl = "https://aidi.tv";
|
||||
private static final String siteHost = "aidi.tv";
|
||||
|
||||
/**
|
||||
* 播放源配置
|
||||
*/
|
||||
private JSONObject playerConfig;
|
||||
/**
|
||||
* 筛选配置
|
||||
*/
|
||||
private JSONObject filterConfig;
|
||||
|
||||
private Pattern regexCategory = Pattern.compile("/v/(\\w+).html");
|
||||
private Pattern regexVid = Pattern.compile("/movie/(\\w+).html");
|
||||
private Pattern regexPlay = Pattern.compile("\\S+/play/(\\w+)-(\\d+)-(\\d+).html");
|
||||
private Pattern regexPage = Pattern.compile("/show/(\\S+).html");
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"xg_app_player\":{\"sh\":\"app全局解析\",\"pu\":\"\",\"sn\":0,\"or\":999},\"dplayer\":{\"sh\":\"dplayer\",\"pu\":\"\",\"sn\":0,\"or\":999},\"videojs\":{\"sh\":\"videojs-H5播放器\",\"pu\":\"\",\"sn\":0,\"or\":999},\"iva\":{\"sh\":\"iva-H5播放器\",\"pu\":\"\",\"sn\":0,\"or\":999},\"iframe\":{\"sh\":\"iframe外链数据\",\"pu\":\"\",\"sn\":0,\"or\":999},\"link\":{\"sh\":\"外链数据\",\"pu\":\"top.\",\"sn\":0,\"or\":999},\"swf\":{\"sh\":\"Flash文件\",\"pu\":\"\",\"sn\":0,\"or\":999},\"flv\":{\"sh\":\"Flv文件\",\"pu\":\"\",\"sn\":0,\"or\":999},\"qiepian\":{\"sh\":\"爱迪云播\",\"pu\":\"\",\"sn\":0,\"or\":999},\"ckm3u8\":{\"sh\":\"爱迪影视\",\"pu\":\"\",\"sn\":0,\"or\":999},\"xin\":{\"sh\":\"爱迪高速\",\"pu\":\"\",\"sn\":0,\"or\":999},\"ppyun\":{\"sh\":\"爱迪云链\",\"pu\":\"\",\"sn\":0,\"or\":999},\"jisu\":{\"sh\":\"极速路线\",\"pu\":\"\",\"sn\":0,\"or\":999},\"ppayun\":{\"sh\":\"pp云\",\"pu\":\"https://wy.ppayun.cn/api/ShowVideoWy/973ed6d6891c43269706718cb0aedb72/\",\"sn\":0,\"or\":999},\"yun3edu\":{\"sh\":\"爱迪云三\",\"pu\":\"\",\"sn\":0,\"or\":999},\"guoji\":{\"sh\":\"國際路線\",\"pu\":\"\",\"sn\":0,\"or\":999},\"ddyunp\":{\"sh\":\"蓝光线路\",\"pu\":\"\",\"sn\":0,\"or\":999},\"eduyun\":{\"sh\":\"爱迪云二\",\"pu\":\"\",\"sn\":0,\"or\":999},\"dbm3u8\":{\"sh\":\"720P线路\",\"pu\":\"\",\"sn\":0,\"or\":999},\"yjm3u8\":{\"sh\":\"备用线路\",\"pu\":\"\",\"sn\":0,\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"dianying\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"dianying\"},{\"n\":\"动作片\",\"v\":\"dongzuopian\"},{\"n\":\"喜剧片\",\"v\":\"xijupian\"},{\"n\":\"爱情片\",\"v\":\"aiqingpian\"},{\"n\":\"科幻片\",\"v\":\"kehuanpian\"},{\"n\":\"恐怖片\",\"v\":\"kongbupian\"},{\"n\":\"剧情片\",\"v\":\"juqingpian\"},{\"n\":\"战争片\",\"v\":\"zhanzhengpian\"},{\"n\":\"传记\",\"v\":\"zhuanji\"}]},{\"key\":3,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动画\",\"v\":\"动画\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"枪战\",\"v\":\"枪战\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"文艺\",\"v\":\"文艺\"},{\"n\":\"微电影\",\"v\":\"微电影\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"农村\",\"v\":\"农村\"},{\"n\":\"儿童\",\"v\":\"儿童\"},{\"n\":\"网络电影\",\"v\":\"网络电影\"},{\"n\":\"情色\",\"v\":\"情色\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"lianxuju\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"lianxuju\"},{\"n\":\"国产剧\",\"v\":\"guochanju\"},{\"n\":\"港台剧\",\"v\":\"gangtaiju\"},{\"n\":\"韩剧\",\"v\":\"hanju\"},{\"n\":\"美剧\",\"v\":\"meiju\"},{\"n\":\"日剧\",\"v\":\"riju\"},{\"n\":\"英剧\",\"v\":\"yingju\"},{\"n\":\"泰剧\",\"v\":\"taiju\"}]},{\"key\":3,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"青春偶像\",\"v\":\"青春偶像\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"乡村\",\"v\":\"乡村\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"网剧\",\"v\":\"网剧\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"zongyi\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"zongyi\"},{\"n\":\"内地综艺\",\"v\":\"ndzy\"},{\"n\":\"港台综艺\",\"v\":\"gtzy\"},{\"n\":\"韩国综艺节目\",\"v\":\"variety\"},{\"n\":\"欧美综艺\",\"v\":\"oumeizongyi\"}]},{\"key\":3,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"播报\",\"v\":\"播报\"},{\"n\":\"旅游\",\"v\":\"旅游\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"美食\",\"v\":\"美食\"},{\"n\":\"纪实\",\"v\":\"纪实\"},{\"n\":\"曲艺\",\"v\":\"曲艺\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"游戏互动\",\"v\":\"游戏互动\"},{\"n\":\"财经\",\"v\":\"财经\"},{\"n\":\"求职\",\"v\":\"求职\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"dongman\":[{\"key\":0,\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"dongman\"},{\"n\":\"日韩动漫\",\"v\":\"rihan\"},{\"n\":\"国产动漫\",\"v\":\"guoman\"},{\"n\":\"欧美动漫\",\"v\":\"oumei\"},{\"n\":\"动漫电影\",\"v\":\"cartoon\"}]},{\"key\":3,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国产\",\"v\":\"国产\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"jilu\":[{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||
// 分类节点
|
||||
Elements elements = doc.select("ul.nav_list > li a");
|
||||
JSONArray classes = new JSONArray();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.select("span").text();
|
||||
if (name.equals("樱花动漫")) {
|
||||
name = "动漫";
|
||||
}
|
||||
boolean show = name.equals("电影") ||
|
||||
name.equals("连续剧") ||
|
||||
name.equals("动漫") ||
|
||||
name.equals("纪录片") ||
|
||||
name.equals("综艺");
|
||||
if (show) {
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
// 把分类的id和名称取出来加到列表里
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
// 取首页推荐视频列表
|
||||
Element homeList = doc.select("div.vod_row").get(1);
|
||||
Elements list = homeList.select("div.cbox1 > ul.vodlist li a.vodlist_thumb");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.attr("title");
|
||||
String cover = vod.attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic_text").text();
|
||||
Matcher matcher = regexVid.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String[] urlParams = new String[]{"", "", "", "", "", "", "", "", "", "", "", ""};
|
||||
urlParams[0] = tid;
|
||||
urlParams[8] = pg;
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
urlParams[Integer.parseInt(key)] = URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
// 获取分类数据的url
|
||||
String url = siteUrl + "/show/" + TextUtils.join("-", urlParams) + ".html";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
// 取页码相关信息
|
||||
Elements pageInfo = doc.select("ul.page li");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element li = pageInfo.get(i);
|
||||
Element a = li.selectFirst("a");
|
||||
if (a == null)
|
||||
continue;
|
||||
String name = a.text();
|
||||
if (page == -1 && li.hasClass("active")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾页")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
// 取当前分类页的视频列表
|
||||
Elements list = doc.select("ul.vodlist li a.vodlist_thumb");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.attr("title");
|
||||
String cover = vod.attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic_text").text();
|
||||
Matcher matcher = regexVid.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 60);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 60);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/movie/" + ids.get(0) + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String cover = doc.selectFirst("div.detail_list_box a.vodlist_thumb img").attr("data-original");
|
||||
String title = doc.selectFirst("div.detail_list_box h2.title").text();
|
||||
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.detail_list_box div.content_detail span");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("类型:")) {
|
||||
category = text.nextElementSibling().text();
|
||||
} else if (info.equals("年份:")) {
|
||||
year = text.nextElementSibling().text();
|
||||
} else if (info.equals("地区:")) {
|
||||
area = text.nextElementSibling().text();
|
||||
} else if (info.equals("状态:")) {
|
||||
remark = text.nextElementSibling().text();
|
||||
} else if (info.equals("导演:")) {
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
directors.add(aa.get(j).text());
|
||||
}
|
||||
director = TextUtils.join(",", directors);
|
||||
} else if (info.equals("主演:")) {
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", ids.get(0));
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 取播放列表数据
|
||||
Elements sources = doc.select("div.play_source_tab > a");
|
||||
Elements sourceList = doc.select("div.play_list_box > div.playlist_full");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.attr("alt");
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = sourceList.get(i).select("li > a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/play/" + id + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) { // 取直链
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
*
|
||||
* @param key
|
||||
* @param quick 是否播放页的快捷搜索
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
if (quick)
|
||||
return "";
|
||||
String url = siteUrl + "/vsearch/-------------.html?wd=" + URLEncoder.encode(key) + "&submit=";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
Elements list = doc.select("div.search_box li.searchlist_item a.vodlist_thumb");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.attr("title");
|
||||
String cover = vod.attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic_text").text();
|
||||
Matcher matcher = regexVid.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,483 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 真不卡 播放好像还有问题 需要大佬继续修复
|
||||
* <p>
|
||||
* Author: 小黄瓜
|
||||
*/
|
||||
public class Buka extends Spider {
|
||||
private static final String siteUrl = "https://www.zhenbuka3.com";
|
||||
private static final String siteHost = "www.zhenbuka3.com";
|
||||
private static final String ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36";
|
||||
|
||||
/**
|
||||
* 播放源配置
|
||||
*/
|
||||
private JSONObject playerConfig;
|
||||
/**
|
||||
* 筛选配置
|
||||
*/
|
||||
private JSONObject filterConfig;
|
||||
|
||||
private Pattern regexCategory = Pattern.compile("/vodtype/(\\w+)/");
|
||||
private Pattern regexVid = Pattern.compile("/voddetail/(\\w+)/");
|
||||
private Pattern regexPlay = Pattern.compile("/vodplay/(\\w+)-(\\d+)-(\\d+)/");
|
||||
private Pattern regexPage = Pattern.compile("/vodshow/(\\S+)/");
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"qqpic\":{\"sh\":\"不卡超清[推荐]\",\"pu\":\"http://good-vip.mmiyue.com/zhenbuka2/player/index.php?video_id=\",\"sn\":0,\"or\":999},\"niuxyun\":{\"sh\":\"不卡备用[推荐]\",\"pu\":\"http://good-vip.mmiyue.com/jiekou/zbk-bkby/jx.php?id=\",\"sn\":0,\"or\":999},\"vipjx\":{\"sh\":\"不卡备用③[推荐]\",\"pu\":\"https://cq.mmiyue.com/zhenbuka2/player/index.php?url=\",\"sn\":0,\"or\":999},\"bkm3u8\":{\"sh\":\"不卡备用②[推荐]\",\"pu\":\"http://good-vip.mmiyue.com/zhenbuka2/player/index.php?url=//good-vip.mmiyue.com/zhenbuka2/api/dymp4.php?video_id=\",\"sn\":0,\"or\":999},\"cy\":{\"sh\":\"动漫云\",\"pu\":\"https://cq.mmiyue.com/jiekou/zbk-bkby/jx.php?id=\",\"sn\":0,\"or\":999},\"mgtv\":{\"sh\":\"不卡芒果\",\"pu\":\"https://cq.mmiyue.com/zhenbuka2/player/index.php?url=\",\"sn\":0,\"or\":999},\"qiyi\":{\"sh\":\"不卡奇艺\",\"pu\":\"https://cq.mmiyue.com/zhenbuka2/player/index.php?url=\",\"sn\":0,\"or\":999},\"qq\":{\"sh\":\"不卡企鹅\",\"pu\":\"https://cq.mmiyue.com/zhenbuka2/player/index.php?url=\",\"sn\":0,\"or\":999},\"youku\":{\"sh\":\"不卡优酷\",\"pu\":\"https://cq.mmiyue.com/zhenbuka2/player/index.php?url=\",\"sn\":0,\"or\":999},\"dbm3u8\":{\"sh\":\"资源备用[不推荐]\",\"pu\":\"\",\"sn\":0,\"or\":999},\"niuyun\":{\"sh\":\"超清备用\",\"pu\":\"https://api.l32c.cn/danmu/niuyun.php?id=\",\"sn\":0,\"or\":999},\"123kum3u8\":{\"sh\":\"资源备用[不推荐]\",\"pu\":\"\",\"sn\":0,\"or\":999},\"sixpan\":{\"sh\":\"不卡备用②[推荐]\",\"pu\":\"https://cq.mmiyue.com/zhenbuka2/player/index.php?url=//cq.mmiyue.com/m3u8/buka/\",\"sn\":0,\"or\":999},\"qq1\":{\"sh\":\"超清云播\",\"pu\":\"https://api.nixingle.com/zhenbuka/player/index.php?id=\",\"sn\":0,\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"1\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"动作片\",\"v\":\"6\"},{\"n\":\"喜剧片\",\"v\":\"7\"},{\"n\":\"爱情片\",\"v\":\"8\"},{\"n\":\"科幻片\",\"v\":\"9\"},{\"n\":\"恐怖片\",\"v\":\"10\"},{\"n\":\"剧情片\",\"v\":\"11\"},{\"n\":\"战争片\",\"v\":\"12\"},{\"n\":\"动画片\",\"v\":\"23\"},{\"n\":\"纪录片\",\"v\":\"25\"},{\"n\":\"犯罪片\",\"v\":\"26\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"中国香港\",\"v\":\"中国香港\"},{\"n\":\"中国台湾\",\"v\":\"中国台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]}],\"2\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国产剧\",\"v\":\"13\"},{\"n\":\"港台剧\",\"v\":\"14\"},{\"n\":\"日韩剧\",\"v\":\"15\"},{\"n\":\"欧美剧\",\"v\":\"16\"},{\"n\":\"海外剧\",\"v\":\"20\"},{\"n\":\"纪录片\",\"v\":\"24\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"中国香港\",\"v\":\"中国香港\"},{\"n\":\"中国台湾\",\"v\":\"中国台湾\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]}],\"3\":[{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"中国香港\",\"v\":\"中国香港\"},{\"n\":\"中国台湾\",\"v\":\"中国台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"英国\",\"v\":\"英国\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]}],\"4\":[{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", ua);
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||
// 分类节点
|
||||
Elements elements = doc.select("ul.dropdown > li a");
|
||||
JSONArray classes = new JSONArray();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
boolean show = true;
|
||||
if (filter) {
|
||||
show = name.equals("电影") ||
|
||||
name.equals("剧集") ||
|
||||
name.equals("动漫") ||
|
||||
name.equals("综艺");
|
||||
}
|
||||
if (show) {
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
Elements list = doc.select("div.stui-pannel_bd ul.stui-vodlist li div.stui-vodlist__box");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".stui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".stui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String[] urlParams = new String[]{"", "", "", "", "", "", "", "", "", "", "", ""};
|
||||
urlParams[0] = tid;
|
||||
urlParams[8] = pg;
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
if (value.trim().length() == 0)
|
||||
continue;
|
||||
urlParams[Integer.parseInt(key)] = URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
// 获取分类数据的url
|
||||
String url = siteUrl + "/vodshow/" + TextUtils.join("-", urlParams) + "/";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
Elements pageInfo = doc.select(".stui-page li");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element li = pageInfo.get(i);
|
||||
Element a = li.selectFirst("a");
|
||||
if (a == null)
|
||||
continue;
|
||||
String name = a.text();
|
||||
if (page == -1 && li.hasClass("active")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾页")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
Elements list = doc.select("ul.stui-vodlist li div.stui-vodlist__box");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".stui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".stui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 48);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/voddetail/" + ids.get(0) + "/";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String cover = doc.selectFirst("a.stui-vodlist__thumb img").attr("data-original");
|
||||
String title = doc.selectFirst("div.stui-content__detail h1.title").text();
|
||||
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.stui-content__detail span.text-muted");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("类型:")) {
|
||||
category = text.nextElementSibling().text();
|
||||
} else if (info.equals("年份:")) {
|
||||
year = text.nextSibling().outerHtml().trim();
|
||||
} else if (info.equals("地区:")) {
|
||||
area = text.nextSibling().outerHtml().trim();
|
||||
} else if (info.equals("更新:")) {
|
||||
remark = text.nextSibling().outerHtml().trim();
|
||||
} else if (info.equals("导演:")) {
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
directors.add(aa.get(j).text());
|
||||
}
|
||||
director = TextUtils.join(",", directors);
|
||||
} else if (info.equals("主演:")) {
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", ids.get(0));
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
Elements sources = doc.select("div.playlist");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.selectFirst("h3.title").text().trim();
|
||||
String tabHref = source.attr("href");
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = source.select("ul.stui-content__playlist > li > a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/vodplay/" + id + "/";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) {
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
String from = player.getString("from");
|
||||
if (from.equals("qqpic")) {
|
||||
// 感谢猫大神的直连解密代码
|
||||
HashMap<String, String> hds = getHeaders(url);
|
||||
hds.put("Host", "good-vip.mmiyue.com");
|
||||
hds.put("Referer", url);
|
||||
String content1 = OkHttpUtil.string(playUrl + videoUrl, hds);
|
||||
Document doc1 = Jsoup.parse(content1);
|
||||
String url2 = "https:" + doc1.selectFirst("iframe#player").attr("src");
|
||||
hds.put("Host", "pcc.mmiyue.com");
|
||||
hds.put("Referer", "http://good-vip.mmiyue.com/");
|
||||
String content2 = OkHttpUtil.string(url2, hds);
|
||||
String finder = "var id=\"";
|
||||
start = content2.indexOf(finder) + finder.length();
|
||||
end = content2.indexOf('\"', start);
|
||||
String vvid = content2.substring(start, end);
|
||||
finder = "var sk=\"";
|
||||
start = content2.indexOf(finder) + finder.length();
|
||||
end = content2.indexOf('\"', start);
|
||||
String skey = content2.substring(start, end);
|
||||
finder = "var pt=\"";
|
||||
start = content2.indexOf(finder) + finder.length();
|
||||
end = content2.indexOf('\"', start);
|
||||
String pt = content2.substring(start, end);
|
||||
finder = "var ti=\"";
|
||||
start = content2.indexOf(finder) + finder.length();
|
||||
end = content2.indexOf('\"', start);
|
||||
String time = content2.substring(start, end);
|
||||
int bkn = 0x195c;
|
||||
for (int j = 0x0, all = skey.length(); all > j; ++j) {
|
||||
bkn += ((bkn << 5) + (byte) skey.charAt(j));
|
||||
}
|
||||
bkn = 0x7fffffff & bkn;
|
||||
int gtk1 = 0x0;
|
||||
for (int j = 0x0; j < pt.length(); j += 0x4) {
|
||||
gtk1 += Integer.parseInt(String.format("%c%c%c%c", pt.charAt(j), pt.charAt(j + 0x1), pt.charAt(j + 0x2), pt.charAt(j + 0x3)), 0x10);
|
||||
gtk1 %= 0x400a;
|
||||
}
|
||||
int offset = gtk1 % 10;
|
||||
int gtk = 0x0;
|
||||
for (int j = 0x0; j < pt.length(); j++) {
|
||||
gtk += ((byte) pt.charAt(j)) * (j + offset);
|
||||
gtk %= gtk1;
|
||||
}
|
||||
String finalVideoUrl = "https://pcc.mmiyue.com/hls/play/" + vvid + "%7C" + time + "%7C" + skey + "%7C" + pt + "%7C" + bkn + "%7C" + gtk + ".m3u8";
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", "");
|
||||
result.put("url", finalVideoUrl);
|
||||
result.put("header", "");
|
||||
} else {
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
*
|
||||
* @param key
|
||||
* @param quick 是否播放页的快捷搜索
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
// 搜索有验证码 不支持
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,581 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.AES;
|
||||
import com.github.catvod.utils.CBC;
|
||||
import com.github.catvod.utils.gZip;
|
||||
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
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.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.StringReader;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
/**
|
||||
* Demo for self study
|
||||
* <p>
|
||||
* Source from Author: CatVod
|
||||
*/
|
||||
|
||||
public class Ddrk extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://ddrk.me";
|
||||
private static final String siteHost = "ddrk.me";
|
||||
|
||||
protected JSONObject filterConfig;
|
||||
|
||||
protected Pattern regexCategory = Pattern.compile("/category/(\\S+)/");
|
||||
protected Pattern regexVid = Pattern.compile("https://ddrk.me/(\\S+)/");
|
||||
|
||||
protected Pattern regexPage = Pattern.compile("\\S+/page/(\\S+)\\S+");
|
||||
protected Pattern m = Pattern.compile("\\S+(http\\S+g)");
|
||||
protected Pattern mark = Pattern.compile("\\S+(.*)");
|
||||
|
||||
// protected Pattern t = Pattern.compile("(\\S+)");
|
||||
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||
headers.put("Referer", "https://ddrk.me/");
|
||||
return headers;
|
||||
}
|
||||
|
||||
protected static HashMap<String, String> Headers() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Referer", "https://ddrk.me/");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
String url = siteUrl + '/';
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements elements = doc.select("li.menu-item a");
|
||||
JSONArray classes = new JSONArray();
|
||||
ArrayList<String> allClass = new ArrayList<>();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.attr("title");
|
||||
boolean show = !filter || (name.equals("热映中")
|
||||
|| name.equals("欧美剧")
|
||||
|| name.equals("日剧")
|
||||
|| name.equals("韩剧")
|
||||
|| name.equals("华语剧")
|
||||
|| name.equals("其他地区")
|
||||
|| name.equals("全部")
|
||||
|| name.equals("欧美电影")
|
||||
|| name.equals("日韩电影")
|
||||
|| name.equals("华语电影")
|
||||
|| name.equals("新番")
|
||||
|| name.equals("动画")
|
||||
|| name.equals("纪录片")
|
||||
|| name.equals("综艺"));
|
||||
if (allClass.contains(name))
|
||||
show = false;
|
||||
if (show) {
|
||||
allClass.add(name);
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
// 把分类的id和名称取出来加到列表里
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
// 取首页推荐视频列表
|
||||
Elements list = doc.select("div.post-box-container");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String a = vod.selectFirst(".post-box-title a").text();
|
||||
if (a.contains("(")) {
|
||||
String[] item = a.split("\\(");
|
||||
String title = item[0];
|
||||
String remark = item[1].replace(")", "");
|
||||
String cover = doReplaceRegex(m, vod.selectFirst(".post-box-image").attr("style"));
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".post-box-title a").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
} else {
|
||||
String title = a;
|
||||
String cover = doReplaceRegex(m, vod.selectFirst(".post-box-image").attr("style"));
|
||||
String remark = doReplaceRegex(mark, vod.selectFirst(".post-box-title a").text());
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".post-box-title a").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
String url = "";
|
||||
try {
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
if (value != null && value.length() != 0 && value != " ") {
|
||||
url = siteUrl + "/category/" + tid + "/" + value;
|
||||
} else {
|
||||
url = siteUrl + "/category/" + tid;
|
||||
}
|
||||
;
|
||||
}
|
||||
} else {
|
||||
url = siteUrl + "/category/" + tid;
|
||||
}
|
||||
;
|
||||
if (pg.equals("1")) {
|
||||
url = url + "/";
|
||||
} else {
|
||||
url = url + "/page/" + pg + "/";
|
||||
}
|
||||
//System.out.println(url);
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
// 取页码相关信息
|
||||
Elements pageInfo = doc.select("div.nav-links");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element li = pageInfo.get(i);
|
||||
Element a = li.selectFirst("a");
|
||||
if (a == null)
|
||||
continue;
|
||||
String wy = doc.select("div.nav-links a").last().attr("href");
|
||||
String span = doc.select("span.current").text().trim();
|
||||
if (page == -1) {
|
||||
page = Integer.parseInt(span);
|
||||
} else {
|
||||
|
||||
page = 0;
|
||||
}
|
||||
Matcher matcher = regexPage.matcher(wy);
|
||||
if (matcher.find()) {
|
||||
//System.out.println("尾页" + matcher.group(1));
|
||||
pageCount = Integer.parseInt(matcher.group(1));
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
// 取当前分类页的视频列表
|
||||
Elements list = doc.select("div.post-box-container");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String a = vod.selectFirst(".post-box-title a").text();
|
||||
if (a.contains("(")) {
|
||||
String[] item = a.split("\\(");
|
||||
String title = item[0];
|
||||
String remark = item[1].replace(")", "");
|
||||
String cover = doReplaceRegex(m, vod.selectFirst(".post-box-image").attr("style"));
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".post-box-title a").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
} else {
|
||||
String title = a;
|
||||
String cover = doReplaceRegex(m, vod.selectFirst(".post-box-image").attr("style"));
|
||||
String remark = doReplaceRegex(mark, vod.selectFirst(".post-box-title a").text());
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".post-box-title a").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 24);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 24);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/" + ids.get(0) + "/";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String cover = doc.select("div.post img").attr("src");
|
||||
String ab = doc.select("h1.post-title").text();
|
||||
if (ab.contains("(")) {
|
||||
String[] b = ab.split("\\(");
|
||||
String title = b[0];
|
||||
String remark = b[1].replace("(", "");
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_remarks", remark);
|
||||
} else {
|
||||
vodList.put("vod_name", ab);
|
||||
String remark = doc.select("time").text().trim();
|
||||
vodList.put("vod_remarks", "全");
|
||||
}
|
||||
String str2 = doc.select("div.abstract").text().replace(" ", "");
|
||||
String replace = str2.replace("<br>", "");
|
||||
String text = replace.replace("<p></p>", "");
|
||||
Pattern categorys = Pattern.compile("类型:(.*)制");
|
||||
String category = doReplaceRegex(categorys, text);
|
||||
Pattern a = Pattern.compile("年份:(.*)简");
|
||||
String year = doReplaceRegex(a, text);
|
||||
Pattern b = Pattern.compile("地区:(.*)年份");
|
||||
String area = doReplaceRegex(b, text);
|
||||
Pattern c = Pattern.compile("演员:(.*)类");
|
||||
String actor = doReplaceRegex(c, text);
|
||||
Pattern d = Pattern.compile("导演:(.*)演");
|
||||
String director = doReplaceRegex(d, text);
|
||||
Pattern e = Pattern.compile("简介:(.*)");
|
||||
String desc = doReplaceRegex(e, text);
|
||||
|
||||
|
||||
vodList.put("vod_id", ids.get(0));
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
List<String> vodItems2 = new ArrayList<>();
|
||||
Map<String, String> vod_play = new LinkedHashMap<>();
|
||||
|
||||
Elements allScript = doc.select(".wp-playlist-script");
|
||||
String sourceName = "第1季";
|
||||
for (int j = 0; j < allScript.size(); j++) {
|
||||
String scContent = allScript.get(j).html().trim();
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject UJson = new JSONObject(json);
|
||||
JSONArray Track = UJson.getJSONArray("tracks");
|
||||
for (int k = 0; k < Track.length(); k++) {
|
||||
JSONObject src = Track.getJSONObject(k);
|
||||
String adk = src.getString("src1");
|
||||
String vodName = src.getString("caption");
|
||||
String playURL = "https://ddrk.me/getvddr/video?id=" + adk + "&type=mix";
|
||||
String zm = "https://ddrk.me/subddr/" + src.getString("subsrc");
|
||||
String pzm = playURL + "|" + zm;
|
||||
vodItems.add(vodName + "$" + pzm);
|
||||
}
|
||||
vod_play.put(sourceName, TextUtils.join("#", vodItems));
|
||||
}
|
||||
Elements sources = doc.select(".post-page-numbers");
|
||||
if (!sources.isEmpty())
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
sourceName = "第" + source.text() + "季";
|
||||
String Purl = siteUrl + "/" + ids.get(0) + "/" + source.text() + "/";
|
||||
Document docs = Jsoup.parse(OkHttpUtil.string(Purl, getHeaders(Purl)));
|
||||
Elements allScripts = docs.select(".wp-playlist-script");
|
||||
for (int j = 0; j < allScripts.size(); j++) {
|
||||
String scContent = allScripts.get(j).html().trim();
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject UJson = new JSONObject(json);
|
||||
JSONArray Track = UJson.getJSONArray("tracks");
|
||||
for (int k = 0; k < Track.length(); k++) {
|
||||
JSONObject src = Track.getJSONObject(k);
|
||||
String adk = src.getString("src1");
|
||||
String vodName = src.getString("caption");
|
||||
String playURL = "https://ddrk.me/getvddr/video?id=" + adk + "&type=mix";
|
||||
String zm = "https://ddrk.me/subddr/" + src.getString("subsrc");
|
||||
String pzm = playURL + "|" + zm;
|
||||
vodItems2.add(vodName + "$" + pzm);
|
||||
}
|
||||
vod_play.put(sourceName, TextUtils.join("#", vodItems2));
|
||||
}
|
||||
vodItems2.removeAll(vodItems2);
|
||||
}
|
||||
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static Object[] loadsub(String sub) {
|
||||
try {
|
||||
OKCallBack.OKCallBackDefault callBack = new OKCallBack.OKCallBackDefault() {
|
||||
@Override
|
||||
protected void onFailure(Call call, Exception e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResponse(Response response) {
|
||||
|
||||
}
|
||||
};
|
||||
OkHttpClient YM = OkHttpUtil.defaultClient();
|
||||
OkHttpUtil.get(YM, sub, null, Headers(), callBack);
|
||||
Response result = callBack.getResult();
|
||||
int code = result.code();
|
||||
if (code == 404) {
|
||||
return new Object[]{200, "application/octet-stream", new ByteArrayInputStream("WEBVTT".getBytes())};
|
||||
}
|
||||
ResponseBody body = result.body();
|
||||
byte[] bytes = body.bytes();
|
||||
byte[] tokenkey = Arrays.copyOfRange(bytes, 0, 16);
|
||||
byte[] data = Arrays.copyOfRange(bytes, 16, bytes.length);
|
||||
byte[] KS = CBC.CBC(data, tokenkey, tokenkey);
|
||||
String vtt = gZip.KS(KS);
|
||||
|
||||
|
||||
vtt = vtt.replaceAll("(\\d{2}:\\d{2}:\\d{2}.\\d{3}.+\\d{2}:\\d{2}:\\d{2}.\\d{3}).*", "$1");
|
||||
vtt = vtt.replaceAll("(\\d{2}:\\d{2}.\\d{3}).*?( --> )(\\d{2}:\\d{2}.\\d{3}).*", "00:$1$200:$3");
|
||||
BufferedReader br = new BufferedReader(new StringReader(vtt));
|
||||
ArrayList<String> lines = new ArrayList<>();
|
||||
int captionNumber = 1;
|
||||
String line = br.readLine();
|
||||
while (line != null) {
|
||||
if (line.matches("\\d{2}:\\d{2}:\\d{2}.\\d{3}.+\\d{2}:\\d{2}:\\d{2}.\\d{3}")) {
|
||||
if (lines.get(lines.size() - 1).trim().isEmpty()) {
|
||||
lines.add(captionNumber + "");
|
||||
captionNumber++;
|
||||
}
|
||||
}
|
||||
lines.add(line);
|
||||
line = br.readLine();
|
||||
}
|
||||
String join = TextUtils.join("\n", lines);
|
||||
|
||||
return new Object[]{200, "application/octet-stream", new ByteArrayInputStream(join.getBytes())};
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
SpiderDebug.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
String[] item = id.split("\\|");
|
||||
String playUrl = item[0];
|
||||
String ZiMu = item[1];
|
||||
|
||||
String content = OkHttpUtil.string(playUrl, getHeaders(playUrl));
|
||||
JSONObject obj = new JSONObject(content);
|
||||
String RealUrl = obj.optString("url");
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 0);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", RealUrl);
|
||||
result.put("header", "");
|
||||
// if (!TextUtils.isEmpty(str4)) {
|
||||
result.put("subf", "/vtt/utf-8");
|
||||
result.put("subt", Proxy.localProxyUrl() + "?do=ddrk&url=" + URLEncoder.encode(ZiMu));
|
||||
// result.put("subt", ZiMu);
|
||||
// }
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
String url = "https://www.google.com/search?q=site%3Addrk.me+" + URLEncoder.encode(key);
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
String sourceName = doc.select("div.yuRUbf a h3").text();
|
||||
if (sourceName.contains(key)) {
|
||||
String list1 = doc.select("div.yuRUbf a").attr("href");
|
||||
Document ddrklink = Jsoup.parse(OkHttpUtil.string(list1, getHeaders(list1)));
|
||||
String DDlink = ddrklink.select("link[rel=canonical]").attr("href");
|
||||
Matcher matcher = regexVid.matcher(DDlink);
|
||||
if (matcher.find()) {
|
||||
JSONObject v = new JSONObject();
|
||||
String group = matcher.group(1);
|
||||
String ab = ddrklink.select("h1.post-title").text();
|
||||
String cover = ddrklink.select("div.post img").attr("src");
|
||||
if (ab.contains("(")) {
|
||||
String[] b = ab.split("\\(");
|
||||
String title = b[0];
|
||||
String remark = b[1].replace("(", "");
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_remarks", remark);
|
||||
} else {
|
||||
v.put("vod_name", ab);
|
||||
String remark = "全";
|
||||
v.put("vod_remarks", remark);
|
||||
}
|
||||
v.put("vod_id", group);
|
||||
v.put("vod_pic", cover);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String doReplaceRegex(Pattern pattern, String src) {
|
||||
if (pattern == null)
|
||||
return src;
|
||||
try {
|
||||
Matcher matcher = pattern.matcher(src);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1).trim();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,463 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.crawler.SpiderReq;
|
||||
import com.github.catvod.crawler.SpiderReqResult;
|
||||
import com.github.catvod.crawler.SpiderUrl;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 阿房影视
|
||||
* <p>
|
||||
* Author: 小黄瓜
|
||||
*/
|
||||
public class EPang extends Spider {
|
||||
private static final String siteUrl = "https://www.bwl87.com";
|
||||
private static final String siteHost = "www.bwl87.com";
|
||||
private static final String ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36";
|
||||
|
||||
/**
|
||||
* 播放源配置
|
||||
*/
|
||||
private JSONObject playerConfig;
|
||||
/**
|
||||
* 筛选配置
|
||||
*/
|
||||
private JSONObject filterConfig;
|
||||
|
||||
private Pattern regexCategory = Pattern.compile("/type/(\\w+)/");
|
||||
private Pattern regexVid = Pattern.compile("/detail/(\\w+)/");
|
||||
private Pattern regexPlay = Pattern.compile("/play/(\\w+)-(\\d+)-(\\d+)/");
|
||||
private Pattern regexPage = Pattern.compile("/show/(\\S+)/");
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"m3u8\":{\"sh\":\"大明宫\",\"pu\":\"\",\"sn\":0,\"or\":999},\"xin\":{\"sh\":\"阿房宫\",\"pu\":\"https://player.90mm.me/play.php?url=\",\"sn\":1,\"or\":999},\"mx771\":{\"sh\":\"未央宫\",\"pu\":\"\",\"sn\":0,\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"1\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"1\"},{\"n\":\"动作片\",\"v\":\"6\"},{\"n\":\"喜剧片\",\"v\":\"7\"},{\"n\":\"爱情片\",\"v\":\"8\"},{\"n\":\"科幻片\",\"v\":\"9\"},{\"n\":\"恐怖片\",\"v\":\"10\"},{\"n\":\"剧情片\",\"v\":\"11\"},{\"n\":\"战争片\",\"v\":\"12\"},{\"n\":\"奇幻片\",\"v\":\"22\"},{\"n\":\"悬疑片\",\"v\":\"23\"},{\"n\":\"犯罪片\",\"v\":\"24\"},{\"n\":\"动漫电影\",\"v\":\"26\"}]},{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动画\",\"v\":\"动画\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"枪战\",\"v\":\"枪战\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"文艺\",\"v\":\"文艺\"},{\"n\":\"微电影\",\"v\":\"微电影\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"农村\",\"v\":\"农村\"},{\"n\":\"儿童\",\"v\":\"儿童\"},{\"n\":\"网络电影\",\"v\":\"网络电影\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"2\"},{\"n\":\"国产剧\",\"v\":\"13\"},{\"n\":\"港台剧\",\"v\":\"14\"},{\"n\":\"韩日剧\",\"v\":\"15\"},{\"n\":\"欧美剧\",\"v\":\"16\"},{\"n\":\"泰国剧\",\"v\":\"21\"},{\"n\":\"日本剧\",\"v\":\"27\"}]},{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"青春偶像\",\"v\":\"青春偶像\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"乡村\",\"v\":\"乡村\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"网剧\",\"v\":\"网剧\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"播报\",\"v\":\"播报\"},{\"n\":\"旅游\",\"v\":\"旅游\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"美食\",\"v\":\"美食\"},{\"n\":\"纪实\",\"v\":\"纪实\"},{\"n\":\"曲艺\",\"v\":\"曲艺\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"游戏互动\",\"v\":\"游戏互动\"},{\"n\":\"财经\",\"v\":\"财经\"},{\"n\":\"求职\",\"v\":\"求职\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":3,\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国产\",\"v\":\"国产\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":4,\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"20\":[{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", ua);
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
SpiderUrl su = new SpiderUrl(siteUrl, getHeaders(siteUrl));
|
||||
SpiderReqResult srr = SpiderReq.get(su);
|
||||
Document doc = Jsoup.parse(srr.content);
|
||||
// 分类节点
|
||||
Elements elements = doc.select("ul.nav-list > li a");
|
||||
JSONArray classes = new JSONArray();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
boolean show;
|
||||
if (filter) {
|
||||
show = name.equals("电影") ||
|
||||
name.equals("连续剧") ||
|
||||
name.equals("动漫") ||
|
||||
name.equals("综艺") ||
|
||||
name.equals("纪录片");
|
||||
} else {
|
||||
show = !(name.equals("首页") ||
|
||||
name.equals("资讯") ||
|
||||
name.equals("公告") ||
|
||||
name.equals("头条") ||
|
||||
name.equals("专题") ||
|
||||
name.equals("APP"));
|
||||
}
|
||||
if (show) {
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
Elements list = doc.select("div.col-lg-wide-75 > ul.myui-vodlist li div.myui-vodlist__box");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String[] urlParams = new String[]{"", "", "", "", "", "", "", "", "", "", "", ""};
|
||||
urlParams[0] = tid;
|
||||
urlParams[8] = pg;
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
urlParams[Integer.parseInt(key)] = URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
// 获取分类数据的url
|
||||
String url = siteUrl + "/show/" + TextUtils.join("-", urlParams) + "/";
|
||||
SpiderUrl su = new SpiderUrl(url, getHeaders(url));
|
||||
// 发起http请求
|
||||
SpiderReqResult srr = SpiderReq.get(su);
|
||||
String html = srr.content;
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
Elements pageInfo = doc.select(".myui-page li a");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element a = pageInfo.get(i);
|
||||
String name = a.text();
|
||||
if (page == -1 && a.hasClass("btn-warm")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾页")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
Elements list = doc.select("ul.myui-vodlist li div.myui-vodlist__box");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 48);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/detail/" + ids.get(0) + "/";
|
||||
SpiderUrl su = new SpiderUrl(url, getHeaders(url));
|
||||
SpiderReqResult srr = SpiderReq.get(su);
|
||||
Document doc = Jsoup.parse(srr.content);
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String vid = doc.selectFirst("span.mac_hits").attr("data-id");
|
||||
|
||||
String cover = doc.selectFirst("a.myui-vodlist__thumb img").attr("data-original");
|
||||
String title = doc.selectFirst("div.myui-content__detail h1.title").text();
|
||||
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.myui-content__detail span.text-muted");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("分类:")) {
|
||||
category = text.nextElementSibling().text();
|
||||
} else if (info.equals("年份:")) {
|
||||
year = text.nextElementSibling().text();
|
||||
} else if (info.equals("地区:")) {
|
||||
area = text.nextElementSibling().text();
|
||||
} else if (info.equals("更新:")) {
|
||||
remark = text.nextElementSibling().text();
|
||||
} else if (info.equals("导演:")) {
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
directors.add(aa.get(j).text());
|
||||
}
|
||||
director = TextUtils.join(",", directors);
|
||||
} else if (info.equals("主演:")) {
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", vid);
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
Elements sources = doc.select("a[data-toggle=tab]");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.text();
|
||||
String tabHref = source.attr("href");
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = doc.select("div" + tabHref + " ul > li a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/play/" + id + "/";
|
||||
SpiderUrl su = new SpiderUrl(url, getHeaders(url));
|
||||
SpiderReqResult srr = SpiderReq.get(su);
|
||||
Document doc = Jsoup.parse(srr.content);
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) {
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
if (playUrl.contains("bwl87.com")) {
|
||||
try {
|
||||
JSONObject headers = new JSONObject();
|
||||
headers.put("User-Agent", " " + ua);
|
||||
headers.put("Accept", " */*");
|
||||
headers.put("Accept-Language", " zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
headers.put("Accept-Encoding", " gzip, deflate, br");
|
||||
result.put("header", headers.toString());
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
} else {
|
||||
result.put("header", "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
*
|
||||
* @param key
|
||||
* @param quick 是否播放页的快捷搜索
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
// 搜索有验证码 不支持
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 嗯哩嗯哩
|
||||
* <p>
|
||||
* Author: 群友 不负此生
|
||||
*/
|
||||
public class Enlienli extends Spider {
|
||||
|
||||
private String siteUrl = "https://api.app.kongbuya.com";
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
}
|
||||
|
||||
private HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("Connection", "Keep-Alive");
|
||||
headers.put("User-Agent", "okhttp/4.0.1");
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
JSONArray jsonArray = new JSONArray(OkHttpUtil.string(siteUrl + "/api.php/provide/home_nav?", getHeaders(siteUrl)));
|
||||
JSONArray classes = new JSONArray();
|
||||
JSONObject filterConfig = new JSONObject();
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject jObj = jsonArray.getJSONObject(i);
|
||||
String typeName = jObj.getString("name");
|
||||
String typeId = jObj.getString("id");
|
||||
if (typeName.equals("推荐")) {
|
||||
continue;
|
||||
}
|
||||
JSONObject newCls = new JSONObject();
|
||||
newCls.put("type_id", typeId);
|
||||
newCls.put("type_name", typeName);
|
||||
classes.put(newCls);
|
||||
try {
|
||||
JSONArray typeExtend = jObj.getJSONArray("msg");
|
||||
JSONArray extendsAll = new JSONArray();
|
||||
for (int j = 0; j < typeExtend.length(); j++) {
|
||||
JSONObject typeExtendObj = typeExtend.getJSONObject(j);
|
||||
String typeExtendKey = typeExtendObj.getString("name");
|
||||
JSONArray newTypeExtendKeys = typeExtendObj.getJSONArray("data");
|
||||
if (newTypeExtendKeys.length() <= 1)
|
||||
continue;
|
||||
String typeExtendName = newTypeExtendKeys.getString(0);
|
||||
JSONObject newTypeExtend = new JSONObject();
|
||||
newTypeExtend.put("key", typeExtendKey);
|
||||
newTypeExtend.put("name", typeExtendName);
|
||||
JSONArray newTypeExtendKV = new JSONArray();
|
||||
{
|
||||
JSONObject kvAll = new JSONObject();
|
||||
kvAll.put("n", "全部");
|
||||
kvAll.put("v", "");
|
||||
newTypeExtendKV.put(kvAll);
|
||||
}
|
||||
for (int k = 1; k < newTypeExtendKeys.length(); k++) {
|
||||
JSONObject kv = new JSONObject();
|
||||
kv.put("n", newTypeExtendKeys.getString(k));
|
||||
kv.put("v", newTypeExtendKeys.getString(k));
|
||||
newTypeExtendKV.put(kv);
|
||||
}
|
||||
newTypeExtend.put("value", newTypeExtendKV);
|
||||
extendsAll.put(newTypeExtend);
|
||||
}
|
||||
filterConfig.put(typeId, extendsAll);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("class", classes);
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeVideoContent() {
|
||||
try {
|
||||
String url = siteUrl + "/api.php/provide/home_data?page=1&id=0";
|
||||
JSONObject jsonObject = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
if (jsonObject.has("tv")) {
|
||||
JSONArray data = jsonObject.getJSONObject("tv").getJSONArray("data");
|
||||
for (int i = 0; i < data.length(); i++) {
|
||||
jsonArray.put(data.getJSONObject(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonObject.has("video")) {
|
||||
JSONArray vs = jsonObject.getJSONArray("video");
|
||||
for (int i = 0; i < vs.length(); i++) {
|
||||
JSONArray data = vs.getJSONObject(i).getJSONArray("data");
|
||||
for (int j = 0; j < data.length(); j++) {
|
||||
jsonArray.put(data.getJSONObject(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("id"));
|
||||
v.put("vod_name", vObj.getString("name"));
|
||||
v.put("vod_pic", vObj.getString("img"));
|
||||
v.put("vod_remarks", vObj.getString("qingxidu"));
|
||||
videos.put(v);
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String url = siteUrl + "/api.php/provide/vod_list?page=" + pg + "&id=" + tid;
|
||||
Set<String> keys = extend.keySet();
|
||||
for (String key : keys) {
|
||||
url += "&" + key + "=" + URLEncoder.encode(extend.get(key));
|
||||
}
|
||||
JSONArray jsonArray = new JSONArray(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("id"));
|
||||
v.put("vod_name", vObj.getString("name"));
|
||||
v.put("vod_pic", vObj.getString("img"));
|
||||
v.put("vod_remarks", vObj.getString("qingxidu"));
|
||||
videos.put(v);
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
int limit = 20;
|
||||
int page = Integer.parseInt(pg);
|
||||
int total = Integer.MAX_VALUE;
|
||||
int pageCount = videos.length() < 20 ? page : page + 1;
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", limit);
|
||||
result.put("total", total);
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
String url = siteUrl + "/api.php/provide/vod_detail?token=&id=" + ids.get(0) + "&ac=vod_detail";
|
||||
JSONObject jsonObject = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject vodList = new JSONObject();
|
||||
vodList.put("vod_id", ids.get(0));
|
||||
vodList.put("vod_name", jsonObject.getString("name"));
|
||||
vodList.put("vod_pic", jsonObject.getString("img"));
|
||||
vodList.put("type_name", jsonObject.getString("type"));
|
||||
vodList.put("vod_year", "");
|
||||
vodList.put("vod_area", "");
|
||||
vodList.put("vod_remarks", jsonObject.getString("remarks"));
|
||||
vodList.put("vod_actor", jsonObject.getString("actor"));
|
||||
vodList.put("vod_director", jsonObject.getString("director"));
|
||||
vodList.put("vod_content", jsonObject.getString("info"));
|
||||
|
||||
vodList.put("vod_play_from", jsonObject.getString("playcode"));
|
||||
vodList.put("vod_play_url", jsonObject.getString("playlist"));
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 0);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", id);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
if (quick)
|
||||
return "";
|
||||
try {
|
||||
String url = siteUrl + "/api.php/provide/search_result?video_name=" + URLEncoder.encode(key);
|
||||
JSONObject jsonObject = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONArray jsonArray = jsonObject.getJSONObject("result").getJSONArray("search_result");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("id"));
|
||||
v.put("vod_name", vObj.getString("video_name"));
|
||||
v.put("vod_pic", vObj.getString("img"));
|
||||
//v.put("vod_remarks", vObj.getString(""));
|
||||
videos.put(v);
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,482 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class If101 extends Spider {
|
||||
private static final String siteUrl = "https://oulevod.tv";
|
||||
private static final String siteHost = "oulevod.tv";
|
||||
|
||||
/**
|
||||
* 播放源配置
|
||||
*/
|
||||
private JSONObject playerConfig;
|
||||
/**
|
||||
* 筛选配置
|
||||
*/
|
||||
private JSONObject filterConfig;
|
||||
private Pattern regexCategory = Pattern.compile("/index.php/vod/type/id/(\\d+).html");
|
||||
private Pattern regexVid = Pattern.compile("/index.php/vod/detail/id/(\\d+).html");
|
||||
private Pattern regexPlay = Pattern.compile("/index.php/vod/play/id/(\\d+)/sid/(\\d+)/nid/(\\d+).html");
|
||||
private Pattern regexPage = Pattern.compile("\\S+/page/(\\d+)\\S+");
|
||||
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"if101\":{\"sh\":\"高清蓝光\",\"sn\":0,\"pu\":\"\",\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"1\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"冒险\",\"v\":\"6\"},{\"n\":\"剧情\",\"v\":\"7\"},{\"n\":\"动作\",\"v\":\"8\"},{\"n\":\"动画电影\",\"v\":\"9\"},{\"n\":\"同性\",\"v\":\"10\"},{\"n\":\"喜剧\",\"v\":\"11\"},{\"n\":\"奇幻\",\"v\":\"12\"},{\"n\":\"恐怖\",\"v\":\"20\"},{\"n\":\"悬疑\",\"v\":\"21\"},{\"n\":\"惊悚\",\"v\":\"22\"},{\"n\":\"战争\",\"v\":\"23\"},{\"n\":\"歌舞\",\"v\":\"24\"},{\"n\":\"灾难\",\"v\":\"25\"},{\"n\":\"爱情\",\"v\":\"26\"},{\"n\":\"犯罪\",\"v\":\"27\"},{\"n\":\"科幻\",\"v\":\"28\"},{\"n\":\"经典\",\"v\":\"29\"},{\"n\":\"网络电影\",\"v\":\"30\"}]},{\"key\":\"class\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动画\",\"v\":\"动画\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"枪战\",\"v\":\"枪战\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"文艺\",\"v\":\"文艺\"},{\"n\":\"微电影\",\"v\":\"微电影\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"农村\",\"v\":\"农村\"},{\"n\":\"儿童\",\"v\":\"儿童\"},{\"n\":\"网络电影\",\"v\":\"网络电影\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"version\",\"name\":\"版本\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"高清版\",\"v\":\"高清版\"},{\"n\":\"剧场版\",\"v\":\"剧场版\"},{\"n\":\"抢先版\",\"v\":\"抢先版\"},{\"n\":\"OVA\",\"v\":\"OVA\"},{\"n\":\"TV\",\"v\":\"TV\"},{\"n\":\"影院版\",\"v\":\"影院版\"}]},{\"key\":\"state\",\"name\":\"资源\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"正片\",\"v\":\"正片\"},{\"n\":\"预告片\",\"v\":\"预告片\"},{\"n\":\"花絮\",\"v\":\"花絮\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"欧美剧\",\"v\":\"13\"},{\"n\":\"日剧\",\"v\":\"14\"},{\"n\":\"韩剧\",\"v\":\"15\"},{\"n\":\"国产剧\",\"v\":\"16\"},{\"n\":\"泰剧\",\"v\":\"31\"},{\"n\":\"港剧\",\"v\":\"32\"},{\"n\":\"台剧\",\"v\":\"33\"},{\"n\":\"新马剧\",\"v\":\"34\"},{\"n\":\"其它剧\",\"v\":\"35\"}]},{\"key\":\"class\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"青春偶像\",\"v\":\"青春偶像\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"乡村\",\"v\":\"乡村\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"网剧\",\"v\":\"网剧\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"version\",\"name\":\"版本\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"高清版\",\"v\":\"高清版\"},{\"n\":\"剧场版\",\"v\":\"剧场版\"},{\"n\":\"抢先版\",\"v\":\"抢先版\"},{\"n\":\"OVA\",\"v\":\"OVA\"},{\"n\":\"TV\",\"v\":\"TV\"},{\"n\":\"影院版\",\"v\":\"影院版\"}]},{\"key\":\"state\",\"name\":\"资源\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"正片\",\"v\":\"正片\"},{\"n\":\"预告片\",\"v\":\"预告片\"},{\"n\":\"花絮\",\"v\":\"花絮\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"欧美动漫\",\"v\":\"36\"},{\"n\":\"日本动漫\",\"v\":\"37\"},{\"n\":\"韩国动漫\",\"v\":\"38\"},{\"n\":\"国产动漫\",\"v\":\"39\"},{\"n\":\"新马泰动漫\",\"v\":\"40\"},{\"n\":\"港台动漫\",\"v\":\"41\"},{\"n\":\"其他动漫\",\"v\":\"42\"}]},{\"key\":\"class\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"播报\",\"v\":\"播报\"},{\"n\":\"旅游\",\"v\":\"旅游\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"美食\",\"v\":\"美食\"},{\"n\":\"纪实\",\"v\":\"纪实\"},{\"n\":\"曲艺\",\"v\":\"曲艺\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"游戏互动\",\"v\":\"游戏互动\"},{\"n\":\"财经\",\"v\":\"财经\"},{\"n\":\"求职\",\"v\":\"求职\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"内地\",\"v\":\"内地\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"欧美综艺\",\"v\":\"43\"},{\"n\":\"日本综艺\",\"v\":\"44\"},{\"n\":\"韩国综艺\",\"v\":\"45\"},{\"n\":\"国产综艺\",\"v\":\"46\"},{\"n\":\"新马泰综艺\",\"v\":\"47\"},{\"n\":\"港台综艺\",\"v\":\"48\"},{\"n\":\"其他综艺\",\"v\":\"49\"}]},{\"key\":\"class\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"闽南语\",\"v\":\"闽南语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"version\",\"name\":\"版本\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"TV版\",\"v\":\"TV版\"},{\"n\":\"电影版\",\"v\":\"电影版\"},{\"n\":\"OVA版\",\"v\":\"OVA版\"},{\"n\":\"真人版\",\"v\":\"真人版\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"50\":[{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}],\"51\":[{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"by\",\"name\":\"By\",\"value\":[{\"n\":\"按最新\",\"v\":\"time\"},{\"n\":\"按最热\",\"v\":\"hits\"},{\"n\":\"按评分\",\"v\":\"score\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||
// 分类节点
|
||||
Elements elements = doc.select("div.conch-nav div ul li a");
|
||||
JSONArray classes = new JSONArray();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
boolean show = name.equals("电影") ||
|
||||
name.equals("电视剧") ||
|
||||
name.equals("动漫") ||
|
||||
name.equals("综艺") ||
|
||||
name.equals("纪录片") ||
|
||||
name.equals("体育");
|
||||
if (show) {
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
// 把分类的id和名称取出来加到列表里
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
// 取首页推荐视频列表
|
||||
Element homeList = doc.select("ul.hl-vod-list").get(0);
|
||||
Elements list = homeList.select("li.hl-list-item");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst("div.hl-item-title a").text();
|
||||
String cover = vod.selectFirst(".hl-item-thumb").attr("data-original");
|
||||
String remark = vod.selectFirst(".hl-pic-text span").text();
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst("div.hl-item-title a").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String url = siteUrl + "/index.php/vod/show/id/";
|
||||
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||
url += extend.get("tid");
|
||||
} else {
|
||||
url += tid;
|
||||
}
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
if (value.length() > 0) {
|
||||
url += "/" + key + "/" + URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
url += "/page/" + pg + ".html";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
// 取页码相关信息
|
||||
Elements pageInfo = doc.select("ul.hl-page-wrap");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element li = pageInfo.get(i);
|
||||
Element a = li.selectFirst("li a");
|
||||
if (a == null)
|
||||
continue;
|
||||
String span = pageInfo.select("li a.active").text();
|
||||
String wy = doc.select("ul.hl-page-wrap li a").last().attr("href");
|
||||
if (page == -1) {
|
||||
page = Integer.parseInt(span);
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
Matcher matcher = regexPage.matcher(wy);
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
// 取当前分类页的视频列表
|
||||
Elements list = doc.select("li.hl-list-item");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst("div.hl-item-title a").text();
|
||||
String cover = vod.selectFirst(".hl-item-thumb").attr("data-original");
|
||||
String remark = vod.selectFirst(".hl-pic-text span").text();
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst("div.hl-item-title a").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 24);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 24);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/index.php/vod/detail/id/" + ids.get(0) + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String vid = doc.selectFirst("a.digg_link").attr("data-id");
|
||||
|
||||
String cover = doc.selectFirst("div.hl-dc-pic span").attr("data-original");
|
||||
String title = doc.selectFirst("h2.hl-dc-title").text();
|
||||
String desc = doc.selectFirst("span.hl-content-text em").text();
|
||||
String category = "", area = "", year = "", director = "", actor = "", remark = "";
|
||||
Elements span_text_muted = doc.select("li.hl-col-xs-12 em");
|
||||
for (int i = 0; i < span_text_muted.size() - 2; i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.contains("类型")) {
|
||||
try {
|
||||
category = text.parent().select("a").text();
|
||||
} catch (Exception e) {
|
||||
category = "";
|
||||
}
|
||||
} else if (info.contains("年份")) {
|
||||
try {
|
||||
year = text.parent().text().split(":")[1];
|
||||
} catch (Exception e) {
|
||||
year = "";
|
||||
}
|
||||
} else if (info.contains("地区")) {
|
||||
try {
|
||||
area = text.parent().text().split(":")[1];
|
||||
} catch (Exception e) {
|
||||
area = "";
|
||||
}
|
||||
} else if (info.contains("上映")) {
|
||||
try {
|
||||
remark = text.text();
|
||||
} catch (Exception e) {
|
||||
remark = "";
|
||||
}
|
||||
} else if (info.contains("导演")) {
|
||||
try {
|
||||
director = text.parent().select("a").text();
|
||||
} catch (Exception e) {
|
||||
director = "";
|
||||
}
|
||||
} else if (info.contains("主演")) {
|
||||
try {
|
||||
actor = text.parent().select("a").text();
|
||||
} catch (Exception e) {
|
||||
actor = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", vid);
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 取播放列表数据
|
||||
Elements sources = doc.select("div.hl-plays-from a");
|
||||
Elements sourceList = doc.select("div.hl-list-wrap");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.text();
|
||||
sourceName = sourceName.replaceAll("[^\u4E00-\u9FA5]", "");
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = sourceList.get(i).select("ul>li>a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "/sid/" + matcher.group(2) + "/nid/" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/index.php/vod/play/id/" + id + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) { // 取直链
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
if (searchResult.getInt("total") > 0) {
|
||||
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||
for (int i = 0; i < lists.length(); i++) {
|
||||
JSONObject vod = lists.getJSONObject(i);
|
||||
String id = vod.getString("id");
|
||||
String title = vod.getString("name");
|
||||
String cover = vod.getString("pic");
|
||||
if (title.contains(key)) {
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", "");
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String doReplaceRegex(Pattern pattern, String src) {
|
||||
if (pattern == null)
|
||||
return src;
|
||||
try {
|
||||
Matcher matcher = pattern.matcher(src);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1).trim();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
}
|
||||
@@ -1,465 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Demo for self study
|
||||
* <p>
|
||||
* Source from Author: CatVod
|
||||
*/
|
||||
|
||||
public class Imaple extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://imaple.co/";
|
||||
private static final String siteHost = "imaple.co";
|
||||
|
||||
protected JSONObject playerConfig;
|
||||
protected JSONObject filterConfig;
|
||||
|
||||
protected Pattern regexCategory = Pattern.compile("/type/(\\S+).html");
|
||||
protected Pattern regexVid = Pattern.compile("/vod/(\\d+).html");
|
||||
protected Pattern regexPlay = Pattern.compile("/play/(\\d+)-(\\d+)-(\\d+).html");
|
||||
protected Pattern regexPage = Pattern.compile("\\S+/page/(\\d+)\\S+");
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"kbm3u8\":{\"sh\":\"秒播雲\",\"sn\":0,\"pu\":\"\",\"or\":999},\"bjm3u8\":{\"sh\":\"八戒雲\",\"sn\":0,\"pu\":\"\",\"or\":999},\"605m3u8\":{\"sh\":\"光速雲\",\"sn\":0,\"pu\":\"\",\"or\":999},\"mlm3u8\":{\"sh\":\"藍光線一\",\"sn\":0,\"pu\":\"\",\"or\":999},\"alizy\":{\"sh\":\"藍光線三\",\"sn\":1,\"pu\":\"https://player.imaple.tv/player/?url=\",\"or\":999},\"dplayer\":{\"sh\":\"動漫專線\",\"sn\":1,\"pu\":\"https://player.imaple.tv/player/?url=\",\"or\":999},\"qdyun\":{\"sh\":\"驱动云\",\"sn\":0,\"pu\":\"\",\"or\":999},\"wjm3u8\":{\"sh\":\"理想雲\",\"sn\":0,\"pu\":\"\",\"or\":999},\"fanqie\":{\"sh\":\"番茄资源\",\"sn\":1,\"pu\":\"https://player.imaple.tv/player/?url=\",\"or\":999},\"youku\":{\"sh\":\"奇藝雲\",\"sn\":1,\"pu\":\"https://player.imaple.tv/player/?url=\",\"or\":999},\"qq\":{\"sh\":\"騰訊雲\",\"sn\":1,\"pu\":\"https://player.imaple.tv/player/?url=\",\"or\":999},\"mgtv\":{\"sh\":\"芒果雲\",\"sn\":1,\"pu\":\"https://player.imaple.tv/player/?url=\",\"or\":999},\"sohu\":{\"sh\":\"搜狐雲\",\"sn\":1,\"pu\":\"https://player.imaple.tv/player/?url=\",\"or\":999},\"88zym3u8\":{\"sh\":\"優雅雲\",\"sn\":1,\"pu\":\"https://player.imaple.tv/player/?url=\",\"or\":999},\"bilibili\":{\"sh\":\"嗶哩雲\",\"sn\":1,\"pu\":\"https://player.imaple.tv/player/?url=\",\"or\":999},\"dbm3u8\":{\"sh\":\"急速雲\",\"sn\":0,\"pu\":\"\",\"or\":999},\"tkm3u8\":{\"sh\":\"天空雲\",\"sn\":0,\"pu\":\"\",\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"1\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"動作片\",\"v\":\"6\"},{\"n\":\"喜劇片\",\"v\":\"7\"},{\"n\":\"愛情片\",\"v\":\"8\"},{\"n\":\"科幻片\",\"v\":\"9\"},{\"n\":\"恐怖片\",\"v\":\"10\"},{\"n\":\"劇情片\",\"v\":\"11\"},{\"n\":\"戰爭片\",\"v\":\"12\"},{\"n\":\"紀錄片\",\"v\":\"20\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陸\",\"v\":\"大陸\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台灣\",\"v\":\"台灣\"},{\"n\":\"美國\",\"v\":\"美國\"},{\"n\":\"法國\",\"v\":\"法國\"},{\"n\":\"英國\",\"v\":\"英國\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韓國\",\"v\":\"韓國\"},{\"n\":\"德國\",\"v\":\"德國\"},{\"n\":\"泰國\",\"v\":\"泰國\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陸劇\",\"v\":\"13\"},{\"n\":\"港劇\",\"v\":\"14\"},{\"n\":\"台劇\",\"v\":\"15\"},{\"n\":\"日劇\",\"v\":\"16\"},{\"n\":\"韓劇\",\"v\":\"23\"},{\"n\":\"美劇\",\"v\":\"24\"},{\"n\":\"海外劇\",\"v\":\"25\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"港台綜藝\",\"v\":\"29\"},{\"n\":\"日韓綜藝\",\"v\":\"30\"},{\"n\":\"大陸綜藝\",\"v\":\"31\"},{\"n\":\"歐美綜藝\",\"v\":\"32\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"港台動漫\",\"v\":\"33\"},{\"n\":\"日韓動漫\",\"v\":\"34\"},{\"n\":\"大陸動漫\",\"v\":\"35\"},{\"n\":\"歐美動漫\",\"v\":\"36\"},{\"n\":\"海外動漫\",\"v\":\"37\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
String url = siteUrl + '/';
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements elements = doc.select("ul.myui-header__menu>li>a");
|
||||
JSONArray classes = new JSONArray();
|
||||
ArrayList<String> allClass = new ArrayList<>();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
boolean show = !filter || (name.equals("電影") || name.equals("電視劇") || name.equals("綜藝") || name.equals("動漫"));
|
||||
if (allClass.contains(name))
|
||||
show = false;
|
||||
if (show) {
|
||||
allClass.add(name);
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
// 把分类的id和名称取出来加到列表里
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
// 取首页推荐视频列表
|
||||
Elements list = doc.select("li.col-lg-6 >div.myui-vodlist__box");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String url = siteUrl + "/show/";
|
||||
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||
url += extend.get("tid");
|
||||
} else {
|
||||
url += tid;
|
||||
}
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
if (value.length() > 0) {
|
||||
url += "/" + key + "/" + URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
url += "/page/" + pg + ".html";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
// 取页码相关信息
|
||||
Elements pageInfo = doc.select(".myui-page li a");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element a = pageInfo.get(i);
|
||||
String name = a.text();
|
||||
if (page == -1 && a.hasClass("btn-warm")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾頁")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
// 取当前分类页的视频列表
|
||||
Elements list = doc.select("li.col-lg-6 >div.myui-vodlist__box");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 48);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/vod/" + ids.get(0) + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String vid = doc.selectFirst("span.mac_hits").attr("data-id");
|
||||
|
||||
String cover = doc.selectFirst("a.myui-vodlist__thumb img").attr("data-original");
|
||||
String title = doc.selectFirst("div.myui-content__detail h1.title").text();
|
||||
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.myui-content__detail span.text-muted");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("分類:")) {
|
||||
category = text.nextElementSibling().text();
|
||||
} else if (info.equals("年份:")) {
|
||||
year = text.nextElementSibling().text();
|
||||
} else if (info.equals("地區:")) {
|
||||
area = text.nextElementSibling().text();
|
||||
} else if (info.equals("更新:")) {
|
||||
remark = text.nextElementSibling().text();
|
||||
} else if (info.equals("導演:")) {
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
directors.add(aa.get(j).text());
|
||||
}
|
||||
director = TextUtils.join(",", directors);
|
||||
} else if (info.equals("主演:")) {
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", vid);
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 取播放列表数据
|
||||
Elements sources = doc.select("div.myui-panel__head>ul").get(0).select("li");
|
||||
Elements sourceList = doc.select("div.tab-content>div.tab-pane");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.text();
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = sourceList.get(i).select("ul>li>a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
//定义播放用的headers
|
||||
JSONObject headers = new JSONObject();
|
||||
//headers.put("Host", " cokemv.co");
|
||||
headers.put("origin", " https://imaple.co");
|
||||
headers.put("User-Agent", " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", " */*");
|
||||
headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-US;q=0.3,en;q=0.7");
|
||||
headers.put("Accept-Encoding", " gzip, deflate");
|
||||
|
||||
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/play/" + id + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) { // 取直链
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", headers.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
if (quick)
|
||||
return "";
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
if (searchResult.getInt("total") > 0) {
|
||||
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||
for (int i = 0; i < lists.length(); i++) {
|
||||
JSONObject vod = lists.getJSONObject(i);
|
||||
String id = vod.getString("id");
|
||||
String title = vod.getString("name");
|
||||
String cover = vod.getString("pic");
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", "");
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,466 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Demo for self study
|
||||
* <p>
|
||||
* Source from Author: CatVod
|
||||
*/
|
||||
|
||||
public class Jumi extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://jumi.tv/";
|
||||
private static final String siteHost = "jumi.tv";
|
||||
|
||||
protected JSONObject playerConfig;
|
||||
protected JSONObject filterConfig;
|
||||
|
||||
protected Pattern regexCategory = Pattern.compile("/type/(\\S+).html");
|
||||
protected Pattern regexVid = Pattern.compile("/vod/(\\d+).html");
|
||||
protected Pattern regexPlay = Pattern.compile("/play/(\\d+)-(\\d+)-(\\d+).html");
|
||||
protected Pattern regexPage = Pattern.compile("\\S+/page/(\\d+)\\S+");
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"mlm3u8\":{\"sh\":\"極速①線\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"alizy\":{\"sh\":\"極速③線\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"weiyun\":{\"sh\":\"1080P\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"dbm3u8\":{\"sh\":\"急速雲\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"tkm3u8\":{\"sh\":\"天空雲\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"wjm3u8\":{\"sh\":\"無盡雲\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"605m3u8\":{\"sh\":\"光速雲\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"kbm3u8\":{\"sh\":\"秒播雲\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"bjm3u8\":{\"sh\":\"八戒雲\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"hnm3u8\":{\"sh\":\"紅牛雲\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"bdxm3u8\":{\"sh\":\"北鬥雲\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"youku\":{\"sh\":\"優酷雲\",\"sn\":1,\"pu\":\"https://www.mgtv.com.jumi.tv/player/?url=\",\"or\":999},\"mgtv\":{\"sh\":\"芒果雲\",\"sn\":1,\"pu\":\"https://www.mgtv.com.jumi.tv/player/?url=\",\"or\":999},\"88zym3u8\":{\"sh\":\"88雲\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"qiyi\":{\"sh\":\"奇藝雲\",\"sn\":1,\"pu\":\"https://www.mgtv.com.jumi.tv/player/?url=\",\"or\":999},\"dplayer\":{\"sh\":\"動漫專線\",\"sn\":1,\"pu\":\"https://jx.parwix.com:4433/aliplayer/?url=\",\"or\":999},\"qq\":{\"sh\":\"騰訊雲\",\"sn\":1,\"pu\":\"https://www.mgtv.com.jumi.tv/player/?url=\",\"or\":999},\"bilibili\":{\"sh\":\"嗶哩雲\",\"sn\":1,\"pu\":\"https://www.mgtv.com.jumi.tv/player/?url=\",\"or\":999},\"sohu\":{\"sh\":\"搜狐雲\",\"sn\":1,\"pu\":\"https://www.mgtv.com.jumi.tv/player/?url=\",\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"1\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"動作片\",\"v\":\"6\"},{\"n\":\"喜劇片\",\"v\":\"7\"},{\"n\":\"愛情片\",\"v\":\"8\"},{\"n\":\"科幻片\",\"v\":\"9\"},{\"n\":\"恐怖片\",\"v\":\"10\"},{\"n\":\"劇情片\",\"v\":\"11\"},{\"n\":\"戰爭片\",\"v\":\"12\"},{\"n\":\"紀錄片\",\"v\":\"20\"}]},{\"key\":\"class\",\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"驚悚\",\"v\":\"驚悚\"},{\"n\":\"懸疑\",\"v\":\"懸疑\"},{\"n\":\"魔幻\",\"v\":\"魔幻\"},{\"n\":\"罪案\",\"v\":\"罪案\"},{\"n\":\"災難\",\"v\":\"災難\"},{\"n\":\"動畫\",\"v\":\"動畫\"},{\"n\":\"古裝\",\"v\":\"古裝\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"歌舞\",\"v\":\"歌舞\"},{\"n\":\"文藝\",\"v\":\"文藝\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"歷史\",\"v\":\"歷史\"},{\"n\":\"勵志\",\"v\":\"勵志\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"愛情\",\"v\":\"愛情\"},{\"n\":\"喜劇\",\"v\":\"喜劇\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"動作\",\"v\":\"動作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"劇情\",\"v\":\"劇情\"},{\"n\":\"戰爭\",\"v\":\"戰爭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"武俠\",\"v\":\"武俠\"},{\"n\":\"冒險\",\"v\":\"冒險\"},{\"n\":\"經典\",\"v\":\"經典\"},{\"n\":\"兒童\",\"v\":\"兒童\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陸\",\"v\":\"大陸\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台灣\",\"v\":\"台灣\"},{\"n\":\"美國\",\"v\":\"美國\"},{\"n\":\"法國\",\"v\":\"法國\"},{\"n\":\"英國\",\"v\":\"英國\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韓國\",\"v\":\"韓國\"},{\"n\":\"德國\",\"v\":\"德國\"},{\"n\":\"泰國\",\"v\":\"泰國\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"陸劇\",\"v\":\"13\"},{\"n\":\"港劇\",\"v\":\"14\"},{\"n\":\"台劇\",\"v\":\"22\"},{\"n\":\"日劇\",\"v\":\"15\"},{\"n\":\"韓劇\",\"v\":\"23\"},{\"n\":\"美劇\",\"v\":\"16\"},{\"n\":\"海外劇\",\"v\":\"24\"}]},{\"key\":\"class\",\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"言情\",\"v\":\"言情\"},{\"n\":\"都市\",\"v\":\"都市\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"偶像\",\"v\":\"偶像\"},{\"n\":\"喜劇\",\"v\":\"喜劇\"},{\"n\":\"歷史\",\"v\":\"歷史\"},{\"n\":\"古裝\",\"v\":\"古裝\"},{\"n\":\"武俠\",\"v\":\"武俠\"},{\"n\":\"刑偵\",\"v\":\"刑偵\"},{\"n\":\"戰爭\",\"v\":\"戰爭\"},{\"n\":\"神話\",\"v\":\"神話\"},{\"n\":\"軍旅\",\"v\":\"軍旅\"},{\"n\":\"諜戰\",\"v\":\"諜戰\"},{\"n\":\"商戰\",\"v\":\"商戰\"},{\"n\":\"校園\",\"v\":\"校園\"},{\"n\":\"穿越\",\"v\":\"穿越\"},{\"n\":\"懸疑\",\"v\":\"懸疑\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"愛情\",\"v\":\"愛情\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陸\",\"v\":\"大陸\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台灣\",\"v\":\"台灣\"},{\"n\":\"美國\",\"v\":\"美國\"},{\"n\":\"法國\",\"v\":\"法國\"},{\"n\":\"英國\",\"v\":\"英國\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韓國\",\"v\":\"韓國\"},{\"n\":\"德國\",\"v\":\"德國\"},{\"n\":\"泰國\",\"v\":\"泰國\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":\"class\",\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"播报\",\"v\":\"播报\"},{\"n\":\"旅游\",\"v\":\"旅游\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"美食\",\"v\":\"美食\"},{\"n\":\"纪实\",\"v\":\"纪实\"},{\"n\":\"曲艺\",\"v\":\"曲艺\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"游戏互动\",\"v\":\"游戏互动\"},{\"n\":\"财经\",\"v\":\"财经\"},{\"n\":\"求职\",\"v\":\"求职\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":\"class\",\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国产\",\"v\":\"国产\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
String url = siteUrl + '/';
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements elements = doc.select("ul.nav-menu>li>a");
|
||||
JSONArray classes = new JSONArray();
|
||||
ArrayList<String> allClass = new ArrayList<>();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
boolean show = !filter || (name.equals("電影") || name.equals("劇集") || name.equals("綜藝") || name.equals("動漫"));
|
||||
if (allClass.contains(name))
|
||||
show = false;
|
||||
if (show) {
|
||||
allClass.add(name);
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
// 把分类的id和名称取出来加到列表里
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
// 取首页推荐视频列表
|
||||
Elements list = doc.select("div.col-lg-wide-75 > ul.myui-vodlist li div.myui-vodlist__box");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String url = siteUrl + "/show/";
|
||||
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||
url += extend.get("tid");
|
||||
} else {
|
||||
url += tid;
|
||||
}
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
if (value.length() > 0) {
|
||||
url += "/" + key + "/" + URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
url += "/page/" + pg + ".html";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
// 取页码相关信息
|
||||
Elements pageInfo = doc.select(".myui-page li a");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element a = pageInfo.get(i);
|
||||
String name = a.text();
|
||||
if (page == -1 && a.hasClass("btn-warm")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾页")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
// 取当前分类页的视频列表
|
||||
Elements list = doc.select("ul.myui-vodlist li div.myui-vodlist__box");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 48);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/vod/" + ids.get(0) + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String vid = doc.selectFirst("span.mac_hits").attr("data-id");
|
||||
|
||||
String cover = doc.selectFirst("a.myui-vodlist__thumb img").attr("data-original");
|
||||
String title = doc.selectFirst("div.myui-content__detail h1.title").text();
|
||||
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.myui-content__detail span.text-muted");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("分类:")) {
|
||||
category = text.nextElementSibling().text();
|
||||
} else if (info.equals("年份:")) {
|
||||
year = text.nextElementSibling().text();
|
||||
} else if (info.equals("地区:")) {
|
||||
area = text.nextElementSibling().text();
|
||||
} else if (info.equals("更新:")) {
|
||||
remark = text.nextElementSibling().text();
|
||||
} else if (info.equals("导演:")) {
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
directors.add(aa.get(j).text());
|
||||
}
|
||||
director = TextUtils.join(",", directors);
|
||||
} else if (info.equals("主演:")) {
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", vid);
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 取播放列表数据
|
||||
Elements sources = doc.select("div.myui-panel__head>ul").get(0).select("li");
|
||||
Elements sourceList = doc.select("div.tab-content>div.tab-pane");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.text();
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = sourceList.get(i).select("ul>li>a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
//定义播放用的headers
|
||||
JSONObject headers = new JSONObject();
|
||||
//headers.put("Host", " cokemv.co");
|
||||
headers.put("origin", " https://jumi.tv");
|
||||
headers.put("User-Agent", " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", " */*");
|
||||
headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-US;q=0.3,en;q=0.7");
|
||||
headers.put("Accept-Encoding", " gzip, deflate");
|
||||
headers.put("referer", " https://jumi.tv/");
|
||||
|
||||
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/play/" + id + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) { // 取直链
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", headers.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
if (quick)
|
||||
return "";
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
if (searchResult.getInt("total") > 0) {
|
||||
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||
for (int i = 0; i < lists.length(); i++) {
|
||||
JSONObject vod = lists.getJSONObject(i);
|
||||
String id = vod.getString("id");
|
||||
String title = vod.getString("name");
|
||||
String cover = vod.getString("pic");
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", "");
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,471 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 90影视
|
||||
* <p>
|
||||
* Author: 小黄瓜
|
||||
*/
|
||||
public class N0ys extends Spider {
|
||||
private static final String siteUrl = "http://1090ys8.com";
|
||||
private static final String siteHost = "1090ys8.com";
|
||||
private static final String ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36";
|
||||
|
||||
/**
|
||||
* 播放源配置
|
||||
*/
|
||||
private JSONObject playerConfig;
|
||||
|
||||
private Pattern regexCategory = Pattern.compile("/whole/(\\w+).html");
|
||||
private Pattern regexVid = Pattern.compile("/show/(\\w+).html");
|
||||
private Pattern regexPlay = Pattern.compile("/play/(\\w+)-(\\d+)-(\\d+).html");
|
||||
private Pattern regexPage = Pattern.compile("/whole/\\d+/page/(\\d+).html");
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"youbo\":{\"sh\":\"高速1\",\"sn\":\"0\",\"pu\":\"http://jx1090ys5.hongfanedu.top/x2.php?id=\",\"or\":999},\"wanpan\":{\"sh\":\"高速备用\",\"sn\":\"0\",\"pu\":\"\",\"or\":999},\"niuxyun\":{\"sh\":\"高速2\",\"sn\":\"1\",\"pu\":\"http://1090ys2.com/nxjx/jx.php?id=\",\"or\":999},\"bjm3u8\":{\"sh\":\"备用2\",\"sn\":\"0\",\"pu\":\"\",\"or\":999},\"dbm3u8\":{\"sh\":\"备用3\",\"sn\":\"0\",\"pu\":\"\",\"or\":999},\"nfmp4\":{\"sh\":\"高速3\",\"sn\":\"0\",\"pu\":\"\",\"or\":999},\"tkm3u8\":{\"sh\":\"备用1\",\"sn\":\"0\",\"pu\":\"\",\"or\":999},\"wjm3u8\":{\"sh\":\"备用4\",\"sn\":\"0\",\"pu\":\"\",\"or\":999}}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", ua);
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||
// 分类节点
|
||||
Elements elements = doc.select("ul.type-slide > li a");
|
||||
JSONArray classes = new JSONArray();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("class", classes);
|
||||
try {
|
||||
Elements list = doc.select("div.stui-pannel_bd ul.stui-vodlist li div.stui-vodlist__box");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".stui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".stui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
// 获取分类数据的url
|
||||
String url = siteUrl + "/whole/" + tid + "/page/" + pg + ".html";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
Elements pageInfo = doc.select(".stui-page li");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element li = pageInfo.get(i);
|
||||
Element a = li.selectFirst("a");
|
||||
if (a == null)
|
||||
continue;
|
||||
String name = a.text();
|
||||
if (page == -1 && li.hasClass("active")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1));
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾页")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1));
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
Elements list = doc.select("ul.stui-vodlist li div.stui-vodlist__box");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".stui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".stui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 30);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 30);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/show/" + ids.get(0) + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String cover = doc.selectFirst("a.stui-vodlist__thumb img").attr("data-original");
|
||||
String title = doc.selectFirst("a.stui-vodlist__thumb").attr("title");
|
||||
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.stui-content__detail span.text-muted");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("类型:")) {
|
||||
category = text.nextSibling().outerHtml().trim();
|
||||
} else if (info.equals("年份:")) {
|
||||
year = text.nextSibling().outerHtml().trim();
|
||||
} else if (info.equals("地区:")) {
|
||||
area = text.nextSibling().outerHtml().trim();
|
||||
} else if (info.equals("更新:")) {
|
||||
remark = text.nextSibling().outerHtml().trim();
|
||||
} else if (info.equals("导演:")) {
|
||||
director = text.nextSibling().outerHtml().trim();
|
||||
} else if (info.equals("主演:")) {
|
||||
actor = text.nextSibling().outerHtml().trim();
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", ids.get(0));
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
Elements sources = doc.select("div.playlist");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.selectFirst("h3.title").text().trim();
|
||||
String tabHref = source.attr("href");
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = source.select("ul.stui-content__playlist > li > a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
// 播放页 url
|
||||
String url = "http://1090ys8.com/play/" + id + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) {
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
String from = player.getString("from");
|
||||
if (from.equals("youbo")) {
|
||||
// 感谢猫大神的直连解密代码
|
||||
HashMap<String, String> hds = getHeaders(url);
|
||||
hds.put("Host", "jx1090ys5.hongfanedu.top");
|
||||
hds.put("Referer", url);
|
||||
String content1 = OkHttpUtil.string(playUrl + videoUrl, hds);
|
||||
Document doc1 = Jsoup.parse(content1);
|
||||
String url2 = doc1.selectFirst("iframe#WANG").attr("src");
|
||||
String url2host = Uri.parse(url2).getHost();
|
||||
hds.put("Host", url2host);
|
||||
hds.put("Referer", "http://jx1090ys5.hongfanedu.top/");
|
||||
String content2 = OkHttpUtil.string(url2, hds);
|
||||
String finder = "var id=\"";
|
||||
start = content2.indexOf(finder) + finder.length();
|
||||
end = content2.indexOf('\"', start);
|
||||
String vvid = content2.substring(start, end);
|
||||
finder = "var sk=\"";
|
||||
start = content2.indexOf(finder) + finder.length();
|
||||
end = content2.indexOf('\"', start);
|
||||
String skey = content2.substring(start, end);
|
||||
finder = "var pt=\"";
|
||||
start = content2.indexOf(finder) + finder.length();
|
||||
end = content2.indexOf('\"', start);
|
||||
String pt = content2.substring(start, end);
|
||||
finder = "var ti=\"";
|
||||
start = content2.indexOf(finder) + finder.length();
|
||||
end = content2.indexOf('\"', start);
|
||||
String time = content2.substring(start, end);
|
||||
int bkn = 0x195c;
|
||||
for (int j = 0x0, all = skey.length(); all > j; ++j) {
|
||||
bkn += ((bkn << 5) + (byte) skey.charAt(j));
|
||||
}
|
||||
bkn = 0x7fffffff & bkn;
|
||||
int gtk1 = 0x0;
|
||||
for (int j = 0x0; j < pt.length(); j += 0x4) {
|
||||
gtk1 += Integer.parseInt(String.format("%c%c%c%c", pt.charAt(j), pt.charAt(j + 0x1), pt.charAt(j + 0x2), pt.charAt(j + 0x3)), 0x10);
|
||||
gtk1 %= 0x400a;
|
||||
}
|
||||
int offset = gtk1 % 10;
|
||||
int gtk = 0x0;
|
||||
for (int j = 0x0; j < pt.length(); j++) {
|
||||
gtk += ((byte) pt.charAt(j)) * (j + offset);
|
||||
gtk %= gtk1;
|
||||
}
|
||||
String finalVideoUrl = "http://" + url2host + "/hls/play/" + vvid + "%7C" + time + "%7C" + skey + "%7C" + pt + "%7C" + bkn + "%7C" + gtk + ".m3u8";
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", "");
|
||||
result.put("url", finalVideoUrl);
|
||||
result.put("header", "{\"Referer\":\" " + url2 + "\"}");
|
||||
} else {
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
*
|
||||
* @param key
|
||||
* @param quick 是否播放页的快捷搜索
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
if (searchResult.getInt("total") > 0) {
|
||||
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||
for (int i = 0; i < lists.length(); i++) {
|
||||
JSONObject vod = lists.getJSONObject(i);
|
||||
String id = vod.getString("id");
|
||||
String title = vod.getString("name");
|
||||
String cover = vod.getString("pic");
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", "");
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,489 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
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.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.Response;
|
||||
|
||||
|
||||
public class Nekk extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://www.9ela.com";
|
||||
private static final String siteHost = "www.9ela.com";
|
||||
|
||||
protected JSONObject playerConfig;
|
||||
protected JSONObject filterConfig;
|
||||
|
||||
protected Pattern regexCategory = Pattern.compile("/vodshow/(\\S+).html");
|
||||
protected Pattern regexVid = Pattern.compile("/voddetail/(\\d+).html");
|
||||
protected Pattern regexPlay = Pattern.compile("/vodplay/(\\d+)-(\\d+)-(\\d+).html");
|
||||
protected Pattern regexPage = Pattern.compile("\\S+/page/(\\d+)\\S+");
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"9ekk\":{\"sh\":\"手机线路\",\"sn\":0,\"pu\":\"\",\"or\":999},\"ttee\":{\"sh\":\"9亿超清\",\"sn\":0,\"pu\":\"\",\"or\":999},\"9999ku\":{\"sh\":\"手机线路2\",\"sn\":0,\"pu\":\"\",\"or\":999},\"gsyun\":{\"sh\":\"九亿超清\",\"sn\":0,\"pu\":\"\",\"or\":999},\"kkyun\":{\"sh\":\"HD超清线路\",\"sn\":0,\"pu\":\"\",\"or\":999},\"ty01\":{\"sh\":\"超清线路\",\"sn\":0,\"pu\":\"\",\"or\":999},\"ppayun\":{\"sh\":\"九亿线路\",\"sn\":0,\"pu\":\"https://wy.mlkioiy.cn/api/GetDownUrlWy/d91ea50eb7eb4932b92aa8bb3c61560d/\",\"or\":999},\"8kdm\":{\"sh\":\"九亿动漫\",\"sn\":0,\"pu\":\"\",\"or\":999},\"jsyun\":{\"sh\":\"九亿备用\",\"sn\":0,\"pu\":\"\",\"or\":999},\"9evip\":{\"sh\":\"九亿解析-弃用\",\"sn\":0,\"pu\":\"\",\"or\":999},\"189pan\":{\"sh\":\"九亿超清11\",\"sn\":0,\"pu\":\"http://1987s.com/api/dp.php?url=\",\"or\":999},\"VIP\":{\"sh\":\"VIP线路\",\"sn\":0,\"pu\":\"\",\"or\":999},\"qq\":{\"sh\":\"九亿解析\",\"sn\":1,\"pu\":\"\",\"or\":999},\"mgtv\":{\"sh\":\"九亿解析\",\"sn\":1,\"pu\":\"\",\"or\":999},\"bjm3u8\":{\"sh\":\"线路三\",\"sn\":0,\"pu\":\"\",\"or\":999},\"dbm3u8\":{\"sh\":\"线路四\",\"sn\":0,\"pu\":\"\",\"or\":999},\"ckm3u8\":{\"sh\":\"线路二\",\"sn\":0,\"pu\":\"\",\"or\":999},\"mahua\":{\"sh\":\"线路四\",\"sn\":0,\"pu\":\"\",\"or\":999},\"123kum3u8\":{\"sh\":\"123kum3u8\",\"sn\":1,\"pu\":\"https://jx.123ku.com/123kudpbfq/?url=\",\"or\":999},\"pqc\":{\"sh\":\"测试\",\"sn\":1,\"pu\":\"https://jx.qiuzeqi.top/jx1/dp/index.php?url=\",\"or\":999},\"test\":{\"sh\":\"test\",\"sn\":1,\"pu\":\"https//1987s.com/api/dp.php?url=\",\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"dianying\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语配音电影\",\"v\":\"gypy\"},{\"n\":\"最近热播电影\",\"v\":\"zuijinrebodianying\"},{\"n\":\"动作片\",\"v\":\"dongzuopian\"},{\"n\":\"喜剧片\",\"v\":\"xijupian\"},{\"n\":\"爱情片\",\"v\":\"aiqingpian\"},{\"n\":\"科幻片\",\"v\":\"kehuanpian\"},{\"n\":\"恐怖片\",\"v\":\"kongbupian\"},{\"n\":\"剧情片\",\"v\":\"juqingpian\"},{\"n\":\"战争片\",\"v\":\"zhanzhengpian\"}]},{\"key\":\"class\",\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动画\",\"v\":\"动画\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"枪战\",\"v\":\"枪战\"},{\"n\":\"恐怖\",\"v\":\"恐怖\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"文艺\",\"v\":\"文艺\"},{\"n\":\"微电影\",\"v\":\"微电影\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"农村\",\"v\":\"农村\"},{\"n\":\"儿童\",\"v\":\"儿童\"},{\"n\":\"网络电影\",\"v\":\"网络电影\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"中国香港\",\"v\":\"中国香港\"},{\"n\":\"中国台湾\",\"v\":\"中国台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"},{\"n\":\"热门\",\"v\":\"热门\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"lianxuju\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"最近热播电视剧\",\"v\":\"zuijinrebodianshiju\"},{\"n\":\"国语配音剧集\",\"v\":\"guoyupeiyinhanju\"},{\"n\":\"热播美剧\",\"v\":\"rebomeiju\"},{\"n\":\"电视剧\",\"v\":\"guochanju\"},{\"n\":\"港台剧\",\"v\":\"gangtaiju\"},{\"n\":\"日韩剧\",\"v\":\"rihanju\"},{\"n\":\"欧美剧\",\"v\":\"oumeiju\"}]},{\"key\":\"class\",\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"青春偶像\",\"v\":\"青春偶像\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"犯罪\",\"v\":\"犯罪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"经典\",\"v\":\"经典\"},{\"n\":\"乡村\",\"v\":\"乡村\"},{\"n\":\"情景\",\"v\":\"情景\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"网剧\",\"v\":\"网剧\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"zongyi\":[{\"key\":\"class\",\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"播报\",\"v\":\"播报\"},{\"n\":\"旅游\",\"v\":\"旅游\"},{\"n\":\"音乐\",\"v\":\"音乐\"},{\"n\":\"美食\",\"v\":\"美食\"},{\"n\":\"纪实\",\"v\":\"纪实\"},{\"n\":\"曲艺\",\"v\":\"曲艺\"},{\"n\":\"生活\",\"v\":\"生活\"},{\"n\":\"游戏互动\",\"v\":\"游戏互动\"},{\"n\":\"财经\",\"v\":\"财经\"},{\"n\":\"求职\",\"v\":\"求职\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"中国大陆\",\"v\":\"中国大陆\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"dongman\":[{\"key\":\"class\",\"name\":\"剧情\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"萝莉\",\"v\":\"萝莉\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"运动\",\"v\":\"运动\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"少年\",\"v\":\"少年\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"社会\",\"v\":\"社会\"},{\"n\":\"原创\",\"v\":\"原创\"},{\"n\":\"亲子\",\"v\":\"亲子\"},{\"n\":\"益智\",\"v\":\"益智\"},{\"n\":\"励志\",\"v\":\"励志\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国产\",\"v\":\"国产\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36");
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
String url = siteUrl + '/';
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements elements = doc.select("ul.nav-list > li a");
|
||||
JSONArray classes = new JSONArray();
|
||||
ArrayList<String> allClass = new ArrayList<>();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
boolean show = !filter || (name.equals("电影") || name.equals("连续剧") || name.equals("综艺") || name.equals("动漫"));
|
||||
if (allClass.contains(name))
|
||||
show = false;
|
||||
if (show) {
|
||||
allClass.add(name);
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
Elements list = doc.select("div.col-lg-wide-75 > ul.myui-vodlist li div.myui-vodlist__box");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = fixCover(vod.selectFirst(".myui-vodlist__thumb").attr("data-original"));
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String url = siteUrl + "/vodshow/";
|
||||
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||
url += extend.get("tid");
|
||||
} else {
|
||||
url += tid;
|
||||
}
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
if (value.length() > 0) {
|
||||
url += "/" + key + "/" + URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
url += "/page/" + pg + ".html";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
Elements pageInfo = doc.select(".myui-page li a");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element a = pageInfo.get(i);
|
||||
String name = a.text();
|
||||
if (page == -1 && a.hasClass("btn-warm")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾页")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
Elements list = doc.select("ul.myui-vodlist li div.myui-vodlist__box");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = fixCover(vod.selectFirst(".myui-vodlist__thumb").attr("data-original"));
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 48);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
String url = siteUrl + "/voddetail/" + ids.get(0) + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
String vid = doc.selectFirst("span.mac_hits").attr("data-id");
|
||||
|
||||
String cover = fixCover(doc.selectFirst("a.myui-vodlist__thumb img").attr("data-original"));
|
||||
String title = doc.selectFirst("div.myui-content__detail h1.title").text();
|
||||
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.myui-content__detail span.text-muted");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("分类:")) {
|
||||
category = text.nextElementSibling().text();
|
||||
} else if (info.equals("年份:")) {
|
||||
year = text.nextElementSibling().text();
|
||||
} else if (info.equals("地区:")) {
|
||||
area = text.nextElementSibling().text();
|
||||
} else if (info.equals("更新:")) {
|
||||
remark = text.nextElementSibling().text();
|
||||
} else if (info.equals("导演:")) {
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
directors.add(aa.get(j).text());
|
||||
}
|
||||
director = TextUtils.join(",", directors);
|
||||
} else if (info.equals("主演:")) {
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", vid);
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
Elements sources = doc.select("a[data-toggle=tab]");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.text();
|
||||
String tabHref = source.attr("href");
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = doc.select("div" + tabHref + " ul > li a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
String url = siteUrl + "/vodplay/" + id + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) {
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
if (player.has("encrypt")) {
|
||||
int encrypt = player.getInt("encrypt");
|
||||
if (encrypt == 1) {
|
||||
videoUrl = URLDecoder.decode(videoUrl);
|
||||
} else if (encrypt == 2) {
|
||||
videoUrl = new String(Base64.decode(videoUrl, Base64.DEFAULT));
|
||||
videoUrl = URLDecoder.decode(videoUrl);
|
||||
}
|
||||
}
|
||||
String playUrl = pCfg.getString("pu");
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
if (flag.equals("9ekk")) {
|
||||
JSONObject headers = new JSONObject();
|
||||
headers.put("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36");
|
||||
headers.put("Accept", " */*");
|
||||
headers.put("Connection", " keep-alive");
|
||||
result.put("header", headers.toString());
|
||||
} else {
|
||||
result.put("header", "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
if (quick)
|
||||
return "";
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
if (searchResult.getInt("total") > 0) {
|
||||
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||
for (int i = 0; i < lists.length(); i++) {
|
||||
JSONObject vod = lists.getJSONObject(i);
|
||||
String id = vod.getString("id");
|
||||
String title = vod.getString("name");
|
||||
String cover = fixCover(vod.getString("pic"));
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", "");
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
protected String fixCover(String cover) {
|
||||
try {
|
||||
return "proxy://do=nekk&pic=" + Base64.encodeToString(cover.getBytes("UTF-8"), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return cover;
|
||||
}
|
||||
|
||||
private static HashMap<String, String> nekkPicHeader = null;
|
||||
|
||||
public static Object[] loadPic(String pic) {
|
||||
try {
|
||||
pic = new String(Base64.decode(pic, Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP), "UTF-8");
|
||||
|
||||
if (nekkPicHeader == null) {
|
||||
nekkPicHeader = new HashMap<>();
|
||||
nekkPicHeader.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36");
|
||||
nekkPicHeader.put("referer", siteUrl + "/");
|
||||
}
|
||||
OKCallBack.OKCallBackDefault callBack = new OKCallBack.OKCallBackDefault() {
|
||||
@Override
|
||||
protected void onFailure(Call call, Exception e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResponse(Response response) {
|
||||
|
||||
}
|
||||
};
|
||||
OkHttpUtil.get(OkHttpUtil.defaultClient(), pic, null, nekkPicHeader, callBack);
|
||||
if (callBack.getResult().code() == 200) {
|
||||
Headers headers = callBack.getResult().headers();
|
||||
String type = headers.get("Content-Type");
|
||||
if (type == null) {
|
||||
type = "application/octet-stream";
|
||||
}
|
||||
Object[] result = new Object[3];
|
||||
result[0] = 200;
|
||||
result[1] = type;
|
||||
System.out.println(pic);
|
||||
System.out.println(type);
|
||||
result[2] = callBack.getResult().body().byteStream();
|
||||
return result;
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
th.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,449 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Demo for self study
|
||||
* <p>
|
||||
* Source from Author: CatVod
|
||||
*/
|
||||
|
||||
public class Nfx extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://nfxhd.com/";
|
||||
private static final String siteHost = "nfxhd.com";
|
||||
|
||||
protected JSONObject playerConfig;
|
||||
|
||||
protected Pattern regexCategory = Pattern.compile("/vodtype/(\\w+)/");
|
||||
protected Pattern regexVid = Pattern.compile("/voddetail/(\\w+)/");
|
||||
protected Pattern regexPlay = Pattern.compile("/vodplay/(\\w+)-(\\d+)-(\\d+)/");
|
||||
protected Pattern regexPage = Pattern.compile("/vodshow/(\\S+)/");
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"adaplay\":{\"sh\":\"菜逼播放器\",\"sn\":\"1\",\"pu\":\"https://nfxhd.com/dp.php/?url=\",\"or\":999},\"xigua\":{\"sh\":\"手动点播放才能播放的播放器\",\"sn\":\"1\",\"pu\":\"https://nfxhd.com/dp.php/?url=\",\"or\":999},\"danmuku\":{\"sh\":\"海王播放器\",\"sn\":\"1\",\"pu\":\"\",\"or\":999},\"dplayer\":{\"sh\":\"冥王星播放器\",\"sn\":\"0\",\"pu\":\"\",\"or\":999},\"bdxm3u8\":{\"sh\":\"北斗星m3u8\",\"sn\":\"1\",\"pu\":\"https://player.bdxzym3u8.com/dplayer/?url=\",\"or\":999},\"bdxyun\":{\"sh\":\"北斗星云播放\",\"sn\":\"1\",\"pu\":\"\",\"or\":999},\"gangtiexia\":{\"sh\":\"土星播放器\",\"sn\":\"1\",\"pu\":\"https://wy.bigmao.top/api/ShowVideoWy/3bb24322f78b47dfb8723c13d46d45ee/\",\"or\":999},\"tt10\":{\"sh\":\"木星播放器\",\"sn\":\"1\",\"pu\":\"https://wy.bigmao.top/api/ShowVideoMu/3bb24322f78b47dfb8723c13d46d45ee/\",\"or\":999},\"docker\":{\"sh\":\"彗星播放器\",\"sn\":\"1\",\"pu\":\"https://wy.bigmao.top/api/ShowVideoDoc/3bb24322f78b47dfb8723c13d46d45ee/\",\"or\":999},\"qq\":{\"sh\":\"腾讯视频\",\"sn\":\"1\",\"pu\":\"\",\"or\":999},\"youku\":{\"sh\":\"优酷\",\"sn\":\"1\",\"pu\":\"\",\"or\":999},\"qiyi\":{\"sh\":\"爱奇艺\",\"sn\":\"1\",\"pu\":\"\",\"or\":999},\"mgtv\":{\"sh\":\"仅限APP播放\",\"sn\":\"1\",\"pu\":\"\",\"or\":999},\"m3u8\":{\"sh\":\"m3u8\",\"sn\":\"1\",\"pu\":\"\",\"or\":999},\"mx771\":{\"sh\":\"站长采集的播放器\",\"sn\":\"0\",\"pu\":\"\",\"or\":999},\"ppayun2\":{\"sh\":\"白鸟座播放器\",\"sn\":\"1\",\"pu\":\"https://wy.bigmao.top/api/ShowVideoMu/3bb24322f78b47dfb8723c13d46d45ee/\",\"or\":999},\"sohu\":{\"sh\":\"搜狐\",\"sn\":\"1\",\"pu\":\"\",\"or\":999},\"iframe\":{\"sh\":\"iframe外链数据\",\"sn\":\"0\",\"pu\":\"\",\"or\":999}}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
String url = siteUrl;
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements elements = doc.select("ul.nav-menu>li>a");
|
||||
JSONArray classes = new JSONArray();
|
||||
ArrayList<String> allClass = new ArrayList<>();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
boolean show = !filter || (name.equals("电影") || name.equals("美剧") || name.equals("日韩") || name.equals("动漫"));
|
||||
if (allClass.contains(name))
|
||||
show = false;
|
||||
if (show) {
|
||||
allClass.add(name);
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
// 把分类的id和名称取出来加到列表里
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("class", classes);
|
||||
try {
|
||||
// 取首页推荐视频列表
|
||||
Elements list = doc.select("ul.myui-vodlist>li>div");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
// 获取分类数据的url
|
||||
String url = siteUrl + "/vodtype/" + tid + "-" + pg + "/";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
// 取页码相关信息
|
||||
Elements pageInfo = doc.select("ul.myui-page>li");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element li = pageInfo.get(i);
|
||||
Element a = li.selectFirst("a");
|
||||
if (a == null)
|
||||
continue;
|
||||
String name = a.text();
|
||||
if (page == -1 && a.hasClass("btn-warm")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾页")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
// 取当前分类页的视频列表
|
||||
Elements list = doc.select("div.myui-panel_bd>ul>li>div");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 48);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/voddetail/" + ids.get(0) + "/";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String vid = doc.selectFirst("span.mac_hits").attr("data-id");
|
||||
|
||||
String cover = doc.selectFirst("a.myui-vodlist__thumb img").attr("data-original");
|
||||
String title = doc.selectFirst("div.myui-content__detail h1.title").text();
|
||||
String desc = doc.selectFirst("div.col-pd>span.sketch").text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.myui-content__detail span.text-muted");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("分类:")) {
|
||||
category = text.nextElementSibling().text();
|
||||
} else if (info.equals("年份:")) {
|
||||
year = text.nextElementSibling().text();
|
||||
} else if (info.equals("地区:")) {
|
||||
area = text.nextElementSibling().text();
|
||||
} else if (info.equals("更新:")) {
|
||||
remark = text.nextElementSibling().text();
|
||||
} else if (info.equals("导演:")) {
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
directors.add(aa.get(j).text());
|
||||
}
|
||||
} else if (info.equals("主演:")) {
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", vid);
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 取播放列表数据
|
||||
Elements sources = doc.select("div.myui-panel__head").get(1).select("h3");
|
||||
Elements sourceList = doc.select("ul.myui-content__list");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.text();
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = sourceList.get(i).select("li>a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
//定义播放用的headers
|
||||
JSONObject headers = new JSONObject();
|
||||
//headers.put("Host", " cokemv.co");
|
||||
headers.put("origin", " https://nfxhd.com");
|
||||
headers.put("User-Agent", " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", " */*");
|
||||
headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-US;q=0.3,en;q=0.7");
|
||||
headers.put("Accept-Encoding", " gzip, deflate");
|
||||
|
||||
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/vodplay/" + id + "/";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) { // 取直链
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", headers.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
if (quick)
|
||||
return "";
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
if (searchResult.getInt("total") > 0) {
|
||||
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||
for (int i = 0; i < lists.length(); i++) {
|
||||
JSONObject vod = lists.getJSONObject(i);
|
||||
String id = vod.getString("id");
|
||||
String title = vod.getString("name");
|
||||
String cover = vod.getString("pic");
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", "");
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,503 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.Misc;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Olevod extends Spider {
|
||||
private static final String siteUrl = "https://olevod.com";
|
||||
private static final String siteHost = "olevod.com";
|
||||
|
||||
|
||||
boolean pron = false;
|
||||
/**
|
||||
* 播放源配置
|
||||
*/
|
||||
private JSONObject playerConfig;
|
||||
/**
|
||||
* 筛选配置
|
||||
*/
|
||||
private JSONObject filterConfig;
|
||||
private Pattern regexCategory = Pattern.compile("/index.php/vod/type/id/(\\d+).html");
|
||||
private Pattern regexVid = Pattern.compile("/index.php/vod/detail/id/(\\d+).html");
|
||||
private Pattern regexPlay = Pattern.compile("/index.php/vod/play/id/(\\d+)/sid/(\\d+)/nid/(\\d+).html");
|
||||
private Pattern regexPage = Pattern.compile("\\S+/page/(\\d+)\\S+");
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
super.init(context, extend);
|
||||
if (extend != null && extend.trim().equals("ojbkporn")) {
|
||||
pron = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"plyr\":{\"sh\":\"欧乐官方播放器\",\"sn\":0,\"pu\":\"\",\"or\":999},\"openplayer\":{\"sh\":\"欧乐影院\",\"sn\":0,\"pu\":\"\",\"or\":999},\"videojs\":{\"sh\":\"欧乐直播播放\",\"sn\":0,\"pu\":\"\",\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"1\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"动作片\",\"v\":\"101\"},{\"n\":\"喜剧片\",\"v\":\"102\"},{\"n\":\"爱情片\",\"v\":\"103\"},{\"n\":\"科幻片\",\"v\":\"104\"},{\"n\":\"恐怖片\",\"v\":\"105\"},{\"n\":\"剧情片\",\"v\":\"106\"},{\"n\":\"战争片\",\"v\":\"107\"},{\"n\":\"动画片\",\"v\":\"108\"},{\"n\":\"悬疑片\",\"v\":\"109\"},{\"n\":\"惊悚片\",\"v\":\"110\"},{\"n\":\"纪录片\",\"v\":\"111\"},{\"n\":\"奇幻片\",\"v\":\"112\"},{\"n\":\"犯罪片\",\"v\":\"113\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"俄罗斯\",\"v\":\"俄罗斯\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"马来西亚\",\"v\":\"马来西亚\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"西语\",\"v\":\"西语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印地语\",\"v\":\"印地语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}],\"2\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国产剧\",\"v\":\"202\"},{\"n\":\"欧美剧\",\"v\":\"201\"},{\"n\":\"港台剧\",\"v\":\"203\"},{\"n\":\"日韩剧\",\"v\":\"204\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"俄罗斯\",\"v\":\"俄罗斯\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"马来西亚\",\"v\":\"马来西亚\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"西语\",\"v\":\"西语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印地语\",\"v\":\"印地语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}],\"3\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"真人秀\",\"v\":\"305\"},{\"n\":\"音乐\",\"v\":\"302\"},{\"n\":\"搞笑\",\"v\":\"304\"},{\"n\":\"家庭\",\"v\":\"301\"},{\"n\":\"曲艺\",\"v\":\"303\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"俄罗斯\",\"v\":\"俄罗斯\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"马来西亚\",\"v\":\"马来西亚\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"西语\",\"v\":\"西语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印地语\",\"v\":\"印地语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}],\"4\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"日本\",\"v\":\"401\"},{\"n\":\"国产\",\"v\":\"402\"},{\"n\":\"欧美\",\"v\":\"403\"}]},{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"俄罗斯\",\"v\":\"俄罗斯\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"新加坡\",\"v\":\"新加坡\"},{\"n\":\"马来西亚\",\"v\":\"马来西亚\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"西语\",\"v\":\"西语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"俄语\",\"v\":\"俄语\"},{\"n\":\"意大利语\",\"v\":\"意大利语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"印地语\",\"v\":\"印地语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}],\"5\":[{\"key\":\"tid\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"AV女优\",\"v\":\"505\"},{\"n\":\"日韩\",\"v\":\"502\"},{\"n\":\"欧美\",\"v\":\"501\"},{\"n\":\"动漫\",\"v\":\"503\"},{\"n\":\"国产\",\"v\":\"504\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"},{\"n\":\"2003\",\"v\":\"2003\"},{\"n\":\"2002\",\"v\":\"2002\"},{\"n\":\"2001\",\"v\":\"2001\"},{\"n\":\"2000\",\"v\":\"2000\"}]},{\"key\":\"letter\",\"name\":\"字母\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"A\",\"v\":\"A\"},{\"n\":\"B\",\"v\":\"B\"},{\"n\":\"C\",\"v\":\"C\"},{\"n\":\"D\",\"v\":\"D\"},{\"n\":\"E\",\"v\":\"E\"},{\"n\":\"F\",\"v\":\"F\"},{\"n\":\"G\",\"v\":\"G\"},{\"n\":\"H\",\"v\":\"H\"},{\"n\":\"I\",\"v\":\"I\"},{\"n\":\"J\",\"v\":\"J\"},{\"n\":\"K\",\"v\":\"K\"},{\"n\":\"L\",\"v\":\"L\"},{\"n\":\"M\",\"v\":\"M\"},{\"n\":\"N\",\"v\":\"N\"},{\"n\":\"O\",\"v\":\"O\"},{\"n\":\"P\",\"v\":\"P\"},{\"n\":\"Q\",\"v\":\"Q\"},{\"n\":\"R\",\"v\":\"R\"},{\"n\":\"S\",\"v\":\"S\"},{\"n\":\"T\",\"v\":\"T\"},{\"n\":\"U\",\"v\":\"U\"},{\"n\":\"V\",\"v\":\"V\"},{\"n\":\"W\",\"v\":\"W\"},{\"n\":\"X\",\"v\":\"X\"},{\"n\":\"Y\",\"v\":\"Y\"},{\"n\":\"Z\",\"v\":\"Z\"}]},{\"key\":\"ifvip\",\"name\":\"权限\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"免费\",\"v\":\"2\"},{\"n\":\"会员\",\"v\":\"3\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||
// 分类节点
|
||||
Elements elements = doc.select("ul.top_nav li a");
|
||||
JSONArray classes = new JSONArray();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
boolean show = name.equals("电影") ||
|
||||
name.equals("连续剧") ||
|
||||
name.equals("动漫") ||
|
||||
name.equals("综艺") ||
|
||||
name.equals("午夜影院");
|
||||
|
||||
if (name.equals("午夜影院") && !pron) {
|
||||
continue;
|
||||
}
|
||||
if (show) {
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
// 把分类的id和名称取出来加到列表里
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
// 取首页推荐视频列表
|
||||
Element homeList = doc.select("div.cbox1").get(0);
|
||||
Elements list = homeList.select("ul.vodlist li.vodlist_item");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst("a.vodlist_thumb").attr("title");
|
||||
String cover = siteUrl + vod.selectFirst("a.vodlist_thumb").attr("data-original");
|
||||
String remark = "";
|
||||
try {
|
||||
remark = vod.select("span.pic_text em").text();
|
||||
} catch (Exception e) {
|
||||
remark = vod.select("span.text_dy").get(0).text();
|
||||
}
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst("a.vodlist_thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String url = siteUrl + "/index.php/vod/show/id/";
|
||||
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||
url += extend.get("tid");
|
||||
} else {
|
||||
url += tid;
|
||||
}
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
if (value.length() > 0) {
|
||||
url += "/" + key + "/" + URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
url += "/page/" + pg + ".html";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
// 取页码相关信息
|
||||
Elements pageInfo = doc.select("ul.page");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element li = pageInfo.get(i);
|
||||
Element a = li.selectFirst("li a");
|
||||
if (a == null)
|
||||
continue;
|
||||
String span = pageInfo.select("li.active a").text();
|
||||
String wy = doc.select("ul.page li a").last().attr("href");
|
||||
if (page == -1) {
|
||||
page = Integer.parseInt(span);
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
Matcher matcher = regexPage.matcher(wy);
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
// 取当前分类页的视频列表
|
||||
Elements list = doc.select("ul.vodlist li.vodlist_item");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst("a.vodlist_thumb").attr("title");
|
||||
String cover = siteUrl + vod.selectFirst("a.vodlist_thumb").attr("data-original");
|
||||
String remark = "";
|
||||
try {
|
||||
remark = vod.select("span.pic_text em").text();
|
||||
} catch (Exception e) {
|
||||
remark = vod.select("span.text_dy").get(0).text();
|
||||
}
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst("a.vodlist_thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 20);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 20);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/index.php/vod/detail/id/" + ids.get(0) + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String vid = doc.selectFirst("a.digg_link").attr("data-id");
|
||||
|
||||
String cover = siteUrl + doc.selectFirst("div.content_thumb a").attr("data-original");
|
||||
String title = doc.selectFirst("div.content_thumb a").attr("title");
|
||||
String desc = doc.selectFirst("div.context span").text();
|
||||
String category = "", area = "", year = "", director = "", actor = "", remark = "";
|
||||
remark = doc.select("span.data_style").text();
|
||||
Elements span_text_muted = doc.select("li.data span");
|
||||
for (int i = 0; i < span_text_muted.size() - 2; i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.contains("类型")) {
|
||||
try {
|
||||
category = text.parent().select("a").get(2).text();
|
||||
} catch (Exception e) {
|
||||
category = "";
|
||||
}
|
||||
} else if (info.contains("年份")) {
|
||||
try {
|
||||
year = text.parent().select("a").get(0).text();
|
||||
} catch (Exception e) {
|
||||
year = "";
|
||||
}
|
||||
} else if (info.contains("地区")) {
|
||||
try {
|
||||
area = text.parent().select("a").get(1).text();
|
||||
} catch (Exception e) {
|
||||
area = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = doc.select("li.data").get(3).select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements bb = doc.select("li.data").get(2).select("a");
|
||||
for (int j = 0; j < bb.size(); j++) {
|
||||
directors.add(bb.get(j).text());
|
||||
}
|
||||
director = TextUtils.join(",", directors);
|
||||
|
||||
|
||||
vodList.put("vod_id", vid);
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 取播放列表数据
|
||||
Elements sources = doc.select("div.play_source_tab a");
|
||||
Elements sourceList = doc.select("div.playlist_full");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.attr("alt");
|
||||
sourceName = sourceName.replaceAll("[^\u4E00-\u9FA5]", "");
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = sourceList.get(i).select("ul>li>a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "/sid/" + matcher.group(2) + "/nid/" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/index.php/vod/play/id/" + id + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) { // 取直链
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
if (searchResult.getInt("total") > 0) {
|
||||
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||
for (int i = 0; i < lists.length(); i++) {
|
||||
JSONObject vod = lists.getJSONObject(i);
|
||||
String id = vod.getString("id");
|
||||
String title = vod.getString("name");
|
||||
String cover = vod.getString("pic");
|
||||
if (title.contains(key)) {
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", "");
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String doReplaceRegex(Pattern pattern, String src) {
|
||||
if (pattern == null)
|
||||
return src;
|
||||
try {
|
||||
Matcher matcher = pattern.matcher(src);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1).trim();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,471 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Xiaoh extends Spider {
|
||||
private static final String siteUrl = "https://www.xiaoheimi.net";
|
||||
private static final String siteHost = "www.xiaoheimi.net";
|
||||
|
||||
/**
|
||||
* 播放源配置
|
||||
*/
|
||||
private JSONObject playerConfig;
|
||||
/**
|
||||
* 筛选配置
|
||||
*/
|
||||
private JSONObject filterConfig;
|
||||
private Pattern regexCategory = Pattern.compile("/index.php/vod/type/id/(\\d+).html");
|
||||
private Pattern regexVid = Pattern.compile("/index.php/vod/detail/id/(\\d+).html");
|
||||
private Pattern regexPlay = Pattern.compile("/index.php/vod/play/id/(\\d+)/sid/(\\d+)/nid/(\\d+).html");
|
||||
private Pattern regexPage = Pattern.compile("\\S+/page/(\\d+)\\S+");
|
||||
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"gqy2\":{\"sh\":\"高清2\",\"sn\":0,\"pu\":\"\",\"or\":999},\"xbyy\":{\"sh\":\"高清\",\"sn\":0,\"pu\":\"\",\"or\":999},\"ysgc\":{\"sh\":\"高清源\",\"sn\":0,\"pu\":\"\",\"or\":999},\"if101\":{\"sh\":\"小宝影院\",\"sn\":0,\"pu\":\"\",\"or\":999},\"bili\":{\"sh\":\"bili\",\"sn\":0,\"pu\":\"\",\"or\":999},\"dplayer\":{\"sh\":\"DPlayer-H5播放器\",\"sn\":0,\"pu\":\"\",\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"1\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"喜剧片\",\"v\":\"喜剧片\"},{\"n\":\"冒险片\",\"v\":\"冒险片\"},{\"n\":\"剧情片\",\"v\":\"剧情片\"},{\"n\":\"动作片\",\"v\":\"动作片\"},{\"n\":\"动画电影\",\"v\":\"动画电影\"},{\"n\":\"同性片\",\"v\":\"同性片\"},{\"n\":\"奇幻片\",\"v\":\"奇幻片\"},{\"n\":\"恐怖片\",\"v\":\"恐怖片\"},{\"n\":\"悬疑片\",\"v\":\"悬疑片\"},{\"n\":\"惊悚片\",\"v\":\"惊悚片\"},{\"n\":\"歌舞片\",\"v\":\"歌舞片\"},{\"n\":\"灾难片\",\"v\":\"灾难片\"},{\"n\":\"爱情片\",\"v\":\"爱情片\"},{\"n\":\"犯罪片\",\"v\":\"犯罪片\"},{\"n\":\"科幻片\",\"v\":\"科幻片\"},{\"n\":\"经典片\",\"v\":\"经典片\"},{\"n\":\"网络电影\",\"v\":\"网络电影\"},{\"n\":\"战争片\",\"v\":\"战争片\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"2\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"偶像\",\"v\":\"偶像\"},{\"n\":\"爱情\",\"v\":\"爱情\"},{\"n\":\"言情\",\"v\":\"言情\"},{\"n\":\"古装\",\"v\":\"古装\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"玄幻\",\"v\":\"玄幻\"},{\"n\":\"谍战\",\"v\":\"谍战\"},{\"n\":\"历险\",\"v\":\"历险\"},{\"n\":\"都市\",\"v\":\"都市\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"军旅\",\"v\":\"军旅\"},{\"n\":\"喜剧\",\"v\":\"喜剧\"},{\"n\":\"武侠\",\"v\":\"武侠\"},{\"n\":\"江湖\",\"v\":\"江湖\"},{\"n\":\"罪案\",\"v\":\"罪案\"},{\"n\":\"青春\",\"v\":\"青春\"},{\"n\":\"家庭\",\"v\":\"家庭\"},{\"n\":\"战争\",\"v\":\"战争\"},{\"n\":\"悬疑\",\"v\":\"悬疑\"},{\"n\":\"穿越\",\"v\":\"穿越\"},{\"n\":\"宫廷\",\"v\":\"宫廷\"},{\"n\":\"神话\",\"v\":\"神话\"},{\"n\":\"商战\",\"v\":\"商战\"},{\"n\":\"警匪\",\"v\":\"警匪\"},{\"n\":\"动作\",\"v\":\"动作\"},{\"n\":\"惊悚\",\"v\":\"惊悚\"},{\"n\":\"剧情\",\"v\":\"剧情\"},{\"n\":\"同性\",\"v\":\"同性\"},{\"n\":\"奇幻\",\"v\":\"奇幻\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"4\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"热血\",\"v\":\"热血\"},{\"n\":\"格斗\",\"v\":\"格斗\"},{\"n\":\"机战\",\"v\":\"机战\"},{\"n\":\"少女\",\"v\":\"少女\"},{\"n\":\"竞技\",\"v\":\"竞技\"},{\"n\":\"科幻\",\"v\":\"科幻\"},{\"n\":\"魔幻\",\"v\":\"魔幻\"},{\"n\":\"爆笑\",\"v\":\"爆笑\"},{\"n\":\"推理\",\"v\":\"推理\"},{\"n\":\"冒险\",\"v\":\"冒险\"},{\"n\":\"恋爱\",\"v\":\"恋爱\"},{\"n\":\"校园\",\"v\":\"校园\"},{\"n\":\"治愈\",\"v\":\"治愈\"},{\"n\":\"泡面\",\"v\":\"泡面\"},{\"n\":\"穿越\",\"v\":\"穿越\"},{\"n\":\"灵异\",\"v\":\"灵异\"},{\"n\":\"耽美\",\"v\":\"耽美\"},{\"n\":\"动画电影\",\"v\":\"动画电影\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"3\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"真人秀\",\"v\":\"真人秀\"},{\"n\":\"选秀\",\"v\":\"选秀\"},{\"n\":\"网综\",\"v\":\"网综\"},{\"n\":\"脱口秀\",\"v\":\"脱口秀\"},{\"n\":\"搞笑\",\"v\":\"搞笑\"},{\"n\":\"竞技\",\"v\":\"竞技\"},{\"n\":\"情感\",\"v\":\"情感\"},{\"n\":\"访谈\",\"v\":\"访谈\"},{\"n\":\"演唱会\",\"v\":\"演唱会\"},{\"n\":\"晚会\",\"v\":\"晚会\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"21\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"class\",\"name\":\"分类\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"文化\",\"v\":\"文化\"},{\"n\":\"探索\",\"v\":\"探索\"},{\"n\":\"军事\",\"v\":\"军事\"},{\"n\":\"解密\",\"v\":\"解密\"},{\"n\":\"科技\",\"v\":\"科技\"},{\"n\":\"历史\",\"v\":\"历史\"},{\"n\":\"人物\",\"v\":\"人物\"},{\"n\":\"自然\",\"v\":\"自然\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"20\":[{\"key\":\"area\",\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"港台\",\"v\":\"港台\"},{\"n\":\"日韩\",\"v\":\"日韩\"},{\"n\":\"欧美\",\"v\":\"欧美\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"year\",\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2022\",\"v\":\"2022\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":\"lang\",\"name\":\"语言\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国语\",\"v\":\"国语\"},{\"n\":\"英语\",\"v\":\"英语\"},{\"n\":\"粤语\",\"v\":\"粤语\"},{\"n\":\"韩语\",\"v\":\"韩语\"},{\"n\":\"日语\",\"v\":\"日语\"},{\"n\":\"法语\",\"v\":\"法语\"},{\"n\":\"德语\",\"v\":\"德语\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"泰国语\",\"v\":\"泰国语\"},{\"n\":\"其它\",\"v\":\"其它\"}]},{\"key\":\"by\",\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
headers.put("Host", siteHost);
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("DNT", "1");
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||
// 分类节点
|
||||
Elements elements = doc.select("ul.nav-menu>li>a");
|
||||
JSONArray classes = new JSONArray();
|
||||
for (Element ele : elements) {
|
||||
String name = ele.text();
|
||||
boolean show = name.equals("电影") ||
|
||||
name.equals("电视剧") ||
|
||||
name.equals("动漫") ||
|
||||
name.equals("综艺") ||
|
||||
name.equals("纪录片") ||
|
||||
name.equals("体育");
|
||||
if (show) {
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
// 把分类的id和名称取出来加到列表里
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
// 取首页推荐视频列表
|
||||
Element homeList = doc.select("ul.myui-vodlist").get(1);
|
||||
Elements list = homeList.select("div.myui-vodlist__box>a");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.attr("title");
|
||||
String cover = vod.attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
Matcher matcher = regexVid.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String url = siteUrl + "/index.php/vod/show/id/";
|
||||
if (extend != null && extend.size() > 0 && extend.containsKey("tid") && extend.get("tid").length() > 0) {
|
||||
url += extend.get("tid");
|
||||
} else {
|
||||
url += tid;
|
||||
}
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
if (value.length() > 0) {
|
||||
url += "/" + key + "/" + URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
url += "/page/" + pg + ".html";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
// 取页码相关信息
|
||||
Elements pageInfo = doc.select(".myui-page li a");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element a = pageInfo.get(i);
|
||||
String name = a.text();
|
||||
if (page == -1 && a.hasClass("btn-warm")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾页")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).trim());
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
// 取当前分类页的视频列表
|
||||
Elements list = doc.select("div.myui-vodlist__box");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".title").text();
|
||||
String cover = vod.selectFirst(".myui-vodlist__thumb").attr("data-original");
|
||||
String remark = vod.selectFirst("span.pic-text").text();
|
||||
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".myui-vodlist__thumb").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 48);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 48);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/index.php/vod/detail/id/" + ids.get(0) + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String vid = doc.selectFirst("span.mac_hits").attr("data-id");
|
||||
|
||||
String cover = doc.selectFirst("a.myui-vodlist__thumb img").attr("data-original");
|
||||
String title = doc.selectFirst("div.myui-content__detail h1.title").text();
|
||||
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.myui-content__detail span.text-muted");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("分类:")) {
|
||||
category = text.nextElementSibling().text();
|
||||
} else if (info.equals("年份:")) {
|
||||
year = text.nextElementSibling().text();
|
||||
} else if (info.equals("地区:")) {
|
||||
area = text.nextElementSibling().text();
|
||||
} else if (info.equals("更新:")) {
|
||||
remark = text.nextElementSibling().text();
|
||||
} else if (info.equals("导演:")) {
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
directors.add(aa.get(j).text());
|
||||
}
|
||||
director = TextUtils.join(",", directors);
|
||||
} else if (info.equals("主演:")) {
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", vid);
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 取播放列表数据
|
||||
Elements sources = doc.select("div.myui-panel__head>ul").get(0).select("li");
|
||||
Elements sourceList = doc.select("div.tab-content>div.tab-pane");
|
||||
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
String sourceName = source.text();
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = sourceList.get(i).select("ul>li>a");
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "/sid/" + matcher.group(2) + "/nid/" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/index.php/vod/play/id/" + id + ".html";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) { // 取直链
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
protected static HashMap<String, String> Headers() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||
headers.put("Referer", siteUrl);
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
String url = "https://www.google.com/search?q=site%3A" + siteHost + "+" + URLEncoder.encode(key);
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, Headers()));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
Elements sourceList = doc.select("div.yuRUbf a");
|
||||
for (int i = 0; i < sourceList.size(); i++) {
|
||||
Element sourcess = sourceList.get(i);
|
||||
String sourceName = sourcess.select("h3").text();
|
||||
String list1 = sourcess.attr("href");
|
||||
Matcher matcher = regexVid.matcher(list1);
|
||||
if (sourceName.contains(key) && matcher.find()) {
|
||||
Document ddrklink = Jsoup.parse(OkHttpUtil.string(list1, getHeaders(list1)));
|
||||
JSONObject v = new JSONObject();
|
||||
String group = matcher.group(1);
|
||||
String cover = ddrklink.selectFirst("a.myui-vodlist__thumb img").attr("data-original");
|
||||
String title = ddrklink.selectFirst("div.myui-content__detail h1.title").text();
|
||||
Elements span_text_muted = ddrklink.select("div.myui-content__detail span.text-muted");
|
||||
for (int j = 0; j < span_text_muted.size(); j++) {
|
||||
Element text = span_text_muted.get(j);
|
||||
String info = text.text();
|
||||
if (info.equals("更新:")) {
|
||||
String remark = text.nextElementSibling().text();
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_remarks", remark);
|
||||
v.put("vod_id", group);
|
||||
v.put("vod_pic", cover);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,479 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.Misc;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Xifanys extends Spider {
|
||||
|
||||
private static final String siteUrl = "https://www.xifanys.com/";
|
||||
private static final String siteHost = "xifanys.com";
|
||||
|
||||
protected JSONObject playerConfig;
|
||||
protected JSONObject filterConfig;
|
||||
|
||||
protected Pattern regexCategory = Pattern.compile("/yingpiantype/(\\S+).html");
|
||||
protected Pattern regexVid = Pattern.compile("/yingpiandetail/(\\S+).html");
|
||||
protected Pattern regexPlay = Pattern.compile("/yingpianplay/(\\S+)-(\\d+)-(\\d+).html");
|
||||
protected Pattern regexPage = Pattern.compile("/yingpianshow/(\\S+).html");
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
try {
|
||||
playerConfig = new JSONObject("{\"tkm3u8\":{\"sh\":\"R播\",\"pu\":\",\"sn\":0,\"or\":999},\"if101\":{\"sh\":\"Y播\",\"pu\":\"\",\"sn\":0,\"or\":999}}");
|
||||
filterConfig = new JSONObject("{\"20\":[{\"key\":\"0\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"20\"},{\"n\":\"动作片\",\"v\":\"24\"},{\"n\":\"喜剧片\",\"v\":\"25\"},{\"n\":\"愛情片\",\"v\":\"26\"},{\"n\":\"科幻片\",\"v\":\"27\"},{\"n\":\"恐怖片\",\"v\":\"28\"},{\"n\":\"劇情片\",\"v\":\"11\"},{\"n\":\"戰爭片\",\"v\":\"30\"},{\"n\":\"动画电影\",\"v\":\"33\"}]},{\"key\":1,\"name\":\"地区\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"大陆\",\"v\":\"大陆\"},{\"n\":\"香港\",\"v\":\"香港\"},{\"n\":\"台湾\",\"v\":\"台湾\"},{\"n\":\"美国\",\"v\":\"美国\"},{\"n\":\"法国\",\"v\":\"法国\"},{\"n\":\"英国\",\"v\":\"英国\"},{\"n\":\"日本\",\"v\":\"日本\"},{\"n\":\"韩国\",\"v\":\"韩国\"},{\"n\":\"德国\",\"v\":\"德国\"},{\"n\":\"泰国\",\"v\":\"泰国\"},{\"n\":\"印度\",\"v\":\"印度\"},{\"n\":\"意大利\",\"v\":\"意大利\"},{\"n\":\"西班牙\",\"v\":\"西班牙\"},{\"n\":\"加拿大\",\"v\":\"加拿大\"},{\"n\":\"其他\",\"v\":\"其他\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"21\":[{\"key\":\"tid\",\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"国产剧\",\"v\":\"34\"},{\"n\":\"港剧\",\"v\":\"35\"},{\"n\":\"韩剧\",\"v\":\"37\"},{\"n\":\"欧美剧\",\"v\":\"36\"},{\"n\":\"日本剧\",\"v\":\"38\"},{\"n\":\"台湾剧\",\"v\":\"39\"},{\"n\":\"海外剧\",\"v\":\"40\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"22\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"22\"},{\"n\":\"大陆综艺\",\"v\":\"41\"},{\"n\":\"港台综艺\",\"v\":\"42\"},{\"n\":\"日韩综艺\",\"v\":\"43\"},{\"n\":\"欧美综艺\",\"v\":\"44\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}],\"23\":[{\"key\":0,\"name\":\"类型\",\"value\":[{\"n\":\"全部\",\"v\":\"23\"},{\"n\":\"国产动漫\",\"v\":\"45\"},{\"n\":\"日本动漫\",\"v\":\"46\"},{\"n\":\"欧美动漫\",\"v\":\"47\"}]},{\"key\":11,\"name\":\"年份\",\"value\":[{\"n\":\"全部\",\"v\":\"\"},{\"n\":\"2021\",\"v\":\"2021\"},{\"n\":\"2020\",\"v\":\"2020\"},{\"n\":\"2019\",\"v\":\"2019\"},{\"n\":\"2018\",\"v\":\"2018\"},{\"n\":\"2017\",\"v\":\"2017\"},{\"n\":\"2016\",\"v\":\"2016\"},{\"n\":\"2015\",\"v\":\"2015\"},{\"n\":\"2014\",\"v\":\"2014\"},{\"n\":\"2013\",\"v\":\"2013\"},{\"n\":\"2012\",\"v\":\"2012\"},{\"n\":\"2011\",\"v\":\"2011\"},{\"n\":\"2010\",\"v\":\"2010\"},{\"n\":\"2009\",\"v\":\"2009\"},{\"n\":\"2008\",\"v\":\"2008\"},{\"n\":\"2007\",\"v\":\"2007\"},{\"n\":\"2006\",\"v\":\"2006\"},{\"n\":\"2005\",\"v\":\"2005\"},{\"n\":\"2004\",\"v\":\"2004\"}]},{\"key\":2,\"name\":\"排序\",\"value\":[{\"n\":\"时间\",\"v\":\"time\"},{\"n\":\"人气\",\"v\":\"hits\"},{\"n\":\"评分\",\"v\":\"score\"}]}]}");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 爬虫headers
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("method", "GET");
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
headers.put("Referer", url);
|
||||
}
|
||||
//headers.put("sec-ch-ua-platform","Windows");
|
||||
headers.put("Accept-Encoding", "gzip, deflate, br");
|
||||
headers.put("Upgrade-Insecure-Requests", "1");
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");
|
||||
headers.put("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.9");
|
||||
headers.put("Accept-Language", "zh-CN,zh;q=0.9");
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类数据 + 首页最近更新视频列表数据
|
||||
*
|
||||
* @param filter 是否开启筛选 关联的是 软件设置中 首页数据源里的筛选开关
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(siteUrl, getHeaders(siteUrl)));
|
||||
// 分类节点
|
||||
Element cateList = doc.select("ul.nav-menu-items").get(0);
|
||||
Elements elements = cateList.select("li > a");
|
||||
|
||||
JSONArray classes = new JSONArray();
|
||||
for (Element ele : elements) {
|
||||
//分类名
|
||||
String name = ele.attr("title");
|
||||
boolean show = name.equals("电影") ||
|
||||
name.equals("剧集") ||
|
||||
name.equals("综艺") ||
|
||||
name.equals("动漫");
|
||||
if (show) {
|
||||
Matcher mather = regexCategory.matcher(ele.attr("href"));
|
||||
if (!mather.find())
|
||||
continue;
|
||||
// 把分类的id和名称取出来加到列表里
|
||||
String id = mather.group(1).trim();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type_id", id);
|
||||
jsonObject.put("type_name", name);
|
||||
//System.out.println(id+":"+name);
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("class", classes);
|
||||
try {
|
||||
// 取首页推荐视频列表
|
||||
Element homeList = doc.select("div.module-items").get(0);
|
||||
Elements list = homeList.select("div.module-item");
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".module-item-titlebox a").text();
|
||||
String cover = vod.selectFirst(".module-item-pic > img").attr("data-src");
|
||||
String remark = vod.selectFirst(".module-item-text").text();
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".module-item-titlebox a").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
result.put("list", videos);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分类信息数据
|
||||
*
|
||||
* @param tid 分类id
|
||||
* @param pg 页数
|
||||
* @param filter 同homeContent方法中的filter
|
||||
* @param extend 筛选参数{k:v, k1:v1}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String[] urlParams = new String[]{"", "", "", "", "", "", "", "", "", "", "", ""};
|
||||
urlParams[0] = tid;
|
||||
urlParams[8] = pg;
|
||||
if (extend != null && extend.size() > 0) {
|
||||
for (Iterator<String> it = extend.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = it.next();
|
||||
String value = extend.get(key);
|
||||
urlParams[Integer.parseInt(key)] = URLEncoder.encode(value);
|
||||
}
|
||||
}
|
||||
// 获取分类数据的url
|
||||
String url = siteUrl + "/yingpianshow/" + TextUtils.join("-", urlParams) + "/";
|
||||
String html = OkHttpUtil.string(url, getHeaders(url));
|
||||
Document doc = Jsoup.parse(html);
|
||||
JSONObject result = new JSONObject();
|
||||
int pageCount = 0;
|
||||
int page = -1;
|
||||
|
||||
|
||||
// 取页码相关信息
|
||||
Elements pageInfo = doc.select("div.module-footer > div > a");
|
||||
if (pageInfo.size() == 0) {
|
||||
page = Integer.parseInt(pg);
|
||||
pageCount = page;
|
||||
} else {
|
||||
for (int i = 0; i < pageInfo.size(); i++) {
|
||||
Element a = pageInfo.get(i);
|
||||
//Element a = li.selectFirst("a");
|
||||
if (a == null)
|
||||
continue;
|
||||
String name = a.text();
|
||||
if (page == -1 && a.hasClass("display")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
page = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
page = 0;
|
||||
}
|
||||
}
|
||||
if (name.equals("尾页")) {
|
||||
Matcher matcher = regexPage.matcher(a.attr("href"));
|
||||
if (matcher.find()) {
|
||||
pageCount = Integer.parseInt(matcher.group(1).split("-")[8]);
|
||||
} else {
|
||||
pageCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
if (!html.contains("没有找到您想要的结果哦")) {
|
||||
// 取当前分类页的视频列表
|
||||
|
||||
Elements list = doc.select("div.module-items > div.module-item");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element vod = list.get(i);
|
||||
String title = vod.selectFirst(".module-item-titlebox a").text();
|
||||
String cover = vod.selectFirst(".module-item-pic > img").attr("data-src");
|
||||
String remark = vod.selectFirst(".module-item-text").text();
|
||||
Matcher matcher = regexVid.matcher(vod.selectFirst(".module-item-titlebox a").attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String id = matcher.group(1);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", remark);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("page", page);
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", 72);
|
||||
result.put("total", pageCount <= 1 ? videos.length() : pageCount * 72);
|
||||
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 视频详情信息
|
||||
*
|
||||
* @param ids 视频id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
// 视频详情url
|
||||
String url = siteUrl + "/yingpiandetail/" + ids.get(0) + ".html";
|
||||
//System.out.println(url);
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
|
||||
// 取基本数据
|
||||
String cover = doc.selectFirst("div.video-cover .module-item-pic > img").attr("data-src");
|
||||
String title = doc.selectFirst("div.video-cover .module-item-pic > a").attr("alt");
|
||||
String desc = Jsoup.parse(doc.selectFirst("meta[name=description]").attr("content")).text();
|
||||
String category = "", area = "", year = "", remark = "", director = "", actor = "";
|
||||
Elements span_text_muted = doc.select("div.video-info-main span.video-info-itemtitle");
|
||||
for (int i = 0; i < span_text_muted.size(); i++) {
|
||||
Element text = span_text_muted.get(i);
|
||||
String info = text.text();
|
||||
if (info.equals("分类:")) {
|
||||
category = text.nextElementSibling().text();
|
||||
} else if (info.equals("上映:")) {
|
||||
year = text.nextElementSibling().text();
|
||||
} else if (info.equals("地区:")) {
|
||||
area = text.nextElementSibling().text();
|
||||
} else if (info.equals("更新:")) {
|
||||
remark = text.nextElementSibling().text();
|
||||
} else if (info.equals("导演:")) {
|
||||
List<String> directors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
directors.add(aa.get(j).text());
|
||||
}
|
||||
director = TextUtils.join(",", directors);
|
||||
} else if (info.equals("主演:")) {
|
||||
List<String> actors = new ArrayList<>();
|
||||
Elements aa = text.parent().select("a");
|
||||
for (int j = 0; j < aa.size(); j++) {
|
||||
actors.add(aa.get(j).text());
|
||||
}
|
||||
actor = TextUtils.join(",", actors);
|
||||
}
|
||||
}
|
||||
|
||||
vodList.put("vod_id", ids.get(0));
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_pic", cover);
|
||||
vodList.put("type_name", category);
|
||||
vodList.put("vod_year", year);
|
||||
vodList.put("vod_area", area);
|
||||
vodList.put("vod_remarks", remark);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", desc);
|
||||
//System.out.println(vodList.toString());
|
||||
Map<String, String> vod_play = new TreeMap<>(new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
try {
|
||||
int sort1 = playerConfig.getJSONObject(o1).getInt("or");
|
||||
int sort2 = playerConfig.getJSONObject(o2).getInt("or");
|
||||
|
||||
if (sort1 == sort2) {
|
||||
return 1;
|
||||
}
|
||||
return sort1 - sort2 > 0 ? 1 : -1;
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// 取播放列表数据
|
||||
Elements sources = doc.select("div.module-tab-content").get(0).select("div > span");
|
||||
//System.out.println(sources.size());
|
||||
Elements sourceList = doc.select("div.module-player-list");
|
||||
//System.out.println(sourceList.size());
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
Element source = sources.get(i);
|
||||
//System.out.println(sources.text().split(":")[0].split("』")[1]);
|
||||
String sourceName = source.text();
|
||||
boolean found = false;
|
||||
for (Iterator<String> it = playerConfig.keys(); it.hasNext(); ) {
|
||||
String flag = it.next();
|
||||
if (playerConfig.getJSONObject(flag).getString("sh").equals(sourceName)) {
|
||||
sourceName = flag;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
continue;
|
||||
String playList = "";
|
||||
Elements playListA = sourceList.get(i).select(".scroll-content > a");
|
||||
//System.out.println(playListA.size());
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < playListA.size(); j++) {
|
||||
Element vod = playListA.get(j);
|
||||
Matcher matcher = regexPlay.matcher(vod.attr("href"));
|
||||
if (!matcher.find())
|
||||
continue;
|
||||
String playURL = matcher.group(1) + "-" + matcher.group(2) + "-" + matcher.group(3);
|
||||
vodItems.add(vod.text() + "$" + playURL);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
continue;
|
||||
|
||||
vod_play.put(sourceName, playList);
|
||||
}
|
||||
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取视频播放信息
|
||||
*
|
||||
* @param flag 播放源
|
||||
* @param id 视频id
|
||||
* @param vipFlags 所有可能需要vip解析的源
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
//定义播放用的headers
|
||||
JSONObject headers = new JSONObject();
|
||||
//headers.put("Host", " cokemv.co");
|
||||
//headers.put("origin", " https://juhi.cc");
|
||||
//headers.put("User-Agent", " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36");
|
||||
//headers.put("Accept", " */*");
|
||||
//headers.put("Accept-Language", " zh-CN,zh;q=0.9,en-US;q=0.3,en;q=0.7");
|
||||
//headers.put("Accept-Encoding", " gzip, deflate, br");
|
||||
|
||||
|
||||
// 播放页 url
|
||||
String url = siteUrl + "/yingpianplay/" + id + "/";
|
||||
Document doc = Jsoup.parse(OkHttpUtil.string(url, getHeaders(url)));
|
||||
Elements allScript = doc.select("script");
|
||||
JSONObject result = new JSONObject();
|
||||
for (int i = 0; i < allScript.size(); i++) {
|
||||
String scContent = allScript.get(i).html().trim();
|
||||
if (scContent.startsWith("var player_")) { // 取直链
|
||||
int start = scContent.indexOf('{');
|
||||
int end = scContent.lastIndexOf('}') + 1;
|
||||
String json = scContent.substring(start, end);
|
||||
JSONObject player = new JSONObject(json);
|
||||
if (playerConfig.has(player.getString("from"))) {
|
||||
JSONObject pCfg = playerConfig.getJSONObject(player.getString("from"));
|
||||
String videoUrl = player.getString("url");
|
||||
String playUrl = pCfg.getString("pu");
|
||||
if (Misc.isVip(videoUrl)) { // 使用jx:1
|
||||
try {
|
||||
result.put("parse", 1);
|
||||
result.put("jx", "1");
|
||||
result.put("url", videoUrl);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
result.put("parse", pCfg.getInt("sn"));
|
||||
result.put("playUrl", playUrl);
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", headers.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
if (quick)
|
||||
return "";
|
||||
long currentTime = System.currentTimeMillis();
|
||||
String url = siteUrl + "/index.php/ajax/suggest?mid=1&wd=" + URLEncoder.encode(key) + "&limit=10×tamp=" + currentTime;
|
||||
//Document doc = Jsoup.parse(srr.content);
|
||||
JSONObject searchResult = new JSONObject(OkHttpUtil.string(url, getHeaders(url)));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
if (searchResult.getInt("total") > 0) {
|
||||
JSONArray lists = new JSONArray(searchResult.getString("list"));
|
||||
for (int i = 0; i < lists.length(); i++) {
|
||||
JSONObject vod = lists.getJSONObject(i);
|
||||
String id = vod.getString("id");
|
||||
String title = vod.getString("name");
|
||||
String cover = vod.getString("pic");
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", id);
|
||||
v.put("vod_name", title);
|
||||
v.put("vod_pic", cover);
|
||||
v.put("vod_remarks", "");
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,398 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class Yj1211 extends Spider {
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
|
||||
String srcurl = "http://live.yj1211.work/api/live/getRecommend?page=1&size=20";
|
||||
String srcOrignstr ="";
|
||||
for(int i=0 ; i<3 ; i++){
|
||||
srcOrignstr = OkHttpUtil.string(srcurl, getHeaders());
|
||||
if(srcOrignstr.length()>0){
|
||||
break;
|
||||
}else{
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject srcori = new JSONObject(srcOrignstr);
|
||||
JSONArray srcoria = srcori.getJSONArray("data");
|
||||
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray classes = new JSONArray();
|
||||
String catestr ="{\"推荐\":\"?\",\"斗鱼\":\"ByPlatform?platform=douyu&\",\"哔哩哔哩\":\"ByPlatform?platform=bilibili&\",\"虎牙\":\"ByPlatform?platform=huya&\",\"网易CC\":\"ByPlatform?platform=cc&\"}";
|
||||
JSONObject catedef = new JSONObject(catestr);
|
||||
Iterator it = catedef.keys();
|
||||
while(it.hasNext()){
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
String key =(String) it.next();
|
||||
jsonObject.put("type_name", key);
|
||||
jsonObject.put("type_id", catedef.getString(key));
|
||||
classes.put(jsonObject);
|
||||
}
|
||||
result.put("class", classes);
|
||||
|
||||
JSONObject filterConfig = new JSONObject();
|
||||
String geta ="http://live.yj1211.work/api/live/getAllAreas";
|
||||
String aaid = "";
|
||||
for(int i=0 ; i<3 ; i++){
|
||||
aaid = OkHttpUtil.string(geta, getHeaders());
|
||||
if(aaid.length()>0){
|
||||
break;
|
||||
}else{
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject aido = new JSONObject(aaid);
|
||||
JSONArray aidoa = aido.getJSONArray("data");
|
||||
JSONArray extendsAll = new JSONArray();
|
||||
for (int j=0 ; j< 13;j++){
|
||||
JSONObject newTypeExtend = new JSONObject();
|
||||
String typeName = aidoa.getJSONArray(j).getJSONObject(0).getString("typeName");
|
||||
newTypeExtend.put("key", "typeName" + j);
|
||||
newTypeExtend.put("name", typeName);
|
||||
JSONArray newTypeExtendKV = new JSONArray();
|
||||
int fg = Math.min(aidoa.getJSONArray(j).length(), 20);
|
||||
JSONObject kv = new JSONObject();
|
||||
kv.put("n", "全部");
|
||||
kv.put("v", typeName + "=" + "all");
|
||||
newTypeExtendKV.put(kv);
|
||||
for (int k=0 ; k< fg ; k++){
|
||||
kv = new JSONObject();
|
||||
String areaName = aidoa.getJSONArray(j).getJSONObject(k).getString("areaName");
|
||||
kv.put("n", areaName);
|
||||
kv.put("v", typeName + "=" + areaName);
|
||||
newTypeExtendKV.put(kv);
|
||||
}
|
||||
newTypeExtend.put("value", newTypeExtendKV);
|
||||
extendsAll.put(newTypeExtend);
|
||||
}
|
||||
for (int i = 0 ; i < 5 ; i++){
|
||||
String typeId = classes.getJSONObject(i).getString("type_id");
|
||||
filterConfig.put(typeId, extendsAll);
|
||||
}
|
||||
|
||||
JSONArray videos = new JSONArray();
|
||||
int ch = Math.min(srcoria.length(), 10);
|
||||
for (int i = 0; i < ch; i++) {
|
||||
JSONObject srchome = new JSONObject();
|
||||
String platForm = srcoria.getJSONObject(i).getString("platForm");
|
||||
String rd = srcoria.getJSONObject(i).getString("roomId");
|
||||
String id = platForm + "&" + rd;
|
||||
String name = srcoria.getJSONObject(i).getString("ownerName");
|
||||
String pic = srcoria.getJSONObject(i).getString("ownerHeadPic");
|
||||
String mark = srcoria.getJSONObject(i).getString("categoryName");
|
||||
srchome.put("vod_id", id);
|
||||
srchome.put("vod_name", name);
|
||||
srchome.put("vod_pic",pic);
|
||||
srchome.put("vod_remarks", mark);
|
||||
videos.put(srchome);
|
||||
}
|
||||
if (filter) {
|
||||
result.put("filters", filterConfig);
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (
|
||||
Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
String catt="";
|
||||
switch (tid) {
|
||||
case "?":
|
||||
catt = "all";
|
||||
break;
|
||||
case "ByPlatform?platform=douyu&":
|
||||
catt = "douyu";
|
||||
break;
|
||||
case "ByPlatform?platform=bilibili&":
|
||||
catt = "bilibili";
|
||||
break;
|
||||
case "ByPlatform?platform=huya&":
|
||||
catt = "huya";
|
||||
break;
|
||||
case "ByPlatform?platform=cc&":
|
||||
catt = "cc";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extend = extend == null ? new HashMap<>() : extend;
|
||||
String srcurl="";
|
||||
String[] cate= new String[13];
|
||||
int pp = 0;
|
||||
for(int i = 0; i < 13; i++){
|
||||
cate[i] = extend.containsKey("typeName"+i) ? extend.get("typeName"+i) : ("typeName"+i + "=" + "all");
|
||||
String[] info = cate[i].split("=");
|
||||
String area = info[1];
|
||||
if( !area.contains("all") ){
|
||||
pp= pp + 1;
|
||||
}
|
||||
}
|
||||
if(pp == 1){
|
||||
for(int i = 0; i < 13; i++){
|
||||
String[] info = cate[i].split("=");
|
||||
String areaType = info[0];
|
||||
String area = info[1];
|
||||
if(!area.contains("all")) {
|
||||
String urlft = "http://live.yj1211.work/api/live/getRecommendByAreaAll?areaType={areaType}&area={area}&page={pg}";
|
||||
srcurl = urlft.replace("{areaType}", URLEncoder.encode(areaType)).replace("{area}", URLEncoder.encode(area)).replace("{pg}", pg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else if( pp == 0 || pp > 1 ){
|
||||
String urlft = "http://live.yj1211.work/api/live/getRecommend{tid}page={pg}&size=20";
|
||||
srcurl = urlft.replace("{tid}", tid).replace("{pg}", pg);
|
||||
}
|
||||
String srcOrignstr = "";
|
||||
for (int i = 0; i < 3; i++) {
|
||||
srcOrignstr = OkHttpUtil.string(srcurl, getHeaders());
|
||||
if (srcOrignstr.length() > 0 ) {
|
||||
break;
|
||||
} else {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
JSONObject srcori = new JSONObject(srcOrignstr);
|
||||
JSONArray srcoria = srcori.getJSONArray("data");
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
for (int i = 0; i < srcoria.length(); i++) {
|
||||
JSONObject srchome = new JSONObject();
|
||||
String platForm = srcoria.getJSONObject(i).getString("platForm");
|
||||
if(pp == 1 && !catt.equals("all")){
|
||||
if(!platForm.equals(catt) ){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
String rd = srcoria.getJSONObject(i).getString("roomId");
|
||||
String id = platForm + "&" + rd;
|
||||
String name = srcoria.getJSONObject(i).getString("ownerName");
|
||||
String pic = srcoria.getJSONObject(i).getString("ownerHeadPic");
|
||||
String mark = srcoria.getJSONObject(i).getString("categoryName");
|
||||
srchome.put("vod_id", id);
|
||||
srchome.put("vod_name", name);
|
||||
srchome.put("vod_pic", pic);
|
||||
srchome.put("vod_remarks", mark);
|
||||
videos.put(srchome);
|
||||
}
|
||||
if(videos.length() == 0 ) {
|
||||
JSONObject srchome = new JSONObject();
|
||||
srchome.put("vod_id", 111);
|
||||
srchome.put("vod_name", "此页无符合");
|
||||
srchome.put("vod_pic","");
|
||||
srchome.put("vod_remarks", "nothing");
|
||||
videos.put(srchome);
|
||||
}
|
||||
if (pp ==1 ) {
|
||||
result.put("pagecount", 50);
|
||||
result.put("limit",1 );
|
||||
} else{
|
||||
result.put("pagecount", Integer.MAX_VALUE);
|
||||
result.put("limit",90 );
|
||||
}
|
||||
result.put("list", videos);
|
||||
result.put("page", pg);
|
||||
result.put("total", Integer.MAX_VALUE);
|
||||
|
||||
|
||||
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.134 YaBrowser/22.7.1.755 (beta) Yowser/2.5 Safari/537.36");
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
String id = ids.get(0);
|
||||
String[] info = id.split("&");
|
||||
String platform = info[0];
|
||||
String roomId = info[1];
|
||||
String srcurl = "http://live.yj1211.work/api/live/getRoomInfo?platform="+platform+"&roomId="+roomId;
|
||||
String srcplayurl = "http://live.yj1211.work/api/live/getRealUrl?platform="+platform+"&roomId="+roomId;
|
||||
String srcdtlstr = OkHttpUtil.string(srcurl, getHeaders());
|
||||
String srcdtlplay = OkHttpUtil.string(srcplayurl, getHeaders());
|
||||
JSONObject srcdtl = new JSONObject(srcdtlstr);
|
||||
JSONObject srcdtlo = srcdtl.getJSONObject("data");
|
||||
JSONObject srcdtplay = new JSONObject(srcdtlplay);
|
||||
JSONObject srcdtplayo = srcdtplay.getJSONObject("data");
|
||||
String title = srcdtlo.getString("roomName");
|
||||
String pic = srcdtlo.getString("roomPic");
|
||||
String director = srcdtlo.getString("ownerName") + " RoomID:"+ srcdtlo.getString("roomId");
|
||||
String content = srcdtlo.getString("categoryName");
|
||||
String actor = "观看人数:" + srcdtlo.getString("online");
|
||||
String area =srcdtlo.getString("platForm");
|
||||
String typechk =srcdtlo.optString("isLive");
|
||||
String type = typechk.equals("") ? "录播" : "正在直播中" ;
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vodList = new JSONObject();
|
||||
vodList.put("vod_id", ids.get(0));
|
||||
vodList.put("vod_pic",pic);
|
||||
vodList.put("vod_name", title);
|
||||
vodList.put("vod_area",area );
|
||||
vodList.put("type_name", type);
|
||||
vodList.put("vod_actor", actor);
|
||||
vodList.put("vod_director", director);
|
||||
vodList.put("vod_content", content);
|
||||
String playList = "";
|
||||
String pl="";
|
||||
List<String> vodItems = new ArrayList<>();
|
||||
for(int i=0; i<5 ; i++){
|
||||
String[] qq = new String[] {"OD", "HD", "SD", "LD", "FD"};
|
||||
String qa = srcdtplayo.optString(qq[i]);
|
||||
if (qa.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
switch (qq[i]) {
|
||||
case "OD":
|
||||
pl = "原画" + "$" + qa;
|
||||
break;
|
||||
case "HD":
|
||||
pl = "超清" + "$" + qa;
|
||||
break;
|
||||
case "SD":
|
||||
pl = "高清" + "$" + qa;
|
||||
break;
|
||||
case "LD":
|
||||
pl = "清晣" + "$" + qa;
|
||||
break;
|
||||
case "FD":
|
||||
pl = "流畅" + "$" + qa;
|
||||
break;
|
||||
}
|
||||
vodItems.add(pl);
|
||||
}
|
||||
if (vodItems.size() > 0)
|
||||
playList = TextUtils.join("#", vodItems);
|
||||
|
||||
if (playList.length() == 0)
|
||||
playList = "NoStream$nolink";
|
||||
|
||||
Map<String, String> vod_play = new TreeMap<>();
|
||||
vod_play.put("YJ1211", playList);
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodList.put("vod_play_from", vod_play_from);
|
||||
vodList.put("vod_play_url", vod_play_url);
|
||||
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodList);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("header", getHeaders());
|
||||
result.put("parse", 1);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", id);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
String url = "http://live.yj1211.work/api/live/search?platform=all&keyWords=" + URLEncoder.encode(key) + "&isLive=0";
|
||||
String content ="";
|
||||
for(int i=0 ; i<3 ; i++){
|
||||
content =OkHttpUtil.string(url, getHeaders());
|
||||
if(content.length() >0){
|
||||
break;
|
||||
}else{
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
JSONObject searchResult = new JSONObject(content);
|
||||
JSONArray sra = searchResult.getJSONArray("data");
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
if (sra.length() > 0) {
|
||||
int ch = Math.min(sra.length(), 20);
|
||||
for (int i = 0; i < ch; i++) {
|
||||
JSONObject srat = new JSONObject();
|
||||
String platForm = sra.getJSONObject(i).getString("platform");
|
||||
String rd = sra.getJSONObject(i).getString("roomId");
|
||||
String id = platForm + "&" + rd;
|
||||
String name = sra.getJSONObject(i).getString("nickName");
|
||||
String pic = sra.getJSONObject(i).getString("headPic");
|
||||
String mark ="";
|
||||
if(!sra.getJSONObject(i).isNull("cateName")){
|
||||
mark = sra.getJSONObject(i).getString("cateName");
|
||||
}
|
||||
srat.put("vod_remarks", mark);
|
||||
srat.put("vod_id", id);
|
||||
srat.put("vod_name", name);
|
||||
srat.put("vod_pic", pic);
|
||||
|
||||
videos.put(srat);
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,275 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Ysdq extends Spider {
|
||||
private static HashMap<String, JSONObject> sites = new HashMap<>();
|
||||
|
||||
protected void fetchRule() {
|
||||
if (sites.size() == 0) {
|
||||
try {
|
||||
String json = OkHttpUtil.string("https://pj567.coding.net/p/source/d/source/git/raw/master/mobile/config.json", null);
|
||||
JSONArray sources = new JSONObject(json).optJSONArray("source");
|
||||
for (int i = 0; i < sources.length(); i++) {
|
||||
JSONObject obj = sources.getJSONObject(i);
|
||||
String type = obj.optString("type");
|
||||
if (type.equals("AppV0") || type.equals("AppTv") || type.equals("aiKanTv")) {
|
||||
String scName = obj.optString("sourceName");
|
||||
sites.put(scName, obj);
|
||||
SpiderDebug.log("{\"key\":\"csp_ysdq_" + scName + "\", \"name\":\"" + scName + "(搜)\", \"type\":3, \"api\":\"csp_Ysdq\",\"searchable\":1,\"quickSearch\":0, \"ext\":\"" + scName + "\"},");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JSONObject getJson() {
|
||||
if (sites.containsKey(sourceName)) {
|
||||
return sites.get(sourceName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String sourceName = "";
|
||||
|
||||
@Override
|
||||
public void init(Context context, String extend) {
|
||||
super.init(context, extend);
|
||||
this.sourceName = extend;
|
||||
}
|
||||
|
||||
private String jsonArr2Str(JSONArray array) {
|
||||
try {
|
||||
ArrayList<String> strings = new ArrayList<>();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
strings.add(array.getString(i));
|
||||
}
|
||||
return TextUtils.join(",", strings);
|
||||
} catch (JSONException e) {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
fetchRule();
|
||||
JSONObject cfg = getJson();
|
||||
if (cfg != null) {
|
||||
String type = cfg.optString("type");
|
||||
JSONObject result = new JSONObject();
|
||||
JSONObject vod = new JSONObject();
|
||||
if (type.equals("AppV0")) {
|
||||
String url = cfg.optString("detailUrl").replace("%s", ids.get(0));
|
||||
String json = OkHttpUtil.string(url, null);
|
||||
JSONObject obj = new JSONObject(json).optJSONObject("data");
|
||||
vod.put("vod_id", obj.getString("vod_id"));
|
||||
vod.put("vod_name", obj.getString("vod_name"));
|
||||
vod.put("vod_pic", obj.getString("vod_pic"));
|
||||
vod.put("type_name", obj.optString("vod_class"));
|
||||
vod.put("vod_year", obj.optString("vod_year"));
|
||||
vod.put("vod_lang", obj.optString("vod_lang"));
|
||||
vod.put("vod_area", obj.optString("vod_area"));
|
||||
vod.put("vod_remarks", obj.optString("vod_remarks"));
|
||||
vod.put("vod_actor", obj.optString("vod_actor"));
|
||||
vod.put("vod_director", obj.optString("vod_director"));
|
||||
vod.put("vod_content", obj.optString("vod_content"));
|
||||
vod.put("vod_play_from", obj.getString("vod_play_from"));
|
||||
vod.put("vod_play_url", obj.getString("vod_play_url"));
|
||||
} else if (type.equals("AppTV")) {
|
||||
String url = ids.get(0);
|
||||
String json = OkHttpUtil.string(url, null);
|
||||
JSONObject obj = new JSONObject(json);
|
||||
vod.put("vod_id", obj.getString("id"));
|
||||
vod.put("vod_name", obj.getString("title"));
|
||||
vod.put("vod_pic", obj.getString("img_url"));
|
||||
vod.put("type_name", jsonArr2Str(obj.optJSONArray("type")));
|
||||
vod.put("vod_year", obj.optString("pubtime"));
|
||||
vod.put("vod_area", jsonArr2Str(obj.optJSONArray("area")));
|
||||
vod.put("vod_remarks", obj.optString("trunk"));
|
||||
vod.put("vod_actor", jsonArr2Str(obj.optJSONArray("actor")));
|
||||
vod.put("vod_director", jsonArr2Str(obj.optJSONArray("director")));
|
||||
vod.put("vod_content", obj.optString("intro"));
|
||||
Map<String, String> vod_play = new LinkedHashMap<>();
|
||||
JSONObject playList = obj.getJSONObject("videolist");
|
||||
Iterator<String> playListKeys = playList.keys();
|
||||
while (playListKeys.hasNext()) {
|
||||
String from = playListKeys.next();
|
||||
JSONArray playListUrls = playList.getJSONArray(from);
|
||||
ArrayList<String> urls = new ArrayList<>();
|
||||
for (int j = 0; j < playListUrls.length(); j++) {
|
||||
JSONObject urlObj = playListUrls.getJSONObject(j);
|
||||
urls.add(urlObj.getString("title") + "$" + urlObj.getString("url"));
|
||||
}
|
||||
vod_play.put(from, TextUtils.join("#", urls));
|
||||
}
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vod.put("vod_play_from", vod_play_from);
|
||||
vod.put("vod_play_url", vod_play_url);
|
||||
} else if (type.equals("aiKanTv")) {
|
||||
String url = cfg.optString("detailUrl").replace("%s", ids.get(0));
|
||||
String json = OkHttpUtil.string(url, null);
|
||||
JSONObject obj = new JSONObject(json).optJSONObject("data");
|
||||
vod.put("vod_id", obj.getString("vod_id"));
|
||||
vod.put("vod_name", obj.getString("vod_name"));
|
||||
vod.put("vod_pic", obj.getString("vod_pic"));
|
||||
vod.put("type_name", obj.optString("vod_class"));
|
||||
vod.put("vod_year", obj.optString("vod_year"));
|
||||
vod.put("vod_lang", obj.optString("vod_lang"));
|
||||
vod.put("vod_area", obj.optString("vod_area"));
|
||||
vod.put("vod_remarks", obj.optString("vod_remarks"));
|
||||
vod.put("vod_actor", obj.optString("vod_actor"));
|
||||
vod.put("vod_director", obj.optString("vod_director"));
|
||||
vod.put("vod_content", obj.optString("vod_content"));
|
||||
|
||||
Map<String, String> vod_play = new LinkedHashMap<>();
|
||||
JSONArray playList = obj.getJSONArray("vod_play_list");
|
||||
for (int i = 0; i < playList.length(); i++) {
|
||||
JSONObject playListObj = playList.getJSONObject(i);
|
||||
String from = playListObj.getString("from");
|
||||
String playUrls = playListObj.getString("url");
|
||||
if (playUrls.length() > 0) {
|
||||
vod_play.put(from, playUrls);
|
||||
}
|
||||
}
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vod.put("vod_play_from", vod_play_from);
|
||||
vod.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vod);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
if (quick)
|
||||
return "";
|
||||
fetchRule();
|
||||
JSONObject cfg = getJson();
|
||||
if (cfg != null) {
|
||||
String type = cfg.optString("type");
|
||||
String url = cfg.optString("searchUrl");
|
||||
if (!url.isEmpty()) {
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
url = url.replace("%s", URLEncoder.encode(key));
|
||||
String json = OkHttpUtil.string(url, null);
|
||||
if (type.equals("AppV0")) {
|
||||
JSONArray list = new JSONObject(json).optJSONArray("list");
|
||||
for (int i = 0; i < list.length(); i++) {
|
||||
JSONObject obj = list.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", obj.getString("vod_id"));
|
||||
v.put("vod_name", obj.getString("vod_name"));
|
||||
v.put("vod_pic", obj.getString("vod_pic"));
|
||||
v.put("vod_remarks", obj.getString("vod_remarks"));
|
||||
videos.put(v);
|
||||
}
|
||||
} else if (type.equals("AppTV")) {
|
||||
JSONArray list = new JSONObject(json).optJSONArray("data");
|
||||
for (int i = 0; i < list.length(); i++) {
|
||||
JSONObject obj = list.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", obj.getString("nextlink"));
|
||||
v.put("vod_name", obj.getString("title"));
|
||||
v.put("vod_pic", obj.getString("pic"));
|
||||
v.put("vod_remarks", obj.getString("state"));
|
||||
videos.put(v);
|
||||
}
|
||||
} else if (type.equals("aiKanTv")) {
|
||||
JSONArray list = new JSONObject(json).optJSONObject("data").optJSONArray("list");
|
||||
for (int i = 0; i < list.length(); i++) {
|
||||
JSONObject obj = list.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", obj.getString("vod_id"));
|
||||
v.put("vod_name", obj.getString("vod_name"));
|
||||
v.put("vod_pic", obj.getString("vod_pic"));
|
||||
v.put("vod_remarks", obj.getString("vod_remarks"));
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
fetchRule();
|
||||
if (vipFlags.contains(flag)) {
|
||||
try {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 1);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", id);
|
||||
result.put("header", "");
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
// 如果是视频直连 直接返回免解
|
||||
else if (isVideoFormat(id)) {
|
||||
try {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 0);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", id);
|
||||
result.put("header", "");
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
// 尝试解析
|
||||
try {
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 1);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", id);
|
||||
result.put("header", "");
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,517 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OKCallBack;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import okhttp3.Call;
|
||||
|
||||
public class YydsAli1 extends Spider {
|
||||
private static final String siteUrl = "https://cmn.yyds.fans";
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
}
|
||||
|
||||
private HashMap<String, String> getHeaders(String url) {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("accept", "application/json, text/plain, */*");
|
||||
headers.put("origin", "https://yyds.fans");
|
||||
headers.put("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36");
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeContent(boolean filter) {
|
||||
try {
|
||||
String url = siteUrl + "/api/categories";
|
||||
String content = OkHttpUtil.string(url, getHeaders(url));
|
||||
JSONObject jsonObject = new JSONObject(content);
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("data");
|
||||
JSONArray classes = new JSONArray();
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject jObj = jsonArray.getJSONObject(i);
|
||||
String typeName = jObj.getString("title");
|
||||
if (typeName.equals("首页") || typeName.equals("热门精选")) {
|
||||
continue;
|
||||
}
|
||||
String typeId = jObj.getString("id");
|
||||
JSONObject newCls = new JSONObject();
|
||||
newCls.put("type_id", typeId);
|
||||
newCls.put("type_name", typeName);
|
||||
classes.put(newCls);
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("class", classes);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String homeVideoContent() {
|
||||
try {
|
||||
JSONArray videos = new JSONArray();
|
||||
try {
|
||||
String url = siteUrl + "/api/posts";
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("category_id", "0");
|
||||
json.put("skip", "0");
|
||||
json.put("limit", "30");
|
||||
json.put("keyword", "");
|
||||
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), url, json.toString(), getHeaders(url), new OKCallBack.OKCallBackString() {
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(response);
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("data");
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("id"));
|
||||
v.put("vod_name", vObj.getString("title"));
|
||||
v.put("vod_pic", vObj.optString("cover"));
|
||||
String mark = vObj.optString("subtitle");
|
||||
if (mark.equals("null"))
|
||||
mark = "";
|
||||
v.put("vod_remarks", mark);
|
||||
videos.put(v);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
|
||||
try {
|
||||
int limit = 30;
|
||||
int page = Integer.parseInt(pg);
|
||||
if (page == 0) {
|
||||
page = 1;
|
||||
}
|
||||
String url = siteUrl + "/api/posts";
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("category_id", tid);
|
||||
json.put("skip", ((page - 1) * limit) + "");
|
||||
json.put("limit", limit + "");
|
||||
json.put("keyword", "");
|
||||
JSONArray videos = new JSONArray();
|
||||
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), url, json.toString(), getHeaders(url), new OKCallBack.OKCallBackString() {
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(response);
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("data");
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("id"));
|
||||
v.put("vod_name", vObj.getString("title"));
|
||||
v.put("vod_pic", vObj.optString("cover"));
|
||||
String mark = vObj.optString("subtitle");
|
||||
if (mark.equals("null"))
|
||||
mark = "";
|
||||
v.put("vod_remarks", mark);
|
||||
videos.put(v);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("page", page);
|
||||
int pageCount = videos.length() == limit ? page + 1 : page;
|
||||
result.put("pagecount", pageCount);
|
||||
result.put("limit", limit);
|
||||
result.put("total", Integer.MAX_VALUE);
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Pattern aliyun = Pattern.compile(".*?aliyundrive.com/s/(\\w+)[^\\w]?");
|
||||
Pattern aliyunShort = Pattern.compile(".*?alywp.net/(\\w+)[^\\w]?");
|
||||
|
||||
@Override
|
||||
public String detailContent(List<String> ids) {
|
||||
try {
|
||||
String url = siteUrl + "/api/post-info";
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("id", ids.get(0));
|
||||
JSONObject vodAtom = new JSONObject();
|
||||
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), url, json.toString(), getHeaders(url), new OKCallBack.OKCallBackString() {
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
try {
|
||||
JSONObject dataObject = new JSONObject(response);
|
||||
JSONObject vObj = dataObject.getJSONObject("data");
|
||||
|
||||
vodAtom.put("vod_id", vObj.getString("id"));
|
||||
vodAtom.put("vod_name", vObj.getString("title"));
|
||||
vodAtom.put("vod_pic", vObj.getString("cover"));
|
||||
vodAtom.put("type_name", "");
|
||||
vodAtom.put("vod_year", vObj.getString("year"));
|
||||
vodAtom.put("vod_area", vObj.getString("region"));
|
||||
String mark = vObj.optString("subtitle");
|
||||
if (mark.equals("null"))
|
||||
mark = "";
|
||||
vodAtom.put("vod_remarks", mark);
|
||||
vodAtom.put("vod_actor", vObj.getString("actors"));
|
||||
vodAtom.put("vod_director", vObj.getString("director"));
|
||||
String desc = vObj.optString("desc");
|
||||
if (desc.equals("null"))
|
||||
desc = "";
|
||||
vodAtom.put("vod_content", desc);
|
||||
|
||||
Map<String, String> vod_play = new LinkedHashMap<>();
|
||||
JSONArray jsonArray = vObj.getJSONArray("links");
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject obj = jsonArray.getJSONObject(i);
|
||||
String link = obj.optString("link", "");
|
||||
updatePlaylist(link, vod_play);
|
||||
}
|
||||
if (vod_play.size() == 0 && vObj.optString("content").length() > 0) {
|
||||
updatePlaylist(vObj.optString("content"), vod_play);
|
||||
}
|
||||
if (vod_play.size() > 0) {
|
||||
String vod_play_from = TextUtils.join("$$$", vod_play.keySet());
|
||||
String vod_play_url = TextUtils.join("$$$", vod_play.values());
|
||||
vodAtom.put("vod_play_from", vod_play_from);
|
||||
vodAtom.put("vod_play_url", vod_play_url);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray list = new JSONArray();
|
||||
list.put(vodAtom);
|
||||
result.put("list", list);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private void updatePlaylist(String link, Map<String, String> vod_play) {
|
||||
String shareId = null;
|
||||
Matcher matcher = aliyun.matcher(link);
|
||||
if (matcher.find()) {
|
||||
shareId = matcher.group(1);
|
||||
} else {
|
||||
matcher = aliyunShort.matcher(link);
|
||||
if (matcher.find()) {
|
||||
shareId = matcher.group(1);
|
||||
Map<String, List<String>> respHeaders = new TreeMap<>();
|
||||
OkHttpUtil.stringNoRedirect("https://alywp.net/" + shareId, null, respHeaders);
|
||||
shareId = OkHttpUtil.getRedirectLocation(respHeaders);
|
||||
if (shareId != null) {
|
||||
matcher = aliyun.matcher(shareId);
|
||||
if (matcher.find()) {
|
||||
shareId = matcher.group(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shareId != null) {
|
||||
String shareToken = getShareTk(shareId, "");
|
||||
ArrayList<String> vodItems = new ArrayList<>();
|
||||
getFileList(shareToken, shareId, "", "root", vodItems);
|
||||
vod_play.put("阿里云盘" + (vod_play.size() > 0 ? vod_play.size() : ""), TextUtils.join("#", vodItems));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String playerContent(String flag, String id, List<String> vipFlags) {
|
||||
try {
|
||||
String[] infos = id.split("\\+");
|
||||
String shareTk = getShareTk(infos[0], "");
|
||||
refreshTk();
|
||||
if (!accessTk.isEmpty()) {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("share_id", infos[0]);
|
||||
json.put("category", "live_transcoding");
|
||||
json.put("file_id", infos[1]);
|
||||
json.put("template_id", "");
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("x-share-token", shareTk);
|
||||
headers.put("authorization", accessTk);
|
||||
OKCallBack.OKCallBackString callback = new OKCallBack.OKCallBackString() {
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
String videoUrl = "";
|
||||
try {
|
||||
JSONArray playList = new JSONObject(response).getJSONObject("video_preview_play_info").getJSONArray("live_transcoding_task_list");
|
||||
String[] orders = new String[]{"FHD", "HD", "SD"};
|
||||
for (String or : orders) {
|
||||
for (int i = 0; i < playList.length(); i++) {
|
||||
JSONObject obj = playList.getJSONObject(i);
|
||||
if (obj.optString("template_id").equals(or)) {
|
||||
videoUrl = obj.getString("url");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!videoUrl.isEmpty())
|
||||
break;
|
||||
}
|
||||
if (videoUrl.isEmpty() && playList.length() > 0) {
|
||||
videoUrl = playList.getJSONObject(0).getString("url");
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
} finally {
|
||||
setResult(videoUrl);
|
||||
}
|
||||
}
|
||||
};
|
||||
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "https://api.aliyundrive.com/v2/file/get_share_link_video_preview_play_info", json.toString(), headers, callback);
|
||||
JSONArray playList = new JSONObject(callback.getResult()).getJSONObject("video_preview_play_info").getJSONArray("live_transcoding_task_list");
|
||||
String videoUrl = "";
|
||||
String[] orders = new String[]{"FHD", "HD", "SD"};
|
||||
for (String or : orders) {
|
||||
for (int i = 0; i < playList.length(); i++) {
|
||||
JSONObject obj = playList.getJSONObject(i);
|
||||
if (obj.optString("template_id").equals(or)) {
|
||||
videoUrl = obj.getString("url");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!videoUrl.isEmpty())
|
||||
break;
|
||||
}
|
||||
if (videoUrl.isEmpty() && playList.length() > 0) {
|
||||
videoUrl = playList.getJSONObject(0).getString("url");
|
||||
}
|
||||
JSONObject headerObj = new JSONObject();
|
||||
headerObj.put("user-agent", " Dalvik/2.1.0 (Linux; U; Android 7.0; ZTE BA520 Build/MRA58K)");
|
||||
headerObj.put("referer", " https://www.aliyundrive.com/");
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("parse", 0);
|
||||
result.put("playUrl", "");
|
||||
result.put("url", videoUrl);
|
||||
result.put("header", headerObj.toString());
|
||||
return result.toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
if (quick)
|
||||
return "";
|
||||
JSONArray videos = new JSONArray();
|
||||
try {
|
||||
String url = siteUrl + "/api/posts";
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("category_id", "-1");
|
||||
json.put("skip", "0");
|
||||
json.put("limit", "30");
|
||||
json.put("keyword", key);
|
||||
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), url, json.toString(), getHeaders(url), new OKCallBack.OKCallBackString() {
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(response);
|
||||
JSONArray jsonArray = jsonObject.getJSONArray("data");
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject vObj = jsonArray.getJSONObject(i);
|
||||
JSONObject v = new JSONObject();
|
||||
v.put("vod_id", vObj.getString("id"));
|
||||
v.put("vod_name", vObj.getString("title"));
|
||||
v.put("vod_pic", vObj.getString("cover"));
|
||||
v.put("vod_remarks", vObj.getString("subtitle"));
|
||||
videos.put(v);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String aliTk = "";
|
||||
|
||||
private void fetchAliTk() {
|
||||
if (aliTk.isEmpty()) {
|
||||
try {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", "okhttp/4.5.0");
|
||||
aliTk = new JSONObject(OkHttpUtil.string("http://81.68.244.5/tv/alitk", headers)).optString("alitk");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String accessTk = "";
|
||||
|
||||
private void refreshTk() {
|
||||
fetchAliTk();
|
||||
if (!aliTk.isEmpty() && accessTk.isEmpty()) {
|
||||
try {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("refresh_token", aliTk);
|
||||
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "https://api.aliyundrive.com/token/refresh", json.toString(), new OKCallBack.OKCallBackString() {
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
try {
|
||||
JSONObject obj = new JSONObject(response);
|
||||
accessTk = obj.getString("token_type") + " " + obj.getString("access_token");
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getShareTk(String shareId, String sharePwd) {
|
||||
try {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("share_id", shareId);
|
||||
json.put("share_pwd", "");
|
||||
OKCallBack.OKCallBackString callback = new OKCallBack.OKCallBackString() {
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
|
||||
}
|
||||
};
|
||||
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "https://api.aliyundrive.com/v2/share_link/get_share_token", json.toString(), callback);
|
||||
return new JSONObject(callback.getResult()).optString("share_token");
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
private void getFileList(String shareTk, String shareId, String sharePwd, String root, ArrayList<String> vodItems) {
|
||||
try {
|
||||
// 取文件夹
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("share_id", shareId);
|
||||
json.put("parent_file_id", root);
|
||||
json.put("limit", 100);
|
||||
json.put("image_thumbnail_process", "image/resize,w_160/format,jpeg");
|
||||
json.put("image_url_process", "image/resize,w_1920/format,jpeg");
|
||||
json.put("video_thumbnail_process", "video/snapshot,t_1000,f_jpg,ar_auto,w_300");
|
||||
json.put("order_by", "name");
|
||||
json.put("order_direction", "ASC");
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("x-share-token", shareTk);
|
||||
OKCallBack.OKCallBackString callback = new OKCallBack.OKCallBackString() {
|
||||
@Override
|
||||
public void onFailure(Call call, Exception e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
|
||||
}
|
||||
};
|
||||
OkHttpUtil.postJson(OkHttpUtil.defaultClient(), "https://api.aliyundrive.com/adrive/v3/file/list", json.toString(), headers, callback);
|
||||
JSONArray rootList = new JSONObject(callback.getResult()).optJSONArray("items");
|
||||
if (rootList != null && rootList.length() > 0) {
|
||||
for (int i = 0; i < rootList.length(); i++) {
|
||||
JSONObject item = rootList.getJSONObject(i);
|
||||
if (item.getString("type").equals("folder")) {
|
||||
String dirId = item.getString("file_id");
|
||||
getFileList(shareTk, shareId, sharePwd, dirId, vodItems);
|
||||
} else {
|
||||
if (item.getString("type").equals("file") && !item.getString("file_extension").equals("txt")) {
|
||||
String fileId = item.getString("file_id");
|
||||
String fileName = item.getString("name");
|
||||
vodItems.add(fileName + "$" + shareId + "+" + fileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 取文件列表
|
||||
} catch (JSONException e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
package com.github.catvod.spider;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.github.catvod.crawler.Spider;
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.utils.okhttp.OkHttpUtil;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class Zhaozy extends Spider {
|
||||
private static final Pattern aliyun = Pattern.compile("(https://www.aliyundrive.com/s/[^\"]+)");
|
||||
private PushAgent pushAgent;
|
||||
|
||||
public String detailContent(List<String> list) {
|
||||
try {
|
||||
Pattern pattern = aliyun;
|
||||
if (pattern.matcher(list.get(0)).find()) {
|
||||
return pushAgent.detailContent(list);
|
||||
}
|
||||
Matcher matcher = pattern.matcher(OkHttpUtil.string("https://zhaoziyuan.me/" + list.get(0), null));
|
||||
if (!matcher.find()) {
|
||||
return "";
|
||||
}
|
||||
list.set(0, matcher.group(1));
|
||||
return pushAgent.detailContent(list);
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public void init(Context context, String str) {
|
||||
super.init(context, str);
|
||||
pushAgent = new PushAgent();
|
||||
pushAgent.init(context, str);
|
||||
}
|
||||
|
||||
public String playerContent(String str, String str2, List<String> list) {
|
||||
return pushAgent.playerContent(str, str2, list);
|
||||
}
|
||||
|
||||
protected static HashMap<String, String> sHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36");
|
||||
headers.put("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.9");
|
||||
headers.put("Accept-encoding", "gzip, deflate, br");
|
||||
headers.put("Accept-language", "zh-SG,zh;q=0.9,en-GB;q=0.8,en;q=0.7,zh-CN;q=0.6");
|
||||
return headers;
|
||||
}
|
||||
|
||||
private Pattern regexVid = Pattern.compile("(\\S+)");
|
||||
|
||||
public String searchContent(String key, boolean quick) {
|
||||
try {
|
||||
String url = "https://zhaoziyuan.me/so?filename=" + URLEncoder.encode(key);
|
||||
Document docs = Jsoup.parse(OkHttpUtil.string(url, null));
|
||||
JSONObject result = new JSONObject();
|
||||
JSONArray videos = new JSONArray();
|
||||
Elements list = docs.select("div.li_con div.news_text");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Element doc = list.get(i);
|
||||
String sourceName = doc.select("div.news_text a h3").text();
|
||||
if (sourceName.contains(key)) {
|
||||
String list1 = doc.select("div.news_text a").attr("href");
|
||||
Matcher matcher = regexVid.matcher(list1);
|
||||
if (matcher.find()) {
|
||||
JSONObject v = new JSONObject();
|
||||
String group = matcher.group(1);
|
||||
String cover = "https://inews.gtimg.com/newsapp_bt/0/13263837859/1000";
|
||||
String remark = doc.select("div.news_text a p").text();
|
||||
|
||||
v.put("vod_name", sourceName);
|
||||
v.put("vod_remarks", remark);
|
||||
v.put("vod_id", group);
|
||||
v.put("vod_pic", cover);
|
||||
videos.put(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.put("list", videos);
|
||||
return result.toString();
|
||||
} catch (Exception e) {
|
||||
SpiderDebug.log(e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user