Merge pull request #521 from okcaptain/dev

Dev
pull/523/head
okcaptain 2 years ago committed by GitHub
commit 7ef963a2b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      app/build.gradle
  2. 1
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java
  3. 2
      app/src/leanback/java/com/fongmi/android/tv/ui/base/BaseActivity.java
  4. 2
      app/src/main/java/com/fongmi/android/tv/bean/Drm.java
  5. 3
      app/src/main/java/com/fongmi/android/tv/bean/Parse.java
  6. 5
      app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java
  7. 2
      app/src/main/java/com/fongmi/android/tv/player/Source.java
  8. 7
      app/src/main/java/com/fongmi/android/tv/server/Nano.java
  9. 2
      app/src/main/java/com/fongmi/android/tv/utils/Sniffer.java
  10. 12
      app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java
  11. 6
      catvod/src/main/java/com/github/catvod/utils/Json.java
  12. 19
      catvod/src/main/java/com/github/catvod/utils/Util.java
  13. 45
      pyramid/src/main/java/com/undcover/freedom/pyramid/Spider.java
  14. 3
      quickjs/src/main/java/com/fongmi/quickjs/bean/Info.java
  15. 4
      quickjs/src/main/java/com/fongmi/quickjs/bean/Res.java
  16. 19
      quickjs/src/main/java/com/fongmi/quickjs/crawler/Spider.java
  17. 11
      quickjs/src/main/java/com/fongmi/quickjs/method/Global.java
  18. 3
      quickjs/src/main/java/com/fongmi/quickjs/utils/Connect.java
  19. 7
      quickjs/src/main/java/com/fongmi/quickjs/utils/Crypto.java
  20. 134
      quickjs/src/main/java/com/fongmi/quickjs/utils/Parser.java

@ -14,7 +14,7 @@ android {
//noinspection ExpiredTargetSdkVersion
targetSdk 28
versionCode 240
versionName "2.4.0"
versionName "0627"
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]

@ -736,7 +736,6 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
private void setQualityActivated(Result result) {
try {
result.setUrl(Source.get().fetch(result));
mPlayers.start(result, isUseParse(), getSite().isChangeable() ? getSite().getTimeout() : -1);
mBinding.danmaku.hide();
} catch (Exception e) {

@ -3,6 +3,7 @@ package com.fongmi.android.tv.ui.base;
import android.app.Activity;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
@ -15,7 +16,6 @@ import androidx.viewbinding.ViewBinding;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.Setting;
import com.fongmi.android.tv.api.config.WallConfig;
import com.fongmi.android.tv.event.RefreshEvent;
import com.fongmi.android.tv.utils.FileUtil;
import com.fongmi.android.tv.utils.ResUtil;

@ -44,7 +44,7 @@ public class Drm {
private String getUri() {
if (getKey().startsWith("http")) return getKey();
return Server.get().getAddress("license/") + Util.base64(getKey());
return Server.get().getAddress("license/") + Util.base64(getKey(), Util.URL_SAFE);
}
public MediaItem.DrmConfiguration get() {

@ -1,7 +1,6 @@
package com.fongmi.android.tv.bean;
import android.text.TextUtils;
import android.util.Base64;
import androidx.annotation.NonNull;
@ -128,7 +127,7 @@ public class Parse {
public String extUrl() {
int index = getUrl().indexOf("?");
if (getExt().isEmpty() || index == -1) return getUrl();
return getUrl().substring(0, index + 1) + "cat_ext=" + Util.base64(getExt().toString(), Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP) + "&" + getUrl().substring(index + 1);
return getUrl().substring(0, index + 1) + "cat_ext=" + Util.base64(getExt().toString(), Util.URL_SAFE) + "&" + getUrl().substring(index + 1);
}
public HashMap<String, String> mixMap() {

@ -112,7 +112,7 @@ public class SiteViewModel extends ViewModel {
} else {
ArrayMap<String, String> params = new ArrayMap<>();
if (site.getType() == 1 && !extend.isEmpty()) params.put("f", App.gson().toJson(extend));
else if (site.getType() == 4) params.put("ext", Util.base64(App.gson().toJson(extend)));
if (site.getType() == 4) params.put("ext", Util.base64(App.gson().toJson(extend), Util.URL_SAFE));
params.put("ac", site.getType() == 0 ? "videolist" : "detail");
params.put("t", tid);
params.put("pg", page);
@ -157,7 +157,7 @@ public class SiteViewModel extends ViewModel {
});
}
public void executePlayer(MutableLiveData<Result> data, String key, String flag, String id) {
private void executePlayer(MutableLiveData<Result> data, String key, String flag, String id) {
execute(data, () -> {
Source.get().stop();
Site site = VodConfig.get().getSite(key);
@ -199,6 +199,7 @@ public class SiteViewModel extends ViewModel {
result.setFlag(flag);
result.setHeader(site.getHeader());
result.setPlayUrl(site.getPlayUrl());
result.setUrl(Source.get().fetch(result));
result.setParse(Sniffer.isVideoFormat(url.v()) && result.getPlayUrl().isEmpty() ? 0 : 1);
SpiderDebug.log(result.toString());
return result;

@ -10,7 +10,6 @@ import com.fongmi.android.tv.player.extractor.TVBus;
import com.fongmi.android.tv.player.extractor.Thunder;
import com.fongmi.android.tv.player.extractor.Video;
import com.fongmi.android.tv.player.extractor.Youtube;
import com.fongmi.android.tv.player.extractor.ZLive;
import com.fongmi.android.tv.utils.UrlUtil;
import java.util.ArrayList;
@ -38,7 +37,6 @@ public class Source {
extractors.add(new TVBus());
extractors.add(new Video());
extractors.add(new Youtube());
extractors.add(new ZLive());
}
private Extractor getExtractor(String url) {

@ -70,7 +70,7 @@ public class Nano extends NanoHTTPD {
if (url.startsWith("/proxy")) return proxy(session);
if (url.startsWith("/tvbus")) return success(LiveConfig.getResp());
if (url.startsWith("/device")) return success(Device.get().toString());
if (url.startsWith("/license")) return success(Util.decode(url.substring(9)));
if (url.startsWith("/license")) return success(new String(Util.decode(url.substring(9), Util.URL_SAFE)));
for (Process process : process) if (process.isRequest(session, url)) return process.doResponse(session, url, files);
return getAssets(url.substring(1));
}
@ -98,7 +98,10 @@ public class Nano extends NanoHTTPD {
Map<String, String> params = session.getParms();
params.putAll(session.getHeaders());
Object[] rs = VodConfig.get().proxyLocal(params);
return rs[0] instanceof Response ? (Response) rs[0] : newChunkedResponse(Response.Status.lookup((Integer) rs[0]), (String) rs[1], (InputStream) rs[2]);
if (rs[0] instanceof Response) return (Response) rs[0];
Response response = newChunkedResponse(Response.Status.lookup((Integer) rs[0]), (String) rs[1], (InputStream) rs[2]);
if (rs.length > 3 && rs[3] != null) for (Map.Entry<String, String> entry : ((Map<String, String>) rs[3]).entrySet()) response.addHeader(entry.getKey(), entry.getValue());
return response;
} catch (Exception e) {
return error(e.getMessage());
}

@ -17,7 +17,7 @@ public class Sniffer {
public static final Pattern CLICKER = Pattern.compile("\\[a=cr:(\\{.*?\\})\\/](.*?)\\[\\/a]");
public static final Pattern AI_PUSH = Pattern.compile("(http|https|rtmp|rtsp|smb|ftp|thunder|magnet|ed2k|mitv|tvbox-xg|jianpian|video):[^\\s]+", Pattern.MULTILINE);
public static final Pattern SNIFFER = Pattern.compile("http((?!http).){12,}?\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac)|http((?!http).)*?video/tos*|http((?!http).)*?obj/tos*");
public static final Pattern SNIFFER = Pattern.compile("http((?!http).){12,}?\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac|mpd)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|mkv|flv|mp3|m4a|aac|mpd)|http((?!http).)*?video/tos*|http((?!http).)*?obj/tos*");
public static final Pattern THUNDER = Pattern.compile("(magnet|thunder|ed2k):.*");
public static boolean isThunder(String url) {

@ -422,6 +422,14 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
mBinding.video.addOnLayoutChangeListener((view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> mPiP.update(getActivity(), view));
}
private void setVideoView(boolean isInPictureInPictureMode) {
if (isInPictureInPictureMode) {
mBinding.video.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
} else {
mBinding.video.setLayoutParams(mFrameParams);
}
}
private void setSubtitleView() {
setSubtitle(Setting.getSubtitle());
getExo().getSubtitleView().setStyle(ExoUtil.getCaptionStyle());
@ -657,7 +665,6 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
@Override
public void onItemClick(Result result) {
try {
result.setUrl(Source.get().fetch(result));
mPlayers.start(result, isUseParse(), getSite().isChangeable() ? getSite().getTimeout() : -1);
mBinding.danmaku.hide();
} catch (Exception e) {
@ -1716,17 +1723,16 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo
@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode);
if (!isFullscreen()) setVideoView(isInPictureInPictureMode);
if (isInPictureInPictureMode) {
PlaybackService.start(mPlayers);
mBinding.danmaku.hide();
enterFullscreen();
setSubtitle(10);
hideControl();
hideSheet();
} else {
showDanmu();
setForeground(true);
exitFullscreen();
PlaybackService.stop();
setSubtitle(Setting.getSubtitle());
if (isStop()) finish();

@ -1,5 +1,7 @@
package com.github.catvod.utils;
import android.text.TextUtils;
import androidx.collection.ArrayMap;
import com.google.gson.JsonElement;
@ -69,6 +71,10 @@ public class Json {
}
}
public static Map<String, String> toMap(String json) {
return TextUtils.isEmpty(json) ? null : toMap(parse(json));
}
public static Map<String, String> toMap(JsonElement element) {
Map<String, String> map = new HashMap<>();
JsonObject object = safeObject(element);

@ -25,25 +25,30 @@ import java.util.Enumeration;
public class Util {
public static final String CHROME = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
public static final int URL_SAFE = Base64.DEFAULT | Base64.URL_SAFE | Base64.NO_WRAP;
public static String base64(String s) {
return base64(s, Base64.URL_SAFE | Base64.NO_PADDING);
return base64(s.getBytes());
}
public static String base64(String s, int flags) {
return base64(s.getBytes(), flags);
public static String base64(byte[] bytes) {
return base64(bytes, Base64.DEFAULT | Base64.NO_WRAP);
}
public static String base64(byte[] bytes) {
return base64(bytes, Base64.DEFAULT);
public static String base64(String s, int flags) {
return base64(s.getBytes(), flags);
}
public static String base64(byte[] bytes, int flags) {
return Base64.encodeToString(bytes, flags);
}
public static String decode(String s) {
return new String(Base64.decode(s, Base64.URL_SAFE | Base64.NO_PADDING));
public static byte[] decode(String s) {
return decode(s, Base64.DEFAULT | Base64.NO_WRAP);
}
public static byte[] decode(String s, int flags) {
return Base64.decode(s, flags);
}
public static String basic(String userInfo) {

@ -2,24 +2,16 @@ package com.undcover.freedom.pyramid;
import android.content.Context;
import androidx.collection.ArrayMap;
import com.chaquo.python.PyObject;
import com.github.catvod.Proxy;
import com.github.catvod.net.OkHttp;
import com.github.catvod.utils.Json;
import com.google.common.net.HttpHeaders;
import com.github.catvod.utils.Util;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.ByteArrayInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import fi.iki.elonen.NanoHTTPD;
import okhttp3.Headers;
public class Spider extends com.github.catvod.crawler.Spider {
private final PyObject app;
@ -88,25 +80,26 @@ public class Spider extends com.github.catvod.crawler.Spider {
}
@Override
public Object[] proxyLocal(Map<String, String> params) throws Exception {
public Object[] proxyLocal(Map<String, String> params) {
List<PyObject> list = app.callAttr("localProxy", obj, gson.toJson(params)).asList();
JsonObject action = Json.parse(list.get(2).toString()).getAsJsonObject();
Map<String, String> headers = Json.toMap(action.get("header"));
String url = action.get("url").getAsString();
String content = list.get(3).toString();
String type = list.get(1).toString();
int code = list.get(0).toInt();
if (action.get("type").getAsString().equals("redirect")) {
NanoHTTPD.Response response = NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.lookup(code), NanoHTTPD.MIME_HTML, "");
for (Map.Entry<String, String> entry : headers.entrySet()) response.addHeader(entry.getKey(), entry.getValue());
response.addHeader(HttpHeaders.LOCATION, url);
return new Object[]{response};
} else if (action.get("type").getAsString().equals("stream")) {
ArrayMap<String, String> param = Json.toArrayMap(action.get("param"));
return new Object[]{code, type, OkHttp.newCall(url, Headers.of(headers), param).execute().body().byteStream()};
Map<PyObject, PyObject> headers = list.size() > 3 ? list.get(3).asMap() : null;
boolean base64 = list.size() > 4 && list.get(4).toInt() == 1;
PyObject r2 = list.get(2);
Object[] result = new Object[4];
result[0] = list.get(0).toInt();
result[1] = list.get(1).toString();
result[2] = r2 == null ? null : getStream(r2, base64);
result[3] = headers;
return result;
}
private ByteArrayInputStream getStream(PyObject o, boolean base64) {
if (o.type().toString().contains("bytes")) {
return new ByteArrayInputStream(o.toJava(byte[].class));
} else {
if (content.isEmpty()) content = OkHttp.newCall(url, Headers.of(headers)).execute().body().string();
return new Object[]{code, type, new ByteArrayInputStream(replaceProxy(content).getBytes())};
String content = replaceProxy(o.toString());
if (base64 && content.contains("base64,")) content = content.split("base64,")[1];
return new ByteArrayInputStream(base64 ? Util.decode(content) : content.getBytes());
}
}

@ -29,8 +29,9 @@ public class Info {
pos = rules[0];
}
try {
index = Integer.parseInt(pos.split("\\(")[1].split("\\)")[0]);
index = Integer.parseInt(pos.replace("eq(", "").replace(")", ""));
} catch (Exception ignored) {
index = 0;
}
}

@ -1,9 +1,9 @@
package com.fongmi.quickjs.bean;
import android.text.TextUtils;
import android.util.Base64;
import com.github.catvod.utils.Json;
import com.github.catvod.utils.Util;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName;
@ -57,7 +57,7 @@ public class Res {
}
public ByteArrayInputStream getStream() {
if (getBuffer() == 2) return new ByteArrayInputStream(Base64.decode(getContent(), Base64.DEFAULT));
if (getBuffer() == 2) return new ByteArrayInputStream(Util.decode(getContent()));
return new ByteArrayInputStream(getContent().getBytes());
}
}

@ -13,6 +13,7 @@ import com.fongmi.quickjs.utils.JSUtil;
import com.fongmi.quickjs.utils.Module;
import com.github.catvod.utils.Asset;
import com.github.catvod.utils.Json;
import com.github.catvod.utils.Util;
import com.whl.quickjs.wrapper.JSArray;
import com.whl.quickjs.wrapper.JSMethod;
import com.whl.quickjs.wrapper.JSObject;
@ -228,10 +229,13 @@ public class Spider extends com.github.catvod.crawler.Spider {
private Object[] proxy1(Map<String, String> params) throws Exception {
JSObject object = JSUtil.toObj(ctx, params);
JSONArray array = new JSONArray(((JSArray) jsObject.getJSFunction("proxy").call(object)).stringify());
Object[] result = new Object[3];
result[0] = array.opt(0);
result[1] = array.opt(1);
result[2] = getStream(array.opt(2));
Map<String, String> headers = array.length() > 3 ? Json.toMap(array.optString(3)) : null;
boolean base64 = array.length() > 4 && array.optInt(4) == 1;
Object[] result = new Object[4];
result[0] = array.optInt(0);
result[1] = array.optString(1);
result[2] = getStream(array.opt(2), base64);
result[3] = headers;
return result;
}
@ -249,15 +253,16 @@ public class Spider extends com.github.catvod.crawler.Spider {
return result;
}
private ByteArrayInputStream getStream(Object o) {
private ByteArrayInputStream getStream(Object o, boolean base64) {
if (o instanceof JSONArray) {
JSONArray a = (JSONArray) o;
byte[] bytes = new byte[a.length()];
for (int i = 0; i < a.length(); i++) bytes[i] = (byte) a.optInt(i);
return new ByteArrayInputStream(bytes);
} else {
return new ByteArrayInputStream(o.toString().getBytes());
String content = o.toString();
if (base64 && content.contains("base64,")) content = content.split("base64,")[1];
return new ByteArrayInputStream(base64 ? Util.decode(content) : content.getBytes());
}
}
}

@ -2,6 +2,7 @@ package com.fongmi.quickjs.method;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.media3.common.util.UriUtil;
import com.fongmi.quickjs.bean.Req;
import com.fongmi.quickjs.utils.Connect;
@ -121,31 +122,31 @@ public class Global {
@Keep
@JSMethod
public String pd(String html, String rule, String urlKey) {
return parser.pdfh(html, rule, urlKey);
return parser.parseDomForUrl(html, rule, urlKey);
}
@Keep
@JSMethod
public String pdfh(String html, String rule) {
return parser.pdfh(html, rule, "");
return parser.parseDomForUrl(html, rule, "");
}
@Keep
@JSMethod
public JSArray pdfa(String html, String rule) {
return JSUtil.toArray(ctx, parser.pdfa(html, rule));
return JSUtil.toArray(ctx, parser.parseDomForArray(html, rule));
}
@Keep
@JSMethod
public JSArray pdfl(String html, String rule, String texts, String urls, String urlKey) {
return JSUtil.toArray(ctx, parser.pdfl(html, rule, texts, urls, urlKey));
return JSUtil.toArray(ctx, parser.parseDomForList(html, rule, texts, urls, urlKey));
}
@Keep
@JSMethod
public String joinUrl(String parent, String child) {
return parser.joinUrl(parent, child);
return UriUtil.resolve(parent, child);
}
@Keep

@ -7,11 +7,10 @@ import com.github.catvod.utils.Util;
import com.google.common.net.HttpHeaders;
import com.whl.quickjs.wrapper.JSObject;
import com.whl.quickjs.wrapper.QuickJSContext;
import java.security.SecureRandom;
import java.security.SecureRandom;
import java.util.List;
import java.util.Map;
import java.util.Random;
import okhttp3.Call;
import okhttp3.FormBody;

@ -2,6 +2,8 @@ package com.fongmi.quickjs.utils;
import android.util.Base64;
import com.github.catvod.utils.Util;
import java.security.Key;
import java.security.KeyFactory;
import java.security.PublicKey;
@ -14,7 +16,6 @@ import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.github.catvod.utils.Util;
public class Crypto {
@ -37,7 +38,7 @@ public class Crypto {
SecretKeySpec keySpec = new SecretKeySpec(keyBuf, "AES");
if (iv == null) cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, keySpec);
else cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivBuf));
byte[] inBuf = inBase64 ? Base64.decode(input.replaceAll("_", "/").replaceAll("-", "+"), Base64.DEFAULT) : input.getBytes("UTF-8");
byte[] inBuf = inBase64 ? Base64.decode(input, Base64.DEFAULT | Base64.URL_SAFE) : input.getBytes("UTF-8");
return outBase64 ? Base64.encodeToString(cipher.doFinal(inBuf), Base64.NO_WRAP) : new String(cipher.doFinal(inBuf), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
@ -50,7 +51,7 @@ public class Crypto {
Key rsaKey = generateKey(pub, key);
int len = getModulusLength(rsaKey);
byte[] outBytes = new byte[0];
byte[] inBytes = inBase64 ? Base64.decode(input.replaceAll("_", "/").replaceAll("-", "+"), Base64.DEFAULT) : input.getBytes("UTF-8");
byte[] inBytes = inBase64 ? Base64.decode(input, Base64.DEFAULT | Base64.URL_SAFE) : input.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, rsaKey);
int blockLen = encrypt ? len / 8 - 11 : len / 8;

@ -20,9 +20,9 @@ import java.util.regex.Pattern;
public class Parser {
private final Pattern p1 = Pattern.compile("url\\((.*?)\\)", Pattern.MULTILINE | Pattern.DOTALL);
private final Pattern NO_ADD = Pattern.compile(":eq|:lt|:gt|:first|:last|^body$|^#");
private final Pattern JOIN_URL = Pattern.compile("(url|src|href|-original|-src|-play|-url|style)$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
private final Pattern URL = Pattern.compile("url\\((.*?)\\)", Pattern.MULTILINE | Pattern.DOTALL);
private final Pattern NO_ADD = Pattern.compile(":eq|:lt|:gt|:first|:last|:not|:even|:odd|:has|:contains|:matches|:empty|^body$|^#");
private final Pattern JOIN_URL = Pattern.compile("(url|src|href|-original|-src|-play|-url|style)$|^(data-|url-|src-)", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
private final Pattern SPEC_URL = Pattern.compile("^(ftp|magnet|thunder|ws):", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
private final Cache cache;
@ -47,7 +47,9 @@ public class Parser {
private String parseHikerToJq(String parse, boolean first) {
if (!parse.contains("&&")) {
String[] split = parse.split(" ");
return (NO_ADD.matcher(split[split.length - 1]).find() || !first) ? parse : parse + ":eq(0)";
Matcher m = NO_ADD.matcher(split[split.length - 1]);
if (!m.find() && first) parse = parse + ":eq(0)";
return parse;
}
String[] parses = parse.split("&&");
List<String> items = new ArrayList<>();
@ -63,59 +65,7 @@ public class Parser {
return TextUtils.join(" ", items);
}
private Elements parseOneRule(Document doc, String parse, Elements elements) {
Info info = getParseInfo(parse);
if (parse.contains(":eq")) {
if (elements.isEmpty()) {
if (info.index < 0) {
Elements r = doc.select(info.rule);
elements = r.eq(r.size() + info.index);
} else {
elements = doc.select(info.rule).eq(info.index);
}
} else {
if (info.index < 0) {
Elements r = elements.select(info.rule);
elements = r.eq(r.size() + info.index);
} else {
elements = elements.select(info.rule).eq(info.index);
}
}
} else {
if (elements.isEmpty()) {
elements = doc.select(parse);
} else {
elements = elements.select(parse);
}
}
if (info.excludes != null && !elements.isEmpty()) {
elements = elements.clone();
for (String exclude : info.excludes) {
elements.select(exclude).remove();
}
}
return elements;
}
public String joinUrl(String parent, String child) {
return UriUtil.resolve(parent, child);
}
public List<String> pdfa(String html, String rule) {
Document doc = cache.getPdfa(html);
rule = parseHikerToJq(rule, false);
String[] parses = rule.split(" ");
Elements elements = new Elements();
for (String parse : parses) {
elements = parseOneRule(doc, parse, elements);
if (elements.isEmpty()) return Collections.emptyList();
}
List<String> items = new ArrayList<>();
for (Element element : elements) items.add(element.outerHtml());
return items;
}
public String pdfh(String html, String rule, String addUrl) {
public String parseDomForUrl(String html, String rule, String addUrl) {
Document doc = cache.getPdfh(html);
if ("body&&Text".equals(rule) || "Text".equals(rule)) {
return doc.text();
@ -143,23 +93,69 @@ public class Parser {
} else if ("Html".equals(option)) {
return elements.html();
} else {
String result = elements.attr(option);
if (option.toLowerCase().contains("style") && result.contains("url(")) {
Matcher matcher = p1.matcher(result);
if (matcher.find()) result = matcher.group(1);
if (result != null) result = result.replaceAll("^['|\"](.*)['|\"]$", "$1");
}
if (!TextUtils.isEmpty(result) && !TextUtils.isEmpty(addUrl)) {
if (JOIN_URL.matcher(option).find() && !SPEC_URL.matcher(result).find()) {
if (result.contains("http")) result = result.substring(result.indexOf("http"));
else result = joinUrl(addUrl, result);
String result = "";
for (String s : option.split("[||]")) {
result = elements.attr(s);
if (s.toLowerCase().contains("style") && result.contains("url(")) {
Matcher m = URL.matcher(result);
if (m.find()) result = m.group(1);
result = result.replaceAll("^['|\"](.*)['|\"]$", "$1");
}
if (!result.isEmpty() && !addUrl.isEmpty()) {
if (JOIN_URL.matcher(s).find() && !SPEC_URL.matcher(result).find()) {
if (result.contains("http")) {
result = result.substring(result.indexOf("http"));
} else {
result = UriUtil.resolve(addUrl, result);
}
}
}
if (!result.isEmpty()) {
return result;
}
}
return result;
}
}
public List<String> pdfl(String html, String rule, String texts, String urls, String urlKey) {
public List<String> parseDomForArray(String html, String rule) {
Document doc = cache.getPdfa(html);
rule = parseHikerToJq(rule, false);
String[] parses = rule.split(" ");
Elements elements = new Elements();
for (String parse : parses) {
elements = parseOneRule(doc, parse, elements);
if (elements.isEmpty()) return new ArrayList<>();
}
List<String> items = new ArrayList<>();
for (Element element : elements) items.add(element.outerHtml());
return items;
}
private Elements parseOneRule(Document doc, String parse, Elements elements) {
Info info = getParseInfo(parse);
if (elements.isEmpty()) {
elements = doc.select(info.rule);
} else {
elements = elements.select(info.rule);
}
if (parse.contains(":eq")) {
if (info.index < 0) {
elements = elements.eq(elements.size() + info.index);
} else {
elements = elements.eq(info.index);
}
}
if (info.excludes != null && !elements.isEmpty()) {
elements = elements.clone();
for (int i = 0; i < info.excludes.size(); i++) {
elements.select(info.excludes.get(i)).remove();
}
}
return elements;
}
public List<String> parseDomForList(String html, String rule, String texts, String urls, String urlKey) {
String[] parses = parseHikerToJq(rule, false).split(" ");
Elements elements = new Elements();
for (String parse : parses) {
@ -169,7 +165,7 @@ public class Parser {
List<String> items = new ArrayList<>();
for (Element element : elements) {
html = element.outerHtml();
items.add(pdfh(html, texts, "").trim() + '$' + pdfh(html, urls, urlKey));
items.add(parseDomForUrl(html, texts, "").trim() + '$' + parseDomForUrl(html, urls, urlKey));
}
return items;
}

Loading…
Cancel
Save