用于APP内的网络导入,可以是单个规则,也可以是合并后的规则。欢迎成为协作者或者提交pr参与规则编写。
merge.sh是自动合并脚本,mainfest 是合并后的规则,链接:
https://raw.githubusercontent.com/mabDc/eso_source/master/manifest
网络问题可以使用jsdelivr cdn,即mainfest from jsdelivr,链接:
https://cdn.jsdelivr.net/gh/mabDc/eso_source/manifest
下面是规则编写说明。主要是三类:地址规则、取元素规则、取字符串规则。
请用源编辑界面
的地址模版
,
@js:
(() => {
var url = `/xx${keyword}xx${page}`;
var method = "get"; // or "post"
var body = {};
var headers = {};
// var encoding = "gbk";
return {url, method, body, headers};
})();
需要对搜索关键词进行中文编码则为
@js:
(() => {
var url = `/xx${keyword}xx${page}`;
var method = "get"; // or "post"
var body = {};
var headers = {};
var encoding = "gbk";
return {url, method, body, encoding, headers};
})();
响应解码由app内部自动处理,无需了解。
使用jsonpath
、xpath
、css
或者js
编写,其中前三种可以网页右键复制路径,app自动识别。
如$..item.*
或者//li
或者li
等,若用js
,最后应输出Array
对象
形如 rule##replaceRegex##replacement##replaceFirst
其中 rule
可以是 js
或 css
或 xpath
或 jsonpath
, 形式如下:
@js:js code
@json:$.name
或 $.name
(省略@json:
)
@css:.name@text
或 .name@text
(省略@css:
)
@xpath://*[class=name]/text()
或 //*[class=name]/text()
(省略@xpath:
)
:regex
建议省略@json:
,@css:
,@xpath:
,由app自动识别。
如果需要拼接则用aaa{{rulexxx}}bbb{{ruleyyy}}ccc
-
所有规则含
host
,除搜索和发现地址都含有result
,除地址都含有baseUrl
。 -
结果规则
会成为下一条地址规则
的result
,成为下一条除地址规则的lastResult
。地址规则的响应会成为其他规则的result
。 -
地址规则不用js时,使用
$加变量名
来动态替换实际内容,包含$keyword
,$page
,$result
,$host
等。地址规则使用js时请写变量名,不需要带$
。 -
可以用
http.get(url)
来获取请求。 -
规则搜索部分共用一个js上下文,目录部分也共用一个js上下文。同一个上下文的规则的全局变量可以直接相互获取。(如用于目录列表设置id,章节结果获取所设置的id)
-
JSONPath
- 形式
@JSon:$.jsonPath
或@JSon:jsonPath
或$.jsonPath
- 标准规范 goessner JSONPath - XPath for JSON
- 在线测试 Jayway JsonPath Evaluator
- 实现库 dart-json-path
- 示例 test
var jPathList = [ "\$.store.book[*].author", "\$..book[*].author", "\$..author", "\$..store.book", ".book[1]", ".book[6]", ".book[-1].author", ".book[0, 1, 2].title", ".book[0 , 1, 2].title", ".book[-1:3].title", ".book[-1:3:].price", ".book[:3:].author", ".book[3::-1].author", ".book[::-1].author", ".book[::].author", ".book[-1::].title", ".book[::].price", ".book['price', 'title']", ".book[*]['price', 'title']", ".book[*]['price']", ".book[(1 + 1 * 1)]['price']", "\$..book[?(@.price <= \$['expensive'] && @.price >= 6)]", "\$..book[?(!(@.price <= \$['expensive'] && @.price >= 6))]", ".book[*][(@.attr)]", "\$..book[?(@.author =~ /.*REES/)]", "\$..book[?(@.author =~ /.*REES/i)]", ".book[?(@.attr == 'price')]", ".book[?(@.attr empty)]", ".book[?(@.attr isNull)]", "\$..book[*]", "\$..book[*].title.substr(0,5)", "\$..book[*].title.length(0,5)", "\$..book.title.length()", "\$..book[*].title.length().sum()", "\$..book.price.sum()", "\$..book[1:2]", ".book[01,2,34,5]", ".book[:-1]", ".book[1:12]", ".book[\$1:12]", ".book[:]", ".book[,]", ".book['a','b', 'c'].value[0].link", "\$..book[?(@.price <= \$['expensive'])]", "\$..book[?(@.author =~ /.*REES/i)]", ".book[*].length()", "\$.store.book[*].author.substr(0,9)", ".book[*].length().substr().aaaa...", ".book[0].length()", "\$..book[?(@.price <= \$['expensive'] && @.price >= 6)]", ".book[?(((@.price >= 16 || @.price <= \$['expensive'] && @.price >= 6)))]", ".book[((@.price || @.price <= \$['expensive']) && (@.price >= 6))]", ".book[((@.price || @.price <= \$['expensive']) && (@.price >= 3 + 6))]", ];
- 形式
-
XPath
-
形式
@XPath:xpath
或//xpath
-
标准规范 W3C XPATH 1.0
-
实现库 xpath_parse
-
Name Expression immediate parent / parent // attribute [@key=value] nth child tag[n] attribute /@key wildcard in tagname /* function function() These XPath syntax are extended only in Xsoup (for convenience in extracting HTML, refer to Jsoup CSS Selector):
Name Expression Support attribute value not equals [@key!=value] yes attribute value start with [@key~=value] yes attribute value end with [@key$=value] yes attribute value contains [@key*=value] yes attribute value match regex [@key~=value] yes -
示例 xpath_test
import 'package:flutter_test/flutter_test.dart'; import 'package:xpath_parse/xpath_selector.dart'; final String html = ''' <html> <div><a href='https://github.com'>github.com</a></div> <div class="head">head</div> <table><tr><td>1</td><td>2</td><td>3</td><td>4</td></tr></table> <div class="end">end</div> </html> '''; Future<void> main() async { test('adds one to input values', () async { var xpath = XPath.source(html); print(xpath.query("//div/a/text()").list()); print(xpath.query("//div/a/@href").get()); print(xpath.query("//div[@class]/text()").list()); print(xpath.query("//div[@class='head']/text()").get()); print(xpath.query("//div[@class^='he']/text()").get()); print(xpath.query("//div[@class\$='nd']/text()").get()); print(xpath.query("//div[@class*='ea']/text()").get()); print(xpath.query("//table//td[1]/text()").get()); print(xpath.query("//table//td[last()]/text()").get()); print(xpath.query("//table//td[position()<3]/text()").list()); print(xpath.query("//table//td[position()>2]/text()").list()); }); }
-
-
CSS
- 形式
@css:css
或css
- 实现库 csslib
- 在线测试 Try jsoup online: Java HTML parser and CSS debugger
- 形式
-
正则
- 形式
##replaceRegex##replacement##replaceFirst
- 教程 veedrin/horseshoe 2018-10 | Regex专题
- 形式
-
自定义三种连接符:
&&, ||, %%
-
不支持动态内容,所有的规则解析以静态加载的内容为准。
-
动态与静态的问题 多多猫插件开发指南 解释的很清楚
2.5.2 插件的调试
...
注意: Ctrl+u和F12开发者工具Elements面板中显示源代码的的区别是前者显示的是不加载js的html源代码,后者显示的是加载内部外部js后的html代码。sited引擎读取前者代码,所以有时候在浏览器开发者工具(Console面板)能找出数据,在app里却报错,就是因为Ctrl+u源代码中没有相应数据。 -
规则形式为
rule##replaceRegex##replacement##replaceFirst
数据文件
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
操作符
XPath | JSONPath | Description |
---|---|---|
/ |
$ |
the root object/element |
. |
@ |
the current object/element |
/ |
. or [] |
child operator |
.. |
n/a |
parent operator |
// |
.. |
recursive descent. JSONPath borrows this syntax from E4X. |
* |
* |
wildcard. All objects/elements regardless their names. |
@ |
n/a |
attribute access. JSON structures don't have attributes. |
[] |
[] |
subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator. |
| | [,] |
Union operator in XPath results in a combination of node sets. JSONPath allows alternate names or array indices as a set. |
n/a |
[start:end:step] |
array slice operator borrowed from ES4. |
[] |
?() |
applies a filter (script) expression. |
n/a |
() |
script expression, using the underlying script engine. |
() |
n/a |
grouping in Xpath |
示例对比
XPath | JSONPath | Result |
---|---|---|
/store/book/author |
$.store.book[*].author |
the authors of all books in the store |
//author |
$..author |
all authors |
/store/* |
$.store.* |
all things in store, which are some books and a red bicycle. |
/store//price |
$.store..price |
the price of everything in the store. |
//book[3] |
$..book[2] |
the third book |
//book[last()] |
$..book[(@.length-1)] $..book[-1:] |
the last book in order. |
//book[position()<3] |
$..book[0,1] $..book[:2] |
the first two books |
//book[isbn] |
$..book[?(@.isbn)] |
filter all books with isbn number |
//book[price<10] |
$..book[?(@.price<10)] |
filter all books cheapier than 10 |
//* |
$..* |
all Elements in XML document. All members of JSON structure. |