Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[自动无缝翻页] 自定义翻页规则 示例说明 #176

Open
XIU2 opened this issue Feb 22, 2022 · 4 comments
Open

[自动无缝翻页] 自定义翻页规则 示例说明 #176

XIU2 opened this issue Feb 22, 2022 · 4 comments
Labels
技巧教程 脚本技巧 或 相关教程

Comments

@XIU2
Copy link
Owner

XIU2 commented Feb 22, 2022

该 Issues 下只讨论 自定义翻页规则,其他请求/反馈请新开 Issues,否则将会删除。

自动无缝翻页 脚本从 v4.8.8 版本开始,支持了自定义翻页规则。

不过当初仅为自用,压根没有考虑过这需求,我只能简单实现自定义翻页规则,因此只适用于简单的静态加载内容网站,当然这类网站占大多数,我写的上千规则中大部分都是这类网站,因此一般是够用了~

# 自写规则 前提条件

  1. 了解 JSON 基本格式 ( 主要是末尾逗号、转义、双引号 )
  2. 了解 CSS 或 XPath 选择器用法 ( 推荐优先使用简单点的 CSS 选择器,对于复杂或需要选择文字的才建议使用 XPath )
  3. 可能需要会一点 JavaScript 语言 / 正则表达式 ( 针对一些较为复杂的网页,主要还是用于 URL 匹配,比如要匹配多个页面什么的 )
    (现在可以直接使用 "url": "return fun.isPager()", 这个新的内置函数通过匹配元素来匹配规则,适用于大部分网站,算是降低了一些编写规则门槛)

简单的来说,这就是提供给 懂一些技术 的用户自给自足制作规则用的~

大多数网站的规则一般都只需要这样(下方示例规则中,urlreplaceEscrollD 均可按需省略):

// "aaa"       是规则名,唯一,因为 自定义翻页规则 优先级最高,所以会覆盖同名的 外置翻页规则

// "host"      是域名,支持正则表达式,也可以像这样 "host": ["bbb1.com", "bbb2.com"], 写多个域名或正则表达式,如果省略,则默认匹配所有域名(会对所有域名匹配 url 规则判断,可以当成一个简单的外置/自定义通用规则的方案)

// "url"       是用来控制哪些网站中页面适用该规则,省略后代表该规则应用于全站(如果不知道写什么,那么就写 return fun.isPager() 这样脚本会默认自动匹配当前网站下存在 nextL 及 pageE 元素的网页,大部分网站是没问题的,如果改为匹配 replaceE 或者其他组合,那么请去下面的 Github Issues 里的 内置函数 中查看具体使用方法)

// "nextL"     是用来指定含有下一页地址的元素选择器(CSS 或 XPath 都行,一般都是 <a> 元素)

// "pageE"     是指定要从下一页获取的元素选择器(也就是网页主体内容),并将其插入当前网页中同样元素的末尾

// "replaceE"  用于将当前网页中的页码元素替换为下一页的页码元素选择器(这样才能无限翻页下去),省略后将会自动判断是替换 nextL 元素自身还是 nextL 元素的父元素(当 nextL 元素后面或前面有其自身 <a> 的相邻兄弟元素时脚本会替换其父元素,反之没有相邻兄弟元素则替换其自身,仅限模式1/3/6,且 "js;" 开头的 nextL 规则除外),值为空 "" 时则完全不替换

// "scrollD"   是用来指定触发翻页的滚动条与底部之间的距离,当滚动条底部距离网页底部之间的距离等于或小于该值时,将触发翻页,因此值越大就越早触发翻页,访问速度慢的网站需要调大,可省略(记得移除上一行末尾逗号),省略后默认 2000


"aaa": {
    "host": "aaa.com",
    "url": "return fun.isPager()",
    "pager": {
        "nextL": "xxx",
        "pageE": "xxx",
        "replaceE": "xxx",
        "scrollD": 2000
    }
}


// 另外还有个大家可能会用的上的:
// "inherits"  规则是继承标识,仅用于自定义规则,用于增删改某个外置规则的部分规则时(比如只是修改域名),可使用该标识来省略不需要修改的规则,只写有变化的规则
// 假如上面那个 "aaa" 翻页规则是脚本的外置翻页规则之一,那么就可以像下面这个 "aaa" 规则一样写一个同名规则(放到自定义翻页规则中),规则内只需要有要修改的 host 内容,以及 inherits 标识,这样脚本就会将这个自定义翻页规则中的 host 覆盖掉外置翻页规则中的 host,而该翻页规则内的其他规则内容则不变。
// 即更灵活了,无需每次为了修改部分规则而去复制全部规则了,也不用担心我后续更新这个外置规则后,你还需要再次复制一遍来修改。。。

"aaa": {
    "host": "ccc.com",
    "inherits": true
}

大家也可以在下面 提出改进建议分享规则~


# 规则总览(只列出了目前 自定义翻页规则 能用的)

「 点击展开查看 」
    inherits:    继承标识,仅用于自定义规则,用于增删改某个外置规则的部分规则时,可使用该标识来省略不需要修改的规则,只写有变化的规则

    host:       先匹配域名,可以是文本,也可以是正则表达式,也可以是数组(数组中也可以文本和正则表达式混合使用),如果省略,则默认匹配所有域名(会对所有域名匹配 url 规则判断,可以当成一个简单的外置/自定义通用规则的方案)
    url:         匹配到域名后,再来匹配 URL,也可以用来执行一些 JS 代码
    urlC:      对于使用 pjax 技术的网站,需要监听 URL 变化来重新判断翻页规则(需要放在 url: 中,自定义规则的话需要使用 fun.isUrlC())

    noReferer:   获取下一页内容时,不携带 Referer(部分网站携带与不携带可能不一样)
    hiddenPN:    不显示脚本左下角的页码
    history:     添加历史记录 并 修改当前 URL(默认开启,对于不支持的网站要设置为 false)
    thread:      对于社区类网站,要在 帖子内 的规则中加入这个,用于脚本的 [帖子内自动翻页] 功能(即用户可以选择开启/关闭所有社区类网站帖子内的自动翻页)
    style:       要插入网页的 CSS Style 样式,当只需要单纯屏蔽部分网页元素时,可以只写 CSS 选择器省略掉 {display: none !important;}
    retry:       允许获取失败后重试
    blank:       强制新标签页打开链接
       1 = 网页 <head> 添加 <base target="_blank"> 来让所有链接默认新标签页打开(对已单独指定 target 或已监听点击事件的元素无效)
       2 = 对 <body> 委托点击事件
       3 = 对 pageE 的父元素 委托点击事件(也会阻止冒泡,但因为距离 <a> 标签较远,因此只有在委托点击事件的元素是 pageE 的父元素的父元素时,才有意义)
       4 = 对 pageE 的子元素 <a> 标签 添加 target="_blank"
       5 = 对 pageE 的子元素 <a> 标签 清理事件后 再添加 target="_blank"
       6 = 对 pageE 的子元素 <a> 标签 清理事件后 再添加 target="_blank" 并阻止冒泡(避免父元素事件委托捕获该元素的点击事件)

pager: {
    type:     翻页模式
       1 = 由脚本实现自动无缝翻页,可省略(适用于:静态加载内容网站,常规模式)

       2 = 只需要点击下一页按钮(适用于:网站自带了 自动无缝翻页 功能)
           nextText:    按钮文本,当按钮文本 = 该文本时,才会点击按钮加载下一页(避免一瞬间加载太多次下一页,下同)
           nextTextOf:  按钮文本的一部分,当按钮文本包含该文本时,才会点击按钮加载下一页
           nextHTML:    按钮内元素,当按钮内元素 = 该元素内容时,才会点击按钮加载下一页
           interval:    点击间隔时间,对于没有按钮文字变化的按钮,可以手动指定间隔时间(省略后默认 500ms,当指定上面三个时,会忽略 interval)
           isHidden:    只有下一页按钮可见时(没有被隐藏),才会点击

       3 = 依靠 [基准元素] 与 [浏览器可视区域底部] 之间的距离缩小来触发翻页(适用于:主体元素下方内容太多 且 高度不固定时)
           scrollE:     作为基准线的元素(一般为底部页码元素),和 replaceE 一样的话可以省略
           scrollD:     当 [基准元素] 与 [可视区域底部] 之间的距离 等于或小于该值时,将触发翻页,省略后默认 2000

       4 = 动态加载类网站(适用于:简单的动态加载内容网站)
           insertE:     用来插入元素的函数

       5 = 插入 iframe 方式来加载下一页,无限套娃(适用于:部分动态加载内容的网站,需要允许 iframe 且支持通过 GET/POST 直接打开下一页)
           style:       加载 iframe 前要插入的 CSS Style 样式(比如为了悬浮的样式与下一页的重叠,隐藏网页底部间距提高阅读连续性)
           iframe:      这个必须加到 pager{} 外面(这样才会在该域名的 iframe 框架下运行脚本)

       6 = 通过 iframe 获取下一页动态加载内容插入本页,只有一个娃(适用于:部分动态加载内容的网站,与上面不同的是,该模式适合简单的网页,没有复杂事件什么的)
           loadTime:    预留的网页加载时间,确保网页内容加载完成(省略后默认为 300ms)

    nextL:    下一页链接所在元素
    pageE:    要从下一页获取的元素
    insertP:  下一页元素插入本页的位置(数组第一个是基准元素,第二个是基准元素的前后具体位置)
       1 = 插入基准元素自身的前面
       2 = 插入基准元素内,第一个子元素前面
       3 = 插入基准元素内,最后一个子元素后面
       4 = 插入基准元素自身的后面
       5 = 插入 pageE 列表最后一个元素的后面(该 insertP 可以直接省略不写,等同于 ['pageE', 5] )
       6 = 插入该元素自身内部末尾(针对小说网站等文本类的),附带参数 insertP6Br: true, 用来中间插入换行
    // 小技巧:当基准元素是下一页主体元素的父元素时(或者说要将下一页元素插入到本页同元素最后一个后面时)是可以省略不写 insertP
         例如:当 pageE: 'css;ul>li' 且 insertP: ['css;ul', 3] 时,实际等同于 ['css;ul>li', 5]
               当 pageE: 'css;.item' 且 insertP: ['css;.item', 4] 时,实际等同于 ['css;.item', 5]
               当 pageE: 'css;.item' 且 insertP: ['css;.page', 1] 时,实际等同于 ['css;.item', 5]
         注意:如 pageE 中选择了多类元素,则不能省略 insertP(比如包含 `,` 与 `|` 符号),除非另外的选择器是 <script> <style> <link> 标签

    replaceE: 要替换为下一页内容的元素(比如页码),省略后将会自动判断是替换 nextL 元素还是 nextL 的父元素(当 nextL 元素后面或前面有 <a> 的相邻兄弟元素时替换其父元素,反之替换其自身,仅限模式1/3/6,且 js 代码除外),值为空 "" 时则完全不替换
    scrollD:当 [滚动条] 与 [网页底部] 之间的距离 等于或小于该值时,将触发翻页,因此值越大就越早触发翻页,访问速度慢的网站需要调大,可省略(记得移除上一行末尾逗号),省略后默认 2000

    scriptT:  单独插入 <script> 标签
       0 = 下一页的所有 <script> 标签
       1 = 下一页的所有 <script> 标签(不包括 src 链接)
       2 = 下一页主体元素 (pageE) 的同级 <script> 标签
       3 = 下一页主体元素 (pageE) 的子元素 <script> 标签

    interval:   翻页后间隔时间(省略后默认 500ms)
    forceHTTPS: 下一页链接强制 HTTPS
},
function: {
       bF = 插入前执行函数
       bFp = 参数
       aF = 插入后执行函数
       aFp = 参数
}

## 内置函数

为了方便,规则中执行 JS 代码时可以使用脚本内置函数:

「 点击展开查看 」
// 返回当前网页的 URL 路径,等同于 location.pathname
fun.lp()


// 该 indexOF 默认不区分大小写,不过正则表达式除外,需要自己加上 /i 修饰符
// 当前网页的 URL 路径中如果包含指定文本则返回 true,等同于 location.pathname.indexOf('xxx') > -1
fun.indexOF('xxx')
// 也支持正则,对于一些需要复合/多个条件判断时才有必要用这个,否则直接正则写到 "url": "/xxx/" 更好
fun.indexOF(/xxx/)
// 加上 's' 参数,则匹配范围改为 URL 末尾的参数,等同于 location.location.search.indexOf('xxx') > -1
fun.indexOF('xxx', 's')


// 根据 UA 和屏幕大小判断是否为手机浏览器,是手机就返回 true,适用于手机版、电脑版网页域名一致但规则不一致的
fun.isMobile()

// 判断网站标题是否包含指定文字
fun.isTitle(文字)

// 判断规则中的 nextL、pageE、insertP、replaceE 元素是否存在于当前网页
// 参数为字符串,省略后会根据当前规则是否含有 nextL 和 pageE 规则(且不是 `js;`),来自动选择默认为 `n` 或 `p` 或 `n,p`(当然大部分情况下都是这个,也就是判断 nextL 和 pageE 元素是否存在),同理,insertP 和 replaceE 对应的就是首字母 i 和 r,如果只写 'n' 则代表只判断 nextL,可以自由组合,只需要用英文逗号分割即可(不能包含空格)
// 一般使用只需要这样: "url": "return fun.isPager()", 即可
fun.isPager()


// 返回所有指定元素,支持 CSS、Xpath 选择器
fun.getAll('元素选择器', 目标节点(省略则为 document))
// 返回一个指定元素,支持 CSS、Xpath 选择器
fun.getOne()
// 返回所有指定元素,支持 Xpath 选择器
fun.getAllXpath()
// 返回一个指定元素,支持 Xpath 选择器
fun.getXpath()
// 返回所有指定元素,支持 CSS 选择器
fun.getAllCSS()
// 返回一个指定元素,支持 CSS 选择器
fun.getCSS()


// 以下这几个请参考项目中 rules.json 里的各个规则用法(下面这几个如果获取成功就会返回 URL,失败则返回 '' 空)
// 通用型获取下一页地址(从 元素 中获取页码)
fun.getNextE(css/xpath)
// 通用型获取下一页地址(从 元素 中获取页码,URL 替换 page= 参数)
fun.getNextEP(css/xpath, 页码参数名, 正则匹配页码参数的值)
// 通用型获取下一页地址(从 元素 中获取页码,URL 替换 pathname 路径)
fun.getNextEPN(css/xpath, 正则匹配 URL 中的页码, 路径前面, 路径后面)
// 通用型获取下一页地址(从 URL 中获取页码,并页码+1,URL 替换 pathname 路径,后三个参数可以省略)
// 如果第一个参数正则捕获到分组(也就是正则表达式中用英文括号括起来的,如 /page\/(\d+)/ 这样的正则就会捕获到 /page/2/ 里面的页码 2),那么就改为使用第一个捕获分组(也就是正则中常说的 $1)作为当前页码数字
fun.getNextUPN(正则匹配 URL 中的页码数字, 正则匹配要替换的页码, 路径前面, 路径后面, 初始页码数字(默认 2), 最大页码数字)
// 通用型获取下一页地址(从 URL 中获取页码,并页码+1,URL 替换 page= 参数,后三个参数可以省略)
fun.getNextUP(页码参数名, 正则匹配页码参数的值, 完整路径, 初始页码数字(默认 2), 最大页码数字)
// 通用型获取下一页地址(从 form input 中获取,返回 GET URL)
fun.getNextF(css/xpath)


// 插入 <Style> 自定义 CSS 样式
// 当只需要单纯屏蔽部分网页元素时,可以参数只写 CSS 选择器省略掉 {display: none !important;} (脚本会自动加上)
fun.insStyle(style)


// 清理目标元素上绑定的事件
// css 为元素选择器(也支持 Xpath)
// delay 为延迟时间,确保其放在 url 规则中执行时网页已经加载完成
// mode 为 0 时清理全部,为 1 时额外清理 onclick 属性,为 2 时添加空点击事件并阻止冒泡
fun.cleanuEvent(css, delay, mode)


// 插入前函数(将网页中的 图片懒加载 立即加载)
fun.src_bF(pageE, [0, '图片元素选择器', '属性名'])
// 这里的 0 代表图片是 src 属性(1 代表是 background-image: url() 背景样式类的图片)
// 如果你要选择的图片元素是 img[data-original] 或 img[data-src] 且加载模式为 0,那么后面这个数组可以省略为: fun.src_bF(pageE),即默认值等同于以下两者:
// fun.src_bF(pageE, [0, 'img[data-original]', 'data-original'])
// fun.src_bF(pageE, [0, 'img[data-src]', 'data-src'])

// 插入前函数(正则过滤,主要针对小说站这种)
fun.xs_bF(pageE, [/正则/, '替换为该内容,可空'])


// 用于在特殊规则情况下手动递增左下角的页码数字,参数就是要增加的数字,省略后默认为 1(也就是 +1)
fun.pageNumIncrement(数字)

## URL 匹配 "url": "xxx",

相比于其他同类脚本,我当初为了方便及避免正则折磨,将 域名 和 URL 分开匹配了,毕竟大量复杂的正则匹配会很费时间,分开后就先匹配域名,再去匹配 URL,间接也提高了效率(而且域名大都是文本,非常快 ~

匹配 URL 路径示例(正则表达式匹配范围仅是域名后面的 路径 及 ? 参数):

注意:URL 匹配是从前往后按顺序匹配的,因此同一个网站有多个不同页面规则时,如果 URL 匹配规则有些许重复的地方就需要控制一下顺序。另外,对于正则表达式均不区分大小写(即脚本默认加上 /i 修饰符)。

「 点击展开查看 」
## URL 路径示例:/ (首页)

# 正则表达式
"url": "/^\\/$/",
# 脚本内置函数
"url": "return (fun.lp() == '/')",
# 上面这个等同于下面这个,只是有点长不好记写着不方便,所以我才搞了个内置函数
"url": "return (location.pathname == '/')",

## URL 路径示例:非 / (即不是首页)

"url": "/^\\/.+/",
"url": "return (fun.lp() != '/')",
"url": "return (location.pathname != '/')",

## URL 路径示例:/post (即位于根路径)

"url": "/^\\/post/",
"url": "return (fun.lp() == '/post')",
"url": "return (location.pathname == '/post')",

## URL 路径示例:/aaa/post/111 (即位于路径中间)

"url": "/\\/post\\//",
"url": "return fun.indexOF('/post/')",
"url": "return location.pathname.indexOf('/post')",

## URL 路径示例:/aaa?pid=233 (即只匹配路径参数)

"url": "/pid=/",
"url": "return fun.indexOF('pid=', 's')",
"url": "return location.search.indexOf('pid=')",

## URL 路径示例:/aaa/post/111?pid=233 (即需要同时匹配 /post/ 和 pid=)
## 中间的连接符 && 等于 且 的意思,即需要两边都满足条件才会返回 true

"url": "return (fun.indexOF('/post/') && fun.indexOF('pid=', 's'))",
"url": "return (location.pathname.indexOf('/post') && location.search.indexOf('pid='))",

## URL 路径示例:/aaa/post/111 或 /search (即只需要匹配 /post/ 或 /search)
## 中间的连接符 || 等于 或 的意思,继续只需要任意一个满足条件就会返回 true

"url": "return (fun.indexOF('/post/') || fun.indexOF('/search'))",
"url": "return (location.pathname.indexOf('/post') || location.pathname.indexOf('/search'))",

## 一些情况下,难以依靠 URL 特征来匹配页面,那么还能用网页元素
## 比如目标网页中含有一个 `#pager` 元素(常用页码元素),那么就可以这样写:

"url": "return fun.getCSS('#pager')",

## replaceE 规则省略后的自动判断方式说明

为了省力方便,6.4.25 版本后,脚本支持省略 replaceE 规则,该规则一般是用来将本页的页码元素替换为下一页的页码元素,以确保 nextL 选择的元素始终是下一页的 URL 地址。

但根据我写了那么多规则的经验来看,大部分情况下 replaceE 都是 nextL 的父元素,除此之外直接替换 nextL 元素也能用(无非就是页码数字不会变,看起来可能有点别扭),因此直接把 replaceE 设置为 nextL 的父元素就够用了,但为了避免误伤、不确定性,我还是做了一些条件判断,不满足条件的则只会单纯的替换 nextL 元素。

「 点击展开查看 」

假设 nextL 规则为 a.next ,而网页中页码元素示例如下:

那么当 a.next 元素后面或前面 的相邻兄弟元素时,则 replaceE 为其父元素(即替换 div.page 元素)

<div class="page">
<a class="next" href="2.html"></a>
<a href="3.html"></a>
</div>
<div class="page">
<a href="1.html"></a>
<a class="next" href="2.html"></a>
</div>

而如果当 a.next 元素后面或前面 没有 的相邻兄弟元素时,则 replaceE 为其自身(即替换 a.next 元素)

<div>
<a class="next" href="2.html"></a>
</div>
<div>
<a href="3.html"></a>
</div>

当然,如果找不到 nextL 元素,或像这样 "replaceE": "" 为空,脚本就不会替换。


# 规则示例

大家也可以参考我写的近千个翻页规则:https://github.com/XIU2/UserScript/blob/master/other/Autopage/rules.json

注意:因为自定义翻页规则的局限性以及格式的差别,因此不能完全照搬脚本内置规则!
以下是我从内置翻页规则中找的几个规则,并改成了自定义翻页规则的格式,大家可以自行对比理解差别。

注意:以下为了方便对每一条规则进行解释,我直接在规则旁边写了注释,但 JSON 是不存在注释的,因此添加到脚本中时记得移除所有注释内容,否则会报错!

当只有一个规则时,是这样的(示例):

{
    "aaa": {
        "host": "xxxx",
        "xxxx": "..."
    }
}

当有多个规则时,要这样连接到一起的(最后一个 } 不加逗号):

{
    "aaa": {
        "host": "xxxx",
        "xxxx": "..."
    },
    "bbb": {
        "host": "xxxx",
        "xxxx": "..."
    }
}

因此在写入自定义翻页规则的时候,记得包裹着所有规则的 { } 大括号,以及最容易犯错的逗号问题(最后一个 } 不能有逗号)。


## 同一个网站 不同页面 适用不同翻页规则

「 点击展开查看 」

不同翻页规则的 host 是可以一样的,但是规则名不能一样,通过不同的 url 规则来进行匹配。
比如下面这个就是先从 URL 匹配 /a 如果没找到,那么再去匹配 /b,如果还没找到那么就直接应用 aaa_3 规则(因为这个没有 url 规则,所以就变成兜底的规则了)。

{
    "aaa": {
        "host": "a.com",
        "url": "/^\\/a/",
        "xxxx": "xxxx"
    },
    "aaa_2": {
        "host": "a.com",
        "url": "return (fun.lp() == '/b')",
        "xxxx": "xxxx"
    },
    "aaa_3": {
        "host": "a.com",
        "xxxx": "xxxx"
    }
}

## 继承标识 inherits 使用说明(v6.4.6 及之后版本)

「 点击展开查看 」

假设外置翻页规则中,有个 aaa 规则,你想要修改它的 host 域名,在以前你需要将其完全复制出来,修改后放到自定义翻页规则中,这样脚本合并规则时,会将其完全覆盖外置规则(即使用你修改后的自定义规则)。

// 某个外置规则
{
    "aaa": {
        "host": "a.com",
        "url": "/^\\/a/",
        "xxxx": "xxxx"
    }
}

但在脚本 v6.4.6 版本后,新加入了 inherits 继承标识,你可以省略不需要修改的那些规则,只写有变化的规则,例如下面这样,因为只需要修改 host 规则,所以只需要这一个规则(当然还需要加上 inherits 来提示脚本),其余的 url 等规则都省略了。

// 你加的自定义规则
{
    "aaa": {
        "host": ["a.com","b.com"],
        "inherits": true
    }
}

脚本发现同名后,会判断是否有 inherits 标识,如果有,就会这两个同名规则合并(也可以说是自定义规则继承了外置规则),最后得到的规则就是这样:

// 最后合并后的规则(在 自定义翻页规则 界面,展开所有规则就可以看到这个)
{
    "aaa": {
        "host": ["a.com","b.com"],
        "url": "/^\\/a/",
        "xxxx": "xxxx",
        "inherits": true
    }
}

不过该功能也是有局限性的,比如只能新增、修改一些规则,无法移除某条规则,因此考虑到这点,特地给 "function": {} 这种带括号内嵌的子规则搞了个例外,自定义规则中的 "function": {} 会完整覆盖外置规则,而非合并,这样如果不需要 function 规则时可以在自定义规则中加个空的 "function": {} 即可(括号内是空的)。


以下这些详细解释的示例可能会失效,因此你也可以找个脚本支持的网站,然后去 自定义翻页规则 界面查看所有翻页规则来找到该网站相对应的翻页规则,来互相印证学习。


## 翻页模式 1

这个模式是最常见的,即网站是纯静态加载内容的。

// 规则名(唯一,不能重复,可以是中文、字母、数字什么的)
"百度搜索": {
// 单个域名
// 支持正则,格式示例如:"host": "/\\.baidu\\.com/", 也支持多个正则组成的数组
    "host": "www.baidu.com",
// 当 URL 路径 = /s 时才应用该规则
// 不过为了方便自定义规则,所以这里也给改成了支持正则表达式,像这样:"url": "/^\/s$/",
    "url": "return (fun.lp() == '/s')",
// 应用规则时,要插入的自定义 CSS 样式(比如用来屏蔽广告什么的,可以直接省略 {display: none !important;})
    "style": "xxxx {xxx: xxx}",
    "pager": {
// 模式 1 的话,可以省略 "type": 1, 这条规则
// 这个是 Xpath 选择器,即在 id="page" 的元素下寻找一个内容包含 下一页的 a 元素
// 这里也可以执行 JS 代码来 return 返回下一页 URL,但要记得在开头加上 js; 标识
        "nextL": "id('page')//a[contains(text(),'下一页')]",
// 这个是主体内容元素,即 id="content_left " 的元素下所有子元素
// 因为要向主体内容元素末尾插入,所以 insertP 可以省略
        "pageE": "#content_left",
// 这个是将当前网页中的某些元素替换为下一页的同类元素(如页码),想省力的话可以和 nextL 内容一样(但不能是 JS 代码)
        "replaceE": "#page",
// 这个是翻页动作触发点,即滚动条 与 网页底部之间小于 2000 时就会翻页,越大就意味着翻页越频繁
        "scrollD": 2000
    }
}
"在线之家": {
// 多个域名的话,就要写成数组了
    "host": [
            "www.zxzj.me",
            "www.zxzj.fun"
    ],
    "url": "return (fun.lp() != '/' && !fun.indexOF('/detail/') && !fun.indexOF('/video/'))",
// style 中如果只写了 CSS 选择器,那么代表要屏蔽隐藏该元素,脚本会自动在末尾加上 {display: none !important;}(因此这块可以省略不写)
    "style": "div.stui-page__all",
    "pager": {
        "nextL": "//ul[contains(@class, 'stui-page__item')]//a[text()='下一页']",
        "pageE": "ul.stui-vodlist > li",
        "replaceE": "ul.stui-page__item",
        "scrollD": 1000
    },
// 这下面的就是翻页前/后,要做的事情了
    "function": {
// 插入前执行的代码,在将主体元素插入网页之前,先处理一下(相比于插入后处理,会更快更好)
// 这个是脚本内置的函数,用来加载图片(一些网站是默认图片,只有浏览到时才会加载图片,而脚本翻页后就只能由脚本去加载图片了)
// 这个里面的 0 代表图片是 src 属性(1 代表是 background-image: url() 背景样式类的图片)
// 这个 "img[data-original]" 代表要寻找的图片 CSS 选择器
// 这个 "data-original" 代表要把图片的 data-original 属性内容设置为 src 属性
// 如果你要选择的是 img[data-original] 或 img[data-src] 且加载模式为 0,那么后面这个数组可以省略为 fun.src_bF(pageE)
        "bF": "return fun.src_bF(pageE, [1, 'a[data-original]', 'data-original'])"
    }
}
"动漫花园": {
    "host": [
        "dmhy.org",
        "share.dmhy.org",
        "dmhy.anoneko.com"
    ],
    "pager": {
        "nextL": "//div[@class='nav_title']/a[contains(text(), '下一')]",
        "pageE": "#topic_list > tbody > tr",
        "replaceE": ".nav_title"
    },
    "function": {
// 插入后执行的代码
// 直接插入 script 标签是不会执行其内部代码的,只有这样插入后才行
        "aF": "document.body.appendChild(document.createElement('script')).textContent = `xxx`"
    }
}

## 翻页模式 2

这个算是第二常见的,即网站自带了自动无缝翻页功能,只需要点一下网页中相应按钮即可。

"discuz_forum": {
    "host": "www.52pojie.cn",
// 没有 url 则代表该规则适用于全站,在规则不影响其他页面的情况下,可以偷懒不写
    "pager": {
// 模式 2
        "type": 2,
// 网页自带的无缝加载下一页/更多内容的元素
        "nextL": "#autopbn",
// 上面元素包含 "下一页" 文字时,脚本才会点击,用来避免多次重复点击,不写的话则会有默认 500ms 的间隔,可以用 interval 规则指定间隔(例如 "interval": 1000, 就是点击下一页元素后最少间隔 1000 毫秒才会继续点击)
        "nextTextOf": "下一页",
        "scrollD": 2000
    }
}

## 翻页模式 3

模式 1 的变种,对于部分网页主体内容与网页底部之间距离不固定的网站,需要把基准从网页底部改为页码等指定元素处。

"3DM": {
    "host": "www.3dmgame.com",
    "pager": {
// 模式 3
            "type": 3,
            "nextL": "li.next > a",
// 有些网站需要插入主体内容后,执行一些网页自身的 JS 文件,所以这里同时选择了 script 和网页主体元素
            "pageE": ".news_warp_center > *, script[src*='common.js']",
            "replaceE": ".pagewrap",
// 基准元素,当和 replaceE 一样时,可以省略
            "scrollE": ".pagewrap",
// 如果要运行 pageE 里选择的 script 代码,那么就需要指定 2
            "scriptT": 2,
// 为了避免翻页过快,而设置的翻页最小间隔(单位 ms)
            "interval": 500,
            "scrollD": 500
    }
}

## 翻页模式 5

对于部分动态加载内容的网站,如果其支持 iframe 且可以通过 GET 直接打开下一页,那么就能用该模式。

插入 iframe 方式来加载下一页,无限套娃~

"知乎 - 用户主页/收藏夹": {
    "host": "www.zhihu.com",
    "url": "fun.isUrlC(); if (fun.indexOF(/\\/people\\/.+\\/.+/) || fun.indexOF('/collection/')) {if (self != top) {fun.insStyle('#ProfileHeader {display: none !important;}')}; return true;}",
// 强制新标签页打开链接
    "forceTarget": true,
// 允许脚本在该网站的 iframe 中运行,模式 5 必须加上
    "iframe": true,
    "pager": {
// 模式 5
        "type": 5,
// 如果要用 JS 代码生成下一页 URL,则记得在前面加上 js; 标识
        "nextL": "js;let next = fun.getCSS('.Pagination .PaginationButton--current+button:not(.PaginationButton-next)');if (next) return (location.origin + location.pathname + '?page=' + next.textContent)",
// 如果要在插入下一页 iframe 后向本页插入自定义样式,则还可以在这里加个 "style" 规则(比如为了悬浮的样式与下一页的重叠,隐藏网页底部间距提高阅读连续性)
        "scrollD": 2000
    }
}

## 翻页模式 6

对于部分动态加载内容的网站,与上面不同的是,该模式适合简单的网页,没有复杂事件什么的。

插入 iframe 加载下一页,等其处理完后,获取下一页动态加载内容插入本页,只有一个娃~

"拷贝漫画 - 分类页": {
// 对于有规律的多域名,可以写成正则表达式
    "host": "/copymanga\\./",
    "url": "/\\/comics/",
    "pager": {
// 模式 6
        "type": 6,
        "nextL": "li.next > a",
        "pageE": ".exemptComicItem",
        "replaceE": "ul.page-all",
// 预留的下一页 iframe 网页加载时间,确保网页内容加载完成
        "loadTime": 1000,
        "scrollD": 3000
    },
    "function": {
// 插入本页前,将懒加载图片改为直接加载
// 如果你要选择的是 img[data-original] 或 img[data-src] 且加载模式为 0,那么后面这个数组可以省略为 return fun.src_bF(pageE)
        "bF": "return fun.src_bF(pageE, [0,'img[data-src]','data-src'])"
    }
}

该 Issues 下只讨论 自定义翻页规则,其他请求/反馈请新开 Issues,否则将会删除。

@XIU2 XIU2 added the 技巧教程 脚本技巧 或 相关教程 label Feb 22, 2022
@XIU2 XIU2 changed the title [自动无缝翻页] 自定义翻页规则示例说明 [自动无缝翻页] 自定义翻页规则 示例说明 Feb 22, 2022
@XIU2
Copy link
Owner Author

XIU2 commented Feb 26, 2022

原先搞得还是有点不方便,就干脆又加了个 外置翻页规则列表,把我最近这几天写的 自定义翻页规则 都给放进去了(后续也会把一些简单的网站规则都放进去),这样用户只需要 更新外置翻页规则 即可。

当然,自定义翻页规则依然保留,提供给有动手能力的人~

@Yunuuuu
Copy link

Yunuuuu commented Apr 5, 2022

您好!版主大大,我以前一直用这个https://github.com/machsix/Super-preloader, 这个最近更新很少了,感觉你这个自定义翻页规则真的棒,不知道能否添加分隔栏,因为不同页面连接得太完美了,导致我们很难分清哪些没看,那些看了!

@XIU2
Copy link
Owner Author

XIU2 commented Apr 5, 2022

@Yunuuuu 不会添加分隔栏,你看我脚本名字就知道了:自动“无缝”翻页
我就是因为不喜欢其他脚本的一些设计(特别是分隔栏我看着很别扭),所以我才专门按照我个人喜好写了这个脚本。

@Yunuuuu
Copy link

Yunuuuu commented Apr 5, 2022

多谢回复!明白了,谢谢您!

Repository owner deleted a comment from BradKML Aug 29, 2022
Repository owner deleted a comment from davisphper Dec 22, 2022
Repository owner deleted a comment from davisphper Dec 22, 2022
Repository owner deleted a comment from Viene0850 Dec 22, 2022
@XIU2 XIU2 pinned this issue Apr 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
技巧教程 脚本技巧 或 相关教程
Projects
None yet
Development

No branches or pull requests

2 participants