Appearance
书源制作提示词与手把手教程
这一页分两部分:可以直接复制的 AI 提示词模板,和一份跟着做就能做出一个真实可用书源的 分步教程。建议先看教程,理解每一步“为什么这么写”,再用提示词模板让 AI 帮你处理具体站点—— 知道该验收什么,比只会复制粘贴 AI 给的 JSON 更重要。
AI 提示词模板
text
请为 Readori 分析这个站点:<URL>。
先判断是否需要登录、Cookie、WebView、验证码、付费或动态 JavaScript。
根据 Readori 的 BookSource 字段生成 JSON,优先使用静态 HTTP、CSS/XPath/JSONPath 规则。
必须分别验证搜索、书籍详情、章节目录、章节正文、图片和下一页;目录 HTTP 200 不算成功。
保留 bookSourceUrl 作为来源身份,说明请求所需的有效基础地址、请求头、编码和登录要求。
输出:来源 JSON、字段解释、已验证样例、失败边界、需要在 iOS 真机复核的项目。
不要生成账号密码、Cookie、Token、绕过验证码或支付的逻辑。生成后仍需在 Readori 的来源管理和真实设备中回放。
手把手:从零做一个书源
书源本质上是"给定一个 HTML/JSON 页面,用规则把书名、章节、正文这些信息挖出来"。挖的 过程分成固定的几段——搜索、详情、目录、正文——每一段单独写、单独测,不要指望一次性写完 整个 JSON 就能跑通。下面用一个虚构但典型的站点结构走一遍完整流程,字段和语法全部对应 书源字段参考和规则语法参考,可以随时切过去 查更完整的定义。
准备工作
- 一个浏览器(Safari/Chrome 均可),用"查看网页源代码"或开发者工具的"检查元素", 不是看渲染后的效果图,是看真实返回的 HTML——书源规则匹配的是 HTML 结构,不是 肉眼看到的排版;
- 一个你确定这个站点搜得到的关键词,比如书名"斗罗大陆",全程用它测试;
- Readori 的书源编辑器(或者一个文本编辑器 + 后面导入),以及 书源批量验证入口,用来做每一步之后的实际验证。
如果是让 AI 帮你分析站点,做法是把下面每一步要看的 HTML 片段复制给它,一步步要结果, 而不是把整个网页源码一次性丢给它说"帮我生成书源"——AI 和人一样,拆开一小段一小段来看, 出错了更容易定位是哪一部分理解错了。
第 1 步:确定搜索入口
打开站点搜索页,用测试关键词搜一次,看两件事:
搜索请求的 URL 长什么样。 比如地址栏变成
https://www.example-book.com/search.php?keyword=斗罗大陆,那searchUrl就是:texthttps://www.example-book.com/search.php?keyword={{key}}是占位符,Readori 请求时会替换成实际搜索词(URL 编码由请求层处理,规则里 不需要自己再编码一次)。如果搜索是 POST 请求(打开浏览器开发者工具的网络面板确认 请求方法),需要用 URL 请求选项语法,见规则语法参考。搜索结果列表的 HTML 结构。 用"检查元素"点开任意一条搜索结果,找到包住"一整本书" 的最小外层标签。假设看到的结构是这样:
html<div class="result-list"> <div class="book-item"> <a href="/book/12345/" class="book-link"> <img src="/covers/12345.jpg" class="book-cover"/> </a> <div class="book-info"> <h3><a href="/book/12345/">斗罗大陆</a></h3> <p class="author">作者:唐家三少</p> <p class="intro">简介:这是属于唐三的世界...</p> <span class="tag">玄幻</span> <span class="update">最新:第1000章 大结局</span> </div> </div> <!-- 后面还有更多 .book-item --> </div>能重复出现、每次对应一本书的标签是
<div class="book-item">。这一层就是bookList。
第 2 步:写搜索规则 ruleSearch
bookList 选中的每一个元素会变成后续所有字段的"局部上下文"——name/author 这些字段 的规则,都是相对这一个 .book-item 内部去找,不是相对整个页面。这是新手最容易搞混的一 点:写 author 规则的时候,脑子里应该只想着"这一条书的 HTML 长什么样",忽略页面上其他 书的存在。
对照上面的 HTML,一个字段一个字段填:
json
"ruleSearch": {
"bookList": ".book-item",
"name": "h3 a@text",
"author": ".author@text##作者[::]?",
"intro": ".intro@text##简介[::]?",
"kind": ".tag@text",
"lastChapter": ".update@text##最新[::]?",
"bookUrl": ".book-link@href",
"coverUrl": ".book-cover@src",
"checkKeyWord": "斗罗大陆"
}逐条解释:
name:.book-item内部找h3下面的a,取文本;author/intro/lastChapter:站点在文案里自带了"作者:"“简介:”“最新:”这类前缀, 用内联##前缀##替换链去掉,只留后面的正文——这里用的是没有@css:前缀的默认写法, 这一点很重要:只有默认(不显式加引擎前缀)的规则末尾的##才会被识别成替换链, 显式写@css:会把##之后的内容整体并入选择器,替换链失效,具体原因见 规则语法参考;bookUrl/coverUrl:取的是href/src,值是相对路径(/book/12345/),Readori 请求 时会自动按bookSourceUrl补全成绝对地址,规则里不需要手动拼域名;checkKeyWord:写你测试用的关键词,批量验证时会用它复测。
写完立刻测,不要往下写。 把这段 ruleSearch 单独放进书源编辑器保存,用测试关键词 搜一次,检查搜索结果列表里书名、作者是不是对的。这一步测不通,后面详情/目录/正文全部 无从谈起。
第 3 步:写详情规则 ruleBookInfo
点开第 2 步里 bookUrl 对应的详情页,同样先看 HTML:
html
<div class="book-detail">
<h1 class="book-title">斗罗大陆</h1>
<p class="book-author">作者:唐家三少</p>
<div class="book-intro">简介内容……</div>
<img class="book-cover" src="/covers/12345.jpg"/>
<a class="toc-link" href="/book/12345/toc.html">查看目录</a>
</div>详情页最关键的字段是 tocUrl——它决定了下一步去哪抓目录,找不到目录链接,规则写得 再漂亮也没用:
json
"ruleBookInfo": {
"name": ".book-title@text",
"author": ".book-author@text##作者[::]?",
"intro": ".book-intro@text",
"coverUrl": ".book-cover@src",
"tocUrl": ".toc-link@href"
}如果目录和详情其实是同一个页面(很多站点是这样,目录列表就写在书籍简介下面), tocUrl 可以直接不写,Readori 会回退用详情页自己的地址去抓目录,见 书源字段参考。
同样,写完单独测:搜索结果点进详情页,确认书名、作者、简介都对,且能拿到一个可用的 目录地址。
第 4 步:写目录规则 ruleToc
打开 tocUrl,看章节列表结构:
html
<ul id="chapter-list">
<li><a href="/book/12345/1.html">第1章 精神力测试</a></li>
<li><a href="/book/12345/2.html">第2章 七怪之首</a></li>
<!-- ... -->
</ul>json
"ruleToc": {
"chapterList": "#chapter-list li",
"chapterName": "a@text",
"chapterUrl": "a@href"
}如果目录本身分页(比如"共 50 章,每页 20 章,下一页"),还需要 nextTocUrl,指向 "下一页"按钮的地址:
json
"nextTocUrl": "a.next-toc-page@href"Readori 会沿着 nextTocUrl 一直翻页抓取,直到某一页拿不到下一页地址为止,抓到的所有页 的章节会拼成一份完整目录,不需要自己判断"翻到第几页该停"。
这一步测试要看两件事:章节数量对不对(如果站点显示"共 1000 章",抓出来的目录也应该 接近这个数字,明显偏少通常说明分页目录没翻完);章节顺序对不对(有些站点默认倒序 展示最新章节在前,需要额外处理,不属于这份最小示例范围,可以在编辑器里查看是否有 "倒序"相关选项)。
第 5 步:写正文规则 ruleContent
打开随便一章的地址,看正文结构:
html
<div id="content">
<p>正文第一段……</p>
<p>正文第二段……</p>
<script>/* 站点统计脚本 */</script>
</div>
<a id="next-chapter" href="/book/12345/2.html">下一章</a>json
"ruleContent": {
"content": "#content@html##<script[\\s\\S]*?</script>##",
"nextContentUrl": "#next-chapter@href"
}content取html而不是text,是为了保留段落<p>标签,阅读器渲染时能识别段落 边界;混进来的<script>标签用内联##替换链删掉;nextContentUrl处理"一章内容也分好几页"的站点(长章节常见);如果这一章正文就在 一个页面里没有分页,这个字段可以不写。
这一步最容易出的错是正文里混进了和内容无关的干扰元素——广告位、"本章说"评论区、 "加入书签"按钮文案。遇到这种情况,先看这些元素是不是有独立的 class/id(能单独选中就删); 如果是散落在正文段落之间的文字(比如每隔几段插一行广告文案),改用独立的 replaceRegex 字段按行清洗,见规则语法参考,不要在 content 规则末尾堆一长串 ##。
第 6 步:组装 JSON,导入验证
把前面几步拼成完整的 BookSource JSON(外层字段和最小骨架见 API 参考首页),通过在线书源里的 "粘贴 JSON" 或"导入文件"存进书源列表,然后跑一次单源验证(不是等着攒够一批书源再验证, 新写的书源应该单独先测)。
第 7 步:读懂验证失败提示
验证失败会给出"失败分组 + 失败类型"两个标签,具体含义见 书源批量验证。对照着排查,而不是逐个字段 瞎猜:
text
搜索失效 + 规则空 → 回第 2 步,检查 bookList/name/bookUrl 是不是选错了元素
搜索正文失效 → 搜索本身没问题,但取回来的 name/bookUrl 有问题,通常是相对路径
拼接错了,或者选到了错误的 <a> 标签
搜索目录失效 → 第 3/4 步的 tocUrl 或目录页规则有问题
搜索正文失效(在正文阶段)→ 回第 5 步,检查 content/nextContentUrl
校验超时 → 网站响应慢或需要更长 timeout,不是规则写错了
反爬 / TLS → 不是规则问题,参考 [Cloudflare 与人机验证](/advanced/cloudflare-bypass)一次验证不通过很正常,书源开发本来就是"写一段、测一段、根据报错改一段"的循环,不是 一次成型。
用 AI 辅助时,怎么检查它有没有偷工减料
把上面每一步的 HTML 片段喂给 AI、让它给出对应字段,是最不容易出错的用法。如果直接让 AI "分析整个站点生成完整书源",交回来的东西按下面四点检查:
1. 来源 JSON——字段和写法应该能对照书源字段参考、 规则语法参考逐条查到,AI 编出来的字段名(不在参考表里的)大概率 是幻觉,需要单独确认。
2. 字段解释——AI 应该逐条说明每个非显而易见的规则为什么这么写,例如:
text
ruleSearch.bookList: ".search-item"
站点搜索结果每条是一个 <div class="search-item">,没有更外层的列表容器可选,
所以直接用 class 选择器而不是 id.xxx 形式
ruleContent.content: "#article@html##<script[\s\S]*?</script>##"
正文容器里混了统计脚本,用内联 ## 替换链删掉;没有用 replaceRegex 字段是因为
只有这一条清洗规则,写在规则末尾更紧凑3. 已验证样例——至少一次搜索关键词 + 命中的书名,加上取到的详情/目录/正文片段长度, 证明规则真的跑通了,而不是"看起来应该可以"。AI 没有实际执行请求的能力时,这一项它写 不出来,应该老实说"未验证",而不是编一个看起来合理的样例。
4. 失败边界与真机复核项——哪些请求依赖 WebView(需要在真机上确认 WKWebView 行为, 模拟器/Python 回放不能替代)、哪些字段没测(比如没有 VIP 章节可测 payAction)、遇到过 的反爬信号(参考Cloudflare 与人机验证的关键词列表)。
拿到这四部分后,还是要按第 7 步走一遍书源批量验证,通过之后 再当作候选源导入正式书架——AI 生成的规则和真实抓取结果之间,永远以后者为准。
