☰
用 xerj autoindex 搜索 EPUB 电子书文件夹:按章索引的提取原理与实战
2026/10/18 16:48:13 网站建设 项目流程
  • 人工智能
  • 搜索引擎
  • 本地部署
  • 后端
  • MCP 服务

【免费下载链接】xerj

XERJ is the new way for AI to search data. Its autoindex capability activates agents to know your data without the token waste of grep and sed. One command indexes code, docs, logs and PDFs for search, RAG, security audits and agent memory, using 40x fewer tokens than grep. Elasticsearch compatible, so existing clients just work.

项目地址:https://gitcode.com/GitHub_Trending/xe/xerj
点击查看免费下载

把xerj autoindex指向一个装满电子书的目录,XERJ 就会把每本.epub拆成一条条"一章一记录"的检索单元:章节标题取自书的目录,书名、作者等元数据随每条记录写入索引,之后你可以像搜网页一样定位到具体章节。本文以官方文档 good_epub_answer.md 为骨架,结合 epub.rs 等源码实现,讲清 EPUB 索引的完整流程、记录字段、边界行为与安全预算,读完即可在自己的书库上跑通并理解每一步发生了什么。

一条命令索引整个书库

EPUB 场景的入口和索引其他本地文件完全一致:直接对文件夹执行xerj autoindex:

xerj autoindex ./books

XERJ 会遍历./books下的本地文件系统(对应 lib.rs 中的 walk 阶段),逐文件做内容嗅探与类型判定,把每个.epub读成"按阅读顺序、每章一条记录",并在单节点安装上完成索引。再次运行命令也不会重复:日志会续跑(resume),幂等的_id保证不会产生重复记录。

一本书如何变成若干条检索记录

在 epub.rs 中,每条章节记录是一个 JSON 字段集,包括:

字段来源说明
title包文档<metadata>的dc:title书名,附在每条章节记录上;无标题时退回文件名(测试a_book_without_a_title_is_titled_from_its_logical_name验证)
authordc:creator多位作者以;连接;缺失时不写入空串
language/publisher/datedc:language/dc:publisher/dc:date均取自包文档,缺失即缺省
chapterspine 中该 XHTML 文档的 1-based 位置章节编号,邻居被跳过或为空时编号保持稳定
part同一文档内按目录切出的块序号(1-based)仅当目录把多个章节塞进一个文件时出现
chapter_title目录条目,或文档第一个标题见下文"章节识别"
section长章节的切分序号章节过长时像 PDF 页面一样分节,section仅在大于 0 时写入
body章节正文经 HTML tokenizer 提取后的纯文本

每条记录的定位符(locator)也携带了层级信息:未切块的文档为ch{n}-s{j}(如ch2-s0),被目录切块的文档为ch{n}.{k}-s{j}(如ch2.3-s0)。chapter、part、section三个数字让搜索结果可以直接回溯到"第几章、第几节",这是把书当成可检索语料而非一整个文本块的关键设计。

章节识别:目录驱动的切分

EPUB 是 zip 容器,XERJ 通过META-INF/container.xml找到包文档(OPF),再依次解析其中的<metadata>(书的信息)、<manifest>(id 到文件的映射)和<spine>(阅读顺序)。每个 spine 文档都是 XHTML,正文交给 HTML 提取器的 tokenizer 处理——章节文本的产出方式与一个.html页面无异。

chapter_title的优先级(见 epub.rs):

  1. EPUB 3 的nav导航文档(epub:type="toc"的那个nav);
  2. 没有nav或它没有任何条目时,回退到 EPUB 2 的 NCX(由spine@toc命名,或按其媒体类型识别);
  3. 都没有命中时,用文档的第一个标题。

多章节单文件切割:很多书把多个章节打包进一个文档(源码注释以 Project Gutenberg 的《白鲸》为例:135 章装在 13 个文件里)。因此 toc_pieces 会在每个目录条目锚点(file.xhtml#id)处把文档切开,每一块以对应目录条目标题命名并编号part。切割时的细节行为(均有测试覆盖):

  • 指向缺失锚点的条目被忽略;若全部无法解析,第一条目标题整篇文档;
  • 两条目录落在同一位置时,先出现的标签获胜;
  • 第一个锚点之前的文本(前言/扉页)单独成块且无标题;
  • 只含标题本身的空块会被折叠进下一块,两个标题用—连接(如CHAPTER 4 — The Counterpane.)。

这一设计让"目录里有多少章"直接决定记录粒度,搜索时既能定位到整章,也能定位到章内小节。

格式识别:内容嗅探而非扩展名

EPUB 能被正确识别,依赖 sniff.rs 的内容嗅探:文件头PK\x03\x04(zip 魔数)命中后,zip_container_kind 会打开容器检查各成员——DOCX/PPTX/XLSX 按各自主部件识别,EPUB 则看mimetype成员是否为application/epub+zip(源码 sniff.rs)。因此扩展名不会被信任:把 JSON 改名成.epub会被按 JSON 索引,反之真正的 EPUB 即便扩展名怪异也能被识别。识别为Family::Epub后,由 extract/mod.rs 分发到epub::extract。

边界行为:DRM、无 OCR 与无效书

官方文档明确了两类"读不了"的情况,源码中都有对应实现与测试:

  • DRM 保护的章节被跳过,而不是解密:XERJ 读取META-INF/encryption.xml,凡是加密算法不属于字体混淆(IDPF/Adobe 的字体嵌入算法)的部件,一律视为 DRM,其密文不会被当成正文索引进噪声(epub.rs)。测试drm_encrypted_chapters_are_skipped_but_font_obfuscation_is_not_drm还验证了另一面:纯字体混淆不属 DRM,正文仍然可读。
  • 只有页面图片的书不会被读取:没有 OCR 能力,纯图片书无法产出文本。
  • 无任何可读章节的书是 junk:既没有META-INF/container.xml/包文档、又没有可读正文的书,会被标记为junk而非产生空记录(测试a_book_without_a_package_or_without_text_is_junk)。
  • 同时出现在 spine 里的导航文档(会重复章节标题)和非 XHTML 的 spine 项(如图片)也会被跳过。

安全与资源预算:解压上限与记录上限

EPUB 是压缩容器,恶意书可能伪装成 zip 炸弹,因此 epub.rs 设置了与docx.rs、pptx.rs一致的三层预算:

常量值作用
MAX_PART_BYTES32 MiB单个章节部件的解压读取上限(章节通常只有几 KB 到几 MB)
MAX_TOTAL_DECOMPRESSED_BYTES256 MiB整个容器的累计解压上限(一千个受限部件加起来仍是炸弹防线)
MAX_BODY_BYTES64 MiB整本书提取正文的累计上限
MAX_RECORDS_PER_FILE4096(extract/mod.rs)单文件记录数上限

任一预算耗尽后,剩余章节会被丢弃,文件标记为truncated(测试the_decompression_budget_truncates_rather_than_reading_on验证)。长章节本身也会被 split_sections 按节切分,避免单条记录过大。

测试保障:行为即契约

epub.rs 的测试模块 用内存构造的 zip 容器完整覆盖了上述行为,可作为理解实现的活文档:

  • EPUB 3:spine 顺序、nav 与 cover 不入章、章节编号保持、目录标题与书元数据逐字段断言;
  • EPUB 2:无nav时用 NCX 取标题,处理百分号编码与..相对路径;
  • DRM 跳过与字体混淆放行;
  • 无包/无正文 → junk;
  • 无dc:title→ 用文件名作书名;
  • 长章节切分与section字段;
  • 多章节单文件按目录锚点切割(含坏锚点、重复锚点、<br/>分隔标签、仅标题块的折叠合并);
  • %XX转义解码与畸形转义存活。

索引之后:如何检索这些章节

索引完成后,书籍章节以标准记录形式进入ax-*索引(--prefix默认ax,可用xerj autoindex map [--json]查看字段类型与示例值)。之后即可用 Elasticsearch 兼容的_search接口查询,例如按作者过滤、按章节标题匹配、或在body全文中定位关键词——由于每条记录都携带title、chapter、part、section与chapter_title,命中结果能直接指出"哪本书的第几章第几节"。

小结

xerj autoindex对 EPUB 的处理是一条完整的"识别 → 拆解 → 建记录"流水线:内容嗅探识别真实格式,OPF 包文档提供书目元数据,spine 保证阅读顺序,目录锚点决定章节粒度,DRM/无 OCR 等边界被明确处理,解压与记录预算防止恶意输入。对于手头有成百上千本电子书的用户,只需一条命令即可把整个书库变成可按章检索的本地索引,无需任何预转换或人工整理。

  • 人工智能
  • 搜索引擎
  • 本地部署
  • 后端
  • MCP 服务

【免费下载链接】xerj

XERJ is the new way for AI to search data. Its autoindex capability activates agents to know your data without the token waste of grep and sed. One command indexes code, docs, logs and PDFs for search, RAG, security audits and agent memory, using 40x fewer tokens than grep. Elasticsearch compatible, so existing clients just work.

项目地址:https://gitcode.com/GitHub_Trending/xe/xerj
点击查看免费下载

相关推荐

上一篇:【亲测免费】 推荐使用SwitchKey:智能输入源切换神器
下一篇:推荐:Dart Code Metrics - 提升Dart代码质量的利器(已停更)

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询