上传XPath苹果CMS直链分析代码和NfMovies爬取代码,增加影视大全搜索接口支持及文档说明

This commit is contained in:
小黄瓜 2021-10-20 12:29:00 +08:00
parent 1eacd72f28
commit 907f6c2d3b
5 changed files with 619 additions and 15 deletions

View File

@ -44,7 +44,7 @@
}
```
Json解析扩展需v2.0.2及以上版本)
**Json解析扩展需v2.0.2及以上版本)**
通过jar包可以实现json解析并发、轮询等相关功能**参与并发和轮询的json解析地址默认为解析地址列表中的所有json解析即type=1**。
@ -63,9 +63,85 @@ Json解析扩展需v2.0.2及以上版本)
}
```
XPath规则套娃需v2.0.4及以上版本)
**XPath规则套娃需v2.0.4及以上版本)**
套娃规则祥见[XPath.md](/XPath.md), 套娃规则合集[戳我](/../../issues/21)
**影视大全搜索接口支持**2021.10.20 by 小黄瓜) 接口杂乱,搜出来能不能播随缘了。
代码里读取[影视大全配置json](https://pj567.coding.net/p/source/d/source/git/raw/master/mobile/config.json)中的搜索接口
所以你需要在自定义配置中增加相关搜索站配置ext字段填影视大全配置json中的`sourceName`当前支持type为AppV0、AppTV、aiKanTv的搜索接口。
注意:这些配置只能用于搜索,也只支持在搜索界面搜索,不支持相关搜索,更不能作为首页源。
```json
{"key":"csp_ysdq_007影视", "name":"007影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"007影视"},
{"key":"csp_ysdq_555电影", "name":"555电影(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"555电影"},
{"key":"csp_ysdq_5060影院", "name":"5060影院(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"5060影院"},
{"key":"csp_ysdq_913E影视", "name":"913E影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"913E影视"},
{"key":"csp_ysdq_播放呀", "name":"播放呀(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"播放呀"},
{"key":"csp_ysdq_畅视影视", "name":"畅视影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"畅视影视"},
{"key":"csp_ysdq_点播TV", "name":"点播TV(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"点播TV"},
{"key":"csp_ysdq_迪迪影院", "name":"迪迪影院(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"迪迪影院"},
{"key":"csp_ysdq_嘀哩嘀哩", "name":"嘀哩嘀哩(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"嘀哩嘀哩"},
{"key":"csp_ysdq_毒舌电影", "name":"毒舌电影(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"毒舌电影"},
{"key":"csp_ysdq_大师兄", "name":"大师兄(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"大师兄"},
{"key":"csp_ysdq_瓜皮TV", "name":"瓜皮TV(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"瓜皮TV"},
{"key":"csp_ysdq_海胆影视", "name":"海胆影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"海胆影视"},
{"key":"csp_ysdq_海绵影视", "name":"海绵影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"海绵影视"},
{"key":"csp_ysdq_京广航", "name":"京广航(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"京广航"},
{"key":"csp_ysdq_九合视频", "name":"九合视频(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"九合视频"},
{"key":"csp_ysdq_江湖影视", "name":"江湖影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"江湖影视"},
{"key":"csp_ysdq_极客", "name":"极客(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"极客"},
{"key":"csp_ysdq_久九影视", "name":"久九影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"久九影视"},
{"key":"csp_ysdq_蓝果影视", "name":"蓝果影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"蓝果影视"},
{"key":"csp_ysdq_琳琅影视", "name":"琳琅影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"琳琅影视"},
{"key":"csp_ysdq_极乐阁", "name":"极乐阁(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"极乐阁"},
{"key":"csp_ysdq_萌蛋蛋", "name":"萌蛋蛋(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"萌蛋蛋"},
{"key":"csp_ysdq_思古影视", "name":"思古影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"思古影视"},
{"key":"csp_ysdq_污妖动漫", "name":"污妖动漫(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"污妖动漫"},
{"key":"csp_ysdq_小易影视", "name":"小易影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"小易影视"},
{"key":"csp_ysdq_影视工场", "name":"影视工场(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"影视工场"},
{"key":"csp_ysdq_追剧达人", "name":"追剧达人(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"追剧达人"},
{"key":"csp_ysdq_80影视", "name":"80影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"80影视"},
{"key":"csp_ysdq_80k影视", "name":"80k影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"80k影视"},
{"key":"csp_ysdq_FUFU影视", "name":"FUFU影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"FUFU影视"},
{"key":"csp_ysdq_VIP影视", "name":"VIP影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"VIP影视"},
{"key":"csp_ysdq_爱影视", "name":"爱影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"爱影视"},
{"key":"csp_ysdq_白菜追剧", "name":"白菜追剧(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"白菜追剧"},
{"key":"csp_ysdq_初心影视", "name":"初心影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"初心影视"},
{"key":"csp_ysdq_段友影视", "name":"段友影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"段友影视"},
{"key":"csp_ysdq_飞捷影视", "name":"飞捷影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"飞捷影视"},
{"key":"csp_ysdq_公主影视", "name":"公主影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"公主影视"},
{"key":"csp_ysdq_辉哥影视", "name":"辉哥影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"辉哥影视"},
{"key":"csp_ysdq_哈尼视频", "name":"哈尼视频(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"哈尼视频"},
{"key":"csp_ysdq_核桃影视V1", "name":"核桃影视V1(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"核桃影视V1"},
{"key":"csp_ysdq_懒猫电影", "name":"懒猫电影(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"懒猫电影"},
{"key":"csp_ysdq_冷视TV", "name":"冷视TV(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"冷视TV"},
{"key":"csp_ysdq_喵乐影视", "name":"喵乐影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"喵乐影视"},
{"key":"csp_ysdq_南府追剧", "name":"南府追剧(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"南府追剧"},
{"key":"csp_ysdq_内涵影视", "name":"内涵影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"内涵影视"},
{"key":"csp_ysdq_柠檬影视", "name":"柠檬影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"柠檬影视"},
{"key":"csp_ysdq_手指影视", "name":"手指影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"手指影视"},
{"key":"csp_ysdq_淘剧社", "name":"淘剧社(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"淘剧社"},
{"key":"csp_ysdq_团夕影院", "name":"团夕影院(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"团夕影院"},
{"key":"csp_ysdq_我爱跟剧", "name":"我爱跟剧(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"我爱跟剧"},
{"key":"csp_ysdq_吾爱影视", "name":"吾爱影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"吾爱影视"},
{"key":"csp_ysdq_小城影视", "name":"小城影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"小城影视"},
{"key":"csp_ysdq_先锋影视", "name":"先锋影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"先锋影视"},
{"key":"csp_ysdq_小极影视", "name":"小极影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"小极影视"},
{"key":"csp_ysdq_小蜻蜓视频", "name":"小蜻蜓视频(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"小蜻蜓视频"},
{"key":"csp_ysdq_休闲影视", "name":"休闲影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"休闲影视"},
{"key":"csp_ysdq_远方影视", "name":"远方影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"远方影视"},
{"key":"csp_ysdq_颖家影院", "name":"颖家影院(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"颖家影院"},
{"key":"csp_ysdq_优炫影视", "name":"优炫影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"优炫影视"},
{"key":"csp_ysdq_一只鱼影视", "name":"一只鱼影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"一只鱼影视"},
{"key":"csp_ysdq_追番猫", "name":"追番猫(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"追番猫"},
{"key":"csp_ysdq_追剧吧", "name":"追剧吧(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"追剧吧"},
{"key":"csp_ysdq_侦探影视", "name":"侦探影视(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"侦探影视"},
{"key":"csp_ysdq_追影兔", "name":"追影兔(搜)", "type":3, "api":"csp_Ysdq","searchable":1,"quickSearch":0, "ext":"追影兔"}
```
## 基础类
----

View File

@ -29,16 +29,15 @@ public class XPath extends Spider {
super.init(context);
}
private XPathRule rule = null;
public void init(Context context, String extend) {
super.init(context, extend);
rule = XPathRule.fromJson(extend);
this.ext = extend;
}
@Override
public String homeContent(boolean filter) {
try {
fetchRule();
JSONObject result = new JSONObject();
JSONArray classes = new JSONArray();
if (rule.getCateManual().size() > 0) {
@ -52,9 +51,7 @@ public class XPath extends Spider {
}
try {
String webUrl = rule.getHomeUrl();
SpiderDebug.log(webUrl);
SpiderUrl su = new SpiderUrl(webUrl, getHeaders(webUrl));
SpiderReqResult srr = SpiderReq.get(su);
SpiderReqResult srr = fetch(webUrl);
JXDocument doc = JXDocument.create(srr.content);
if (rule.getCateManual().size() == 0) {
List<JXNode> navNodes = doc.selN(rule.getCateNode());
@ -107,7 +104,7 @@ public class XPath extends Spider {
return "";
}
private HashMap<String, String> getHeaders(String url) {
protected HashMap<String, String> getHeaders(String url) {
HashMap<String, String> headers = new HashMap<>();
headers.put("User-Agent", rule.getUa().isEmpty()
? "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36"
@ -118,6 +115,7 @@ public class XPath extends Spider {
@Override
public String homeVideoContent() {
try {
fetchRule();
} catch (Exception e) {
SpiderDebug.log(e);
}
@ -127,10 +125,9 @@ public class XPath extends Spider {
@Override
public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) {
try {
fetchRule();
String webUrl = rule.getCateUrl().replace("{cateId}", tid).replace("{catePg}", pg);
SpiderDebug.log(webUrl);
SpiderUrl su = new SpiderUrl(webUrl, getHeaders(webUrl));
SpiderReqResult srr = SpiderReq.get(su);
SpiderReqResult srr = fetch(webUrl);
JSONArray videos = new JSONArray();
JXDocument doc = JXDocument.create(srr.content);
List<JXNode> vodNodes = doc.selN(rule.getCateVodNode());
@ -175,10 +172,9 @@ public class XPath extends Spider {
@Override
public String detailContent(List<String> ids) {
try {
fetchRule();
String webUrl = rule.getDetailUrl().replace("{vid}", ids.get(0));
SpiderDebug.log(webUrl);
SpiderUrl su = new SpiderUrl(webUrl, getHeaders(webUrl));
SpiderReqResult srr = SpiderReq.get(su);
SpiderReqResult srr = fetch(webUrl);
JXDocument doc = JXDocument.create(srr.content);
JXNode vodNode = doc.selNOne(rule.getDetailNode());
@ -319,6 +315,7 @@ public class XPath extends Spider {
@Override
public String playerContent(String flag, String id, List<String> vipFlags) {
try {
fetchRule();
String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id);
SpiderDebug.log(webUrl);
JSONObject result = new JSONObject();
@ -338,6 +335,7 @@ public class XPath extends Spider {
@Override
public String searchContent(String key, boolean quick) {
try {
fetchRule();
String webUrl = rule.getSearchUrl().replace("{wd}", URLEncoder.encode(key));
SpiderDebug.log(webUrl);
SpiderUrl su = new SpiderUrl(webUrl, getHeaders(webUrl));
@ -438,4 +436,33 @@ public class XPath extends Spider {
}
return false;
}
protected String ext = null;
protected XPathRule rule = null;
protected void fetchRule() {
if (rule == null) {
if (ext != null) {
if (ext.startsWith("http")) {
SpiderUrl su = new SpiderUrl(ext, null);
String json = SpiderReq.get(su).content;
rule = XPathRule.fromJson(json);
loadRuleExt(json);
} else {
rule = XPathRule.fromJson(ext);
loadRuleExt(ext);
}
}
}
}
protected void loadRuleExt(String json) {
}
protected SpiderReqResult fetch(String webUrl) {
SpiderDebug.log(webUrl);
SpiderUrl su = new SpiderUrl(webUrl, getHeaders(webUrl));
return SpiderReq.get(su);
}
}

View File

@ -0,0 +1,188 @@
package com.github.catvod.spider;
import android.content.Context;
import android.text.TextUtils;
import android.util.Base64;
import com.github.catvod.crawler.SpiderDebug;
import com.github.catvod.crawler.SpiderReqResult;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class XPathMac extends XPath {
// 尝试分析直连
private boolean decodePlayUrl;
// 尝试匹配官源标识以调用应用配置中的解析列表
private boolean decodeVipFlag;
// 播放器配置js
private String playerConfigJs = "";
// 播放器配置js取值正则
private String playerConfigJsRegex = "[\\W|\\S|.]*?MacPlayerConfig.player_list[\\W|\\S|.]*?=([\\W|\\S|.]*?),MacPlayerConfig.downer_list";
// 站点里播放源对应的真实官源
private HashMap<String, String> show2VipFlag = new HashMap<>();
/**
* mac cms 直连和官源调用应用内播放列表支持
*
* @param context
* @param extend
*/
public void init(Context context, String extend) {
super.init(context, extend);
}
@Override
protected void loadRuleExt(String json) {
try {
JSONObject jsonObj = new JSONObject(json);
decodePlayUrl = jsonObj.optBoolean("dcPlayUrl", false);
decodeVipFlag = jsonObj.optBoolean("dcVipFlag", false);
JSONObject dcShow2Vip = jsonObj.optJSONObject("dcShow2Vip");
if (dcShow2Vip != null) {
Iterator<String> keys = dcShow2Vip.keys();
while (keys.hasNext()) {
String name = keys.next();
show2VipFlag.put(name.trim(), dcShow2Vip.getString(name).trim());
}
}
playerConfigJs = jsonObj.optString("pCfgJs").trim();
playerConfigJsRegex = jsonObj.optString("pCfgJsR", playerConfigJsRegex).trim();
} catch (JSONException e) {
SpiderDebug.log(e);
}
}
@Override
public String homeContent(boolean filter) {
String result = super.homeContent(filter);
if (result.length() > 0 && playerConfigJs.length() > 0) { // 尝试通过playerConfigJs获取展示和flag匹配关系
SpiderReqResult srr = fetch(playerConfigJs);
Matcher matcher = Pattern.compile(playerConfigJsRegex).matcher(srr.content);
if (matcher.find()) {
try {
JSONObject jsonObject = new JSONObject(matcher.group(1));
Iterator<String> keys = jsonObject.keys();
while (keys.hasNext()) {
String key = keys.next();
JSONObject keyObj = jsonObject.optJSONObject(key);
if (keyObj == null)
continue;
String show = keyObj.optString("show").trim();
if (show.isEmpty())
continue;
show2VipFlag.put(show, key);
}
} catch (Exception e) {
SpiderDebug.log(e);
}
}
SpiderDebug.log(srr.content);
}
return result;
}
@Override
public String detailContent(List<String> ids) {
String result = super.detailContent(ids);
if (decodeVipFlag && result.length() > 0) {
try {
JSONObject jsonObject = new JSONObject(result);
String playFrom[] = jsonObject.optJSONArray("list").getJSONObject(0).optString("vod_play_from").split("\\$\\$\\$");
if (playFrom.length > 0) {
for (int i = 0; i < playFrom.length; i++) {
if (show2VipFlag.containsKey(playFrom[i])) {
playFrom[i] = show2VipFlag.get(playFrom[i]);
}
}
jsonObject.optJSONArray("list").getJSONObject(0).put("vod_play_from", TextUtils.join("$$$", playFrom));
result = jsonObject.toString();
}
} catch (Throwable th) {
SpiderDebug.log(th);
}
}
return result;
}
@Override
public String playerContent(String flag, String id, List<String> vipFlags) {
fetchRule();
String webUrl = rule.getPlayUrl().isEmpty() ? id : rule.getPlayUrl().replace("{playUrl}", id);
String videoUrl = null;
// 尝试分析直连
if (decodePlayUrl) {
try {
SpiderReqResult srr = fetch(webUrl);
Document doc = Jsoup.parse(srr.content);
Elements allScript = doc.select("script");
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);
String videoUrlTmp = player.getString("url");
if (player.has("encrypt")) {
int encrypt = player.getInt("encrypt");
if (encrypt == 1) {
videoUrlTmp = URLDecoder.decode(videoUrlTmp);
} else if (encrypt == 2) {
videoUrlTmp = new String(Base64.decode(videoUrlTmp, Base64.DEFAULT));
videoUrlTmp = URLDecoder.decode(videoUrlTmp);
}
}
videoUrl = videoUrlTmp;
break;
}
}
} catch (Exception e) {
SpiderDebug.log(e);
}
}
if (videoUrl != null) {
// 是否使用应用内解析列表解析官源
if (vipFlags.contains(flag)) {
if (decodeVipFlag) {
try {
JSONObject result = new JSONObject();
result.put("parse", 1);
result.put("playUrl", "");
result.put("url", videoUrl);
result.put("header", "");
return result.toString();
} catch (Exception e) {
SpiderDebug.log(e);
}
}
}
// 如果是视频直连 直接返回免解
else if (isVideoFormat(videoUrl)) {
try {
JSONObject result = new JSONObject();
result.put("parse", 0);
result.put("playUrl", "");
result.put("url", videoUrl);
result.put("header", "");
return result.toString();
} catch (Exception e) {
SpiderDebug.log(e);
}
}
}
// 上述都失败了就按默认模式走
return super.playerContent(flag, id, vipFlags);
}
}

View File

@ -0,0 +1,36 @@
package com.github.catvod.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 java.util.HashMap;
public class XPathNfMov extends XPath {
private String cookies = "";
@Override
protected HashMap<String, String> getHeaders(String url) {
HashMap<String, String> hashMap = super.getHeaders(url);
if (cookies.length() > 0)
hashMap.put("Cookie", cookies);
return hashMap;
}
@Override
protected SpiderReqResult fetch(String webUrl) {
SpiderDebug.log(webUrl);
SpiderUrl su = new SpiderUrl(webUrl, getHeaders(webUrl));
SpiderReqResult srr = SpiderReq.get(su);
if (srr.content.contains("http-equiv=\"refresh\"")) {
if (srr.headers.containsKey("set-cookie")) {
cookies = srr.headers.get("set-cookie").get(0);
}
su = new SpiderUrl(webUrl, getHeaders(webUrl));
srr = SpiderReq.get(su);
}
return srr;
}
}

View File

@ -0,0 +1,277 @@
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.SpiderUrl;
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 {
SpiderUrl su = new SpiderUrl("https://pj567.coding.net/p/source/d/source/git/raw/master/mobile/config.json", null);
String json = SpiderReq.get(su).content;
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 = SpiderReq.get(new SpiderUrl(url, null)).content;
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 = SpiderReq.get(new SpiderUrl(url, null)).content;
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 = SpiderReq.get(new SpiderUrl(url, null)).content;
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 = SpiderReq.get(new SpiderUrl(url, null)).content;
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 "";
}
}