PDF 书籍 → 章节化自包含 HTML 站点
何时使用
- 用户提供一本 PDF 书,要求"拆解总结 / 分成章节 / 每章一个独立 HTML 页面 / 能在线访问 / 做个目录页"。
- 适合中文书(金融投资类常见),尤其是张志雄《Value》版等"目录重排、正文用原版章节编号"的译本。
核心难点(必读)
- 文本逐字拆行:很多中文 PDF 的文本层把每个汉字单独放一行,或把"第 二 章"跨行拆分,导致整行正则匹配章节标题失效。
- 用pdfplumber提取(比 pypdf 干净),并跨行拼接来检测标题。 - 扫描版/图片型 PDF 无文字层:
pdfplumber.extract_text()返回空或极短。需要先渲染页面为图片,再做 OCR。
- 用PyMuPDF(fitz)把每页渲染成 PNG:page.get_pixmap(matrix=fitz.Matrix(dpi/72, dpi/72))。
- 用rapidocr_onnxruntime做中文 OCR(pip install rapidocr_onnxruntime),比 tesseract 更轻量、纯 pip 安装,准确率对印刷体足够。
- 多进程并行:Pool(..., initializer=init_rapidocr),worker 数取min(8, cpu_count())。
- OCR 后得到p0001.txt ~ pXXXX.txt,再按目录页码或正则切分章节。 - 目录结构 vs 正文结构不一致:译本目录常把原版多章重排为"3 大章 + N 小节",而正文仍用原版"第X章"编号。以用户可见的目录 + 正文页码边界共同确定切分。
工作流(5 步)
1. 提取与切分
import pdfplumber, os
PDF="book.pdf"; OUT="extracted"; os.makedirs(OUT, exist_ok=True)
with pdfplumber.open(PDF) as pdf:
pages=[p.extract_text() or "" for p in pdf.pages]
# 先探测边界:用跨行容错的正则找"第X章/第X部分/附录X/编后记"
import re
pat=re.compile(r'^(第[一二三四五六七八九十]+\s*[部分章])\s*([\u4e00-\u9fff].{0,25})?')
for i,p in enumerate(pages):
for ln in p.splitlines():
if pat.match(ln.strip()): print(i+1, ln.strip()[:45])
# 按确定的页码范围写入 part1/part2/.../intro/app1... 文本文件
- 边界确定后,用
pages[a-1:b]切片保存各章文本,便于子代理/人工阅读。
2. 并行总结(省上下文)
- 把三大块(或每章)文本文件分给 多个并行 general-purpose 子代理(run_in_background=true),各自读文件、产出结构化中文 markdown 总结(模板:章节概述 / 各小节:核心论点、关键概念、案例与例证、重要引述、本节要点 / 本章核心金句),写入
summary_xxx.md。 - 导言与附录可由主代理亲自读原文撰写(篇幅小)。
3. 生成自包含 HTML 站点
- 每个页面内联 CSS/JS(无外部依赖),这样无论本地打开还是托管都能"独立访问"。
- 必备组件:
- 顶部 sticky 栏 + 目录抽屉(off-canvas,列出全部章节与子节,当前页高亮)。
- 正文用轻量 markdown→HTML 转换器(处理
#/##/###、-列表、1./1、有序列表、>引用、**粗体**、<hr>)。 - 右侧 sticky 章节内导航(用
##标题做锚点,IntersectionObserver 高亮当前节)。 - 底部 上一页/下一页 翻页条。
- 顶部阅读进度条 + 回到顶部按钮。
- 锚点 slugify:中文标题做 id 时剔除
、,。:()等标点(替换为-),且抽屉/章节内导航的#锚点必须与正文id用同一 slugify,否则点击不跳转。 - 生成
index.html:书籍封面 hero + 全书结构卡片(每章可展开子节,点击跳转到chapterX.html#锚点)。
4. 本地验证
cd site && python -m http.server 8765 &
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8765/index.html # 应 200
# 校验锚点:每个页面 href="#x" 都能找到对应 id=
- 检查无残留
__CSS__/__JS__/__TITLE__等占位符。
5. 部署到 CloudStudio(满足"独立在线访问")
- 用
workbuddy_cloudstudio_deploy(directory=site, entry=index.html, port=3000)。 - 返回 shareLink;每个页面在线地址为
shareLink/chapterX.html(curl 验证 200)。
输出清单(典型)
index.html + intro.html + chapter1~3.html + appendix1~3.html + afterword.html(共 9 页),相对链接互相跳转,整站可整体托管。
注意
- 总结必须忠实原文,引用尽量用书中原话(中文),不虚构。
- 金融书常含敏感/合规内容,仅做学习向拆解总结,注明"仅供学习交流"。