|
|
@ -20,7 +20,7 @@ import javax.script.SimpleBindings |
|
|
|
@Keep |
|
|
|
@Keep |
|
|
|
class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
private var `object`: Any? = null |
|
|
|
private var `object`: Any? = null |
|
|
|
private var isJSON: Boolean? = false |
|
|
|
private var isJSON: Boolean = false |
|
|
|
private var baseUrl: String? = null |
|
|
|
private var baseUrl: String? = null |
|
|
|
|
|
|
|
|
|
|
|
private var analyzeByXPath: AnalyzeByXPath? = null |
|
|
|
private var analyzeByXPath: AnalyzeByXPath? = null |
|
|
@ -50,8 +50,8 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 获取XPath解析类 |
|
|
|
* 获取XPath解析类 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private fun getAnalyzeByXPath(o: Any?): AnalyzeByXPath { |
|
|
|
private fun getAnalyzeByXPath(o: Any): AnalyzeByXPath { |
|
|
|
return if (o != null) { |
|
|
|
return if (o != `object`) { |
|
|
|
AnalyzeByXPath().parse(o) |
|
|
|
AnalyzeByXPath().parse(o) |
|
|
|
} else getAnalyzeByXPath() |
|
|
|
} else getAnalyzeByXPath() |
|
|
|
} |
|
|
|
} |
|
|
@ -68,8 +68,8 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 获取JSOUP解析类 |
|
|
|
* 获取JSOUP解析类 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private fun getAnalyzeByJSoup(o: Any?): AnalyzeByJSoup { |
|
|
|
private fun getAnalyzeByJSoup(o: Any): AnalyzeByJSoup { |
|
|
|
return if (o != null) { |
|
|
|
return if (o != `object`) { |
|
|
|
AnalyzeByJSoup().parse(o) |
|
|
|
AnalyzeByJSoup().parse(o) |
|
|
|
} else getAnalyzeByJSoup() |
|
|
|
} else getAnalyzeByJSoup() |
|
|
|
} |
|
|
|
} |
|
|
@ -86,8 +86,8 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 获取JSON解析类 |
|
|
|
* 获取JSON解析类 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private fun getAnalyzeByJSonPath(o: Any?): AnalyzeByJSonPath { |
|
|
|
private fun getAnalyzeByJSonPath(o: Any): AnalyzeByJSonPath { |
|
|
|
return if (o != null) { |
|
|
|
return if (o != `object`) { |
|
|
|
AnalyzeByJSonPath().parse(o) |
|
|
|
AnalyzeByJSonPath().parse(o) |
|
|
|
} else getAnalyzeByJSonPath() |
|
|
|
} else getAnalyzeByJSonPath() |
|
|
|
} |
|
|
|
} |
|
|
@ -116,15 +116,32 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
@Throws(Exception::class) |
|
|
|
@Throws(Exception::class) |
|
|
|
fun getStringList(ruleList: List<SourceRule>, isUrl: Boolean): List<String>? { |
|
|
|
fun getStringList(ruleList: List<SourceRule>, isUrl: Boolean): List<String>? { |
|
|
|
var result: Any? = null |
|
|
|
var result: Any? = null |
|
|
|
for (rule in ruleList) { |
|
|
|
`object`?.let { o -> |
|
|
|
when (rule.mode) { |
|
|
|
if (ruleList.isNotEmpty()) { |
|
|
|
Mode.Js -> { |
|
|
|
if (ruleList.isNotEmpty()) result = o |
|
|
|
if (result == null) result = `object` |
|
|
|
for (rule in ruleList) { |
|
|
|
result = evalJS(rule.rule, result) |
|
|
|
result?.let { |
|
|
|
|
|
|
|
if (rule.rule.isNotEmpty()) { |
|
|
|
|
|
|
|
when (rule.mode) { |
|
|
|
|
|
|
|
Mode.Js -> result = evalJS(rule.rule, result) |
|
|
|
|
|
|
|
Mode.JSon -> result = |
|
|
|
|
|
|
|
getAnalyzeByJSonPath(it).getStringList(rule.rule) |
|
|
|
|
|
|
|
Mode.XPath -> result = |
|
|
|
|
|
|
|
getAnalyzeByXPath(it).getStringList(rule.rule) |
|
|
|
|
|
|
|
else -> result = getAnalyzeByJSoup(it).getStringList(rule.rule) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (rule.replaceRegex.isNotEmpty() && result is List<*>) { |
|
|
|
|
|
|
|
val newList = ArrayList<String>() |
|
|
|
|
|
|
|
for (item in result as List<*>) { |
|
|
|
|
|
|
|
newList.add(replaceRegex(item.toString(), rule)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
result = newList |
|
|
|
|
|
|
|
} else if (rule.replaceRegex.isNotEmpty()) { |
|
|
|
|
|
|
|
result = replaceRegex(result.toString(), rule) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Mode.JSon -> result = getAnalyzeByJSonPath(result).getStringList(rule.rule) |
|
|
|
|
|
|
|
Mode.XPath -> result = getAnalyzeByXPath(result).getStringList(rule.rule) |
|
|
|
|
|
|
|
else -> result = getAnalyzeByJSoup(result).getStringList(rule.rule) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (result == null) return ArrayList() |
|
|
|
if (result == null) return ArrayList() |
|
|
@ -167,19 +184,24 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
@JvmOverloads |
|
|
|
@JvmOverloads |
|
|
|
fun getString(ruleList: List<SourceRule>, isUrl: Boolean = false): String { |
|
|
|
fun getString(ruleList: List<SourceRule>, isUrl: Boolean = false): String { |
|
|
|
var result: Any? = null |
|
|
|
var result: Any? = null |
|
|
|
for (rule in ruleList) { |
|
|
|
`object`?.let { o -> |
|
|
|
if (rule.rule.isNotBlank()) { |
|
|
|
if (ruleList.isNotEmpty()) result = o |
|
|
|
when (rule.mode) { |
|
|
|
for (rule in ruleList) { |
|
|
|
Mode.Js -> { |
|
|
|
result?.let { |
|
|
|
if (result == null) result = `object` |
|
|
|
if (rule.rule.isNotBlank()) { |
|
|
|
result = evalJS(rule.rule, result) |
|
|
|
when (rule.mode) { |
|
|
|
|
|
|
|
Mode.Js -> result = evalJS(rule.rule, it) |
|
|
|
|
|
|
|
Mode.JSon -> result = getAnalyzeByJSonPath(it).getString(rule.rule) |
|
|
|
|
|
|
|
Mode.XPath -> result = getAnalyzeByXPath(it).getString(rule.rule) |
|
|
|
|
|
|
|
Mode.Default -> result = if (isUrl && !TextUtils.isEmpty(baseUrl)) { |
|
|
|
|
|
|
|
getAnalyzeByJSoup(it).getString0(rule.rule) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
getAnalyzeByJSoup(it).getString(rule.rule) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Mode.JSon -> result = getAnalyzeByJSonPath(result).getString(rule.rule) |
|
|
|
if (rule.replaceRegex.isNotEmpty()) { |
|
|
|
Mode.XPath -> result = getAnalyzeByXPath(result).getString(rule.rule) |
|
|
|
result = replaceRegex(result.toString(), rule) |
|
|
|
Mode.Default -> result = if (isUrl && !TextUtils.isEmpty(baseUrl)) { |
|
|
|
|
|
|
|
getAnalyzeByJSoup(result).getString0(rule.rule) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
getAnalyzeByJSoup(result).getString(rule.rule) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -201,15 +223,20 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
if (TextUtils.isEmpty(ruleStr)) return null |
|
|
|
if (TextUtils.isEmpty(ruleStr)) return null |
|
|
|
var result: Any? = null |
|
|
|
var result: Any? = null |
|
|
|
val ruleList = splitSourceRule(ruleStr) |
|
|
|
val ruleList = splitSourceRule(ruleStr) |
|
|
|
for (rule in ruleList) { |
|
|
|
`object`?.let { o -> |
|
|
|
when (rule.mode) { |
|
|
|
if (ruleList.isNotEmpty()) result = o |
|
|
|
Mode.Js -> { |
|
|
|
for (rule in ruleList) { |
|
|
|
if (result == null) result = `object` |
|
|
|
result?.let { |
|
|
|
result = evalJS(rule.rule, result) |
|
|
|
when (rule.mode) { |
|
|
|
|
|
|
|
Mode.Js -> result = evalJS(rule.rule, it) |
|
|
|
|
|
|
|
Mode.JSon -> result = getAnalyzeByJSonPath(it).getObject(rule.rule) |
|
|
|
|
|
|
|
Mode.XPath -> result = getAnalyzeByXPath(it).getElements(rule.rule) |
|
|
|
|
|
|
|
else -> result = getAnalyzeByJSoup(it).getElements(rule.rule) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (rule.replaceRegex.isNotEmpty()) { |
|
|
|
|
|
|
|
result = replaceRegex(result.toString(), rule) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Mode.JSon -> result = getAnalyzeByJSonPath(result).getObject(rule.rule) |
|
|
|
|
|
|
|
Mode.XPath -> result = getAnalyzeByXPath(result).getElements(rule.rule) |
|
|
|
|
|
|
|
else -> result = getAnalyzeByJSoup(result).getElements(rule.rule) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return result |
|
|
|
return result |
|
|
@ -223,15 +250,23 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
fun getElements(ruleStr: String): List<Any> { |
|
|
|
fun getElements(ruleStr: String): List<Any> { |
|
|
|
var result: Any? = null |
|
|
|
var result: Any? = null |
|
|
|
val ruleList = splitSourceRule(ruleStr) |
|
|
|
val ruleList = splitSourceRule(ruleStr) |
|
|
|
for (rule in ruleList) { |
|
|
|
`object`?.let { o -> |
|
|
|
when (rule.mode) { |
|
|
|
if (ruleList.isNotEmpty()) result = o |
|
|
|
Mode.Js -> { |
|
|
|
for (rule in ruleList) { |
|
|
|
if (result == null) result = `object` |
|
|
|
result?.let { |
|
|
|
result = evalJS(rule.rule, result) |
|
|
|
when (rule.mode) { |
|
|
|
|
|
|
|
Mode.Js -> { |
|
|
|
|
|
|
|
if (result == null) result = `object` |
|
|
|
|
|
|
|
result = evalJS(rule.rule, result) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Mode.JSon -> result = getAnalyzeByJSonPath(it).getList(rule.rule) |
|
|
|
|
|
|
|
Mode.XPath -> result = getAnalyzeByXPath(it).getElements(rule.rule) |
|
|
|
|
|
|
|
else -> result = getAnalyzeByJSoup(it).getElements(rule.rule) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (rule.replaceRegex.isNotEmpty()) { |
|
|
|
|
|
|
|
result = replaceRegex(result.toString(), rule) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
Mode.JSon -> result = getAnalyzeByJSonPath(result).getList(rule.rule) |
|
|
|
|
|
|
|
Mode.XPath -> result = getAnalyzeByXPath(result).getElements(rule.rule) |
|
|
|
|
|
|
|
else -> result = getAnalyzeByJSoup(result).getElements(rule.rule) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
result?.let { |
|
|
|
result?.let { |
|
|
@ -240,6 +275,7 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
return ArrayList() |
|
|
|
return ArrayList() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 保存变量 |
|
|
|
* 保存变量 |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -283,6 +319,27 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
return vRuleStr |
|
|
|
return vRuleStr |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* 正则替换 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
private fun replaceRegex(result: String, rule: SourceRule): String { |
|
|
|
|
|
|
|
var result = result |
|
|
|
|
|
|
|
if (rule.replaceRegex.isNotEmpty()) { |
|
|
|
|
|
|
|
result = if (rule.replaceFirst) { |
|
|
|
|
|
|
|
val pattern = Pattern.compile(rule.replaceRegex) |
|
|
|
|
|
|
|
val matcher = pattern.matcher(result) |
|
|
|
|
|
|
|
if (matcher.find()) { |
|
|
|
|
|
|
|
matcher.group(0).replaceFirst(rule.replaceRegex.toRegex(), rule.replacement) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
"" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
result.replace(rule.replaceRegex.toRegex(), rule.replacement) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return result |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 替换JS |
|
|
|
* 替换JS |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -329,7 +386,7 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
mode = Mode.JSon |
|
|
|
mode = Mode.JSon |
|
|
|
vRuleStr = vRuleStr.substring(6) |
|
|
|
vRuleStr = vRuleStr.substring(6) |
|
|
|
} |
|
|
|
} |
|
|
|
else -> mode = if (isJSON!!) { |
|
|
|
else -> mode = if (isJSON) { |
|
|
|
Mode.JSon |
|
|
|
Mode.JSon |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
Mode.Default |
|
|
|
Mode.Default |
|
|
@ -370,14 +427,17 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
inner class SourceRule internal constructor(ruleStr: String, mainMode: Mode) { |
|
|
|
inner class SourceRule internal constructor(ruleStr: String, mainMode: Mode) { |
|
|
|
internal var mode: Mode |
|
|
|
internal var mode: Mode |
|
|
|
internal var rule: String |
|
|
|
internal var rule: String |
|
|
|
|
|
|
|
internal var replaceRegex = "" |
|
|
|
|
|
|
|
internal var replacement = "" |
|
|
|
|
|
|
|
internal var replaceFirst = false |
|
|
|
|
|
|
|
|
|
|
|
init { |
|
|
|
init { |
|
|
|
this.mode = mainMode |
|
|
|
this.mode = mainMode |
|
|
|
if (mode == Mode.Js) { |
|
|
|
if (mode == Mode.Js) { |
|
|
|
if (ruleStr.startsWith("<js>")) { |
|
|
|
rule = if (ruleStr.startsWith("<js>")) { |
|
|
|
rule = ruleStr.substring(4, ruleStr.lastIndexOf("<")) |
|
|
|
ruleStr.substring(4, ruleStr.lastIndexOf("<")) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
rule = ruleStr.substring(4) |
|
|
|
ruleStr.substring(4) |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
when { |
|
|
|
when { |
|
|
@ -400,6 +460,20 @@ class AnalyzeRule(private var book: BaseBook? = null) { |
|
|
|
else -> rule = ruleStr |
|
|
|
else -> rule = ruleStr |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//分离正则表达式 |
|
|
|
|
|
|
|
val ruleStrS = |
|
|
|
|
|
|
|
rule.trim { it <= ' ' }.split("##".toRegex()).dropLastWhile { it.isEmpty() } |
|
|
|
|
|
|
|
.toTypedArray() |
|
|
|
|
|
|
|
rule = ruleStrS[0] |
|
|
|
|
|
|
|
if (ruleStrS.size > 1) { |
|
|
|
|
|
|
|
replaceRegex = ruleStrS[1] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (ruleStrS.size > 2) { |
|
|
|
|
|
|
|
replacement = ruleStrS[2] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (ruleStrS.size > 3) { |
|
|
|
|
|
|
|
replaceFirst = true |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|