name: web-to-epub description: 将在线书籍网站(每章一个页面)转换为 EPUB 电子书。提供网站 URL 即可自动抓取、提取正文、生成带目录的 EPUB。 allowed-tools: Bash, Read, Write, WebFetch, Grep, Glob argument-hint: [book-url]
网页书籍转 EPUB
将在线书籍网站转换为 EPUB 电子书。目标 URL: $ARGUMENTS
整体流程
- 分析目录页 — 获取章节链接和书籍结构
- 生成章节配置 — 创建
chapters.json定义章节顺序和元数据 - 下载所有页面 — 使用 wget 批量下载,带限速避免触发反爬
- 提取正文内容 — 使用 Python 脚本剥离导航栏等 UI 元素,只保留正文
- 生成 EPUB — 使用 pandoc 合并生成带分层目录的 EPUB
前置依赖
确保以下工具已安装(macOS 用 Homebrew):
brew install pandoc wget
pip3 install --break-system-packages beautifulsoup4
步骤详解
Step 1: 分析目录页
使用 WebFetch 获取目标 URL 的目录页,提取所有章节链接。注意:
- 识别书名、作者
- 识别前言/序言/致谢等前置内容
- 识别分篇/分卷结构(如:第一篇、第二篇...)
- 按阅读顺序排列所有章节 URL
- 注意区分正文链接和导航/外部链接
Step 2: 创建工作目录和配置文件
在当前目录下创建 epub_build/ 工作目录,生成以下文件:
urls.txt — 所有章节的完整 URL,每行一个
https://example.com/book/preface
https://example.com/book/ch01
https://example.com/book/ch02
...
chapters.json — 章节结构定义
{
"book_title": "书名",
"author": "作者",
"content_selector": "article",
"prose_selector": { "tag": "div", "class": "prose" },
"parts": [
{ "title": "第一篇 标题", "before_index": 4 }
],
"chapters": [
{ "path": "foreword.html", "title": "前言" },
{ "path": "preface.html", "title": "自序" },
{ "path": "s01/ch01.html", "title": null, "chapter_num": 1 }
]
}
配置说明:
content_selector: 正文所在的 HTML 容器标签(通常是article、main或div.content)prose_selector: 正文文字所在的子容器(可选,用于过滤侧边栏等噪声)parts[].before_index: 该篇标题应插入在第几个章节之前(0-indexed)chapters[].path: 对应 wget 下载后的本地文件相对路径chapters[].title: 显示标题;为 null 时使用 chapter_num 自动生成"第N章"
关键:需要先用 WebFetch 查看一个章节页面的 HTML 结构,确定正确的
content_selector 和 prose_selector。
Step 3: 下载所有页面
cd epub_build
mkdir -p html
wget \
--directory-prefix=html \
--convert-links \
--adjust-extension \
--page-requisites \
--no-parent \
--random-wait --wait=1 \
--input-file=urls.txt
下载参数说明:
--adjust-extension: 自动加.html后缀--page-requisites: 同时下载图片等资源--convert-links: 将链接转为本地路径--random-wait --wait=1: 随机等待 0.5-1.5 秒,避免过快请求
下载完成后确认文件数量与 urls.txt 行数一致。
Step 4: 确定 HTML 路径映射
wget 下载后的文件路径取决于 URL 结构。通常在 html/<域名>/<路径>.html。
用以下命令查看实际下载路径:
find html -name "*.html" | sort
根据实际路径更新 chapters.json 中每个章节的 path 字段,使其相对于 HTML
根目录。
Step 5: 提取正文并生成 clean HTML
python3 ~/.claude/skills/web-to-epub/scripts/extract_and_build.py \
--html-dir html/<域名>/<书籍路径> \
--chapters-json chapters.json \
--output-dir clean \
--files-list files.txt
脚本会:
- 从每个 HTML 中提取
content_selector>prose_selector区域的正文 - 在适当位置插入篇标题(h1)和章节标题(h2)
- 输出 clean HTML 文件和有序文件列表
Step 6: 生成 EPUB
pandoc \
--from=html \
--to=epub3 \
--output="<书名>.epub" \
--metadata title="<书名>" \
--metadata author="<作者>" \
--metadata lang="zh-CN" \
--toc --toc-depth=2 \
--split-level=2 \
$(cat files.txt)
参数说明:
--toc --toc-depth=2: 自动生成两级目录(篇 h1 + 章 h2)--split-level=2: 按 h2 拆分 EPUB 章节,每章一个独立页面
可选增强:
--css=style.css: 自定义样式--epub-cover-image=cover.jpg: 添加封面图
Step 7: 验证
用 Python 检查 EPUB 结构:
import zipfile
from bs4 import BeautifulSoup
with zipfile.ZipFile("<书名>.epub", "r") as z:
with z.open("EPUB/nav.xhtml") as f:
soup = BeautifulSoup(f.read(), "html.parser")
for li in soup.find_all("li"):
a = li.find("a")
if a:
depth = sum(1 for p in li.parents if p.name == "li")
print(" " * depth + a.get_text(strip=True))
将最终 EPUB 复制到当前工作目录根下,告知用户文件路径和大小。
可选:自定义样式
如需更好的阅读体验,创建 style.css:
body {
font-family: serif;
line-height: 1.8;
text-align: justify;
}
h1 {
text-align: center;
margin-top: 2em;
margin-bottom: 1em;
}
h2 {
text-align: center;
margin-top: 1.5em;
margin-bottom: 1em;
}
p {
text-indent: 2em;
margin: 0.5em 0;
}
注意事项
- 下载时使用限速(
--wait),尊重网站服务器 - 每个网站的 HTML 结构不同,Step 2 中的 selector 配置需要根据实际页面调整
- 如果网站使用 JavaScript 渲染内容(SPA),wget 可能无法获取正文,需考虑使用 headless browser
- 生成的 EPUB 可直接用 Apple Books 打开,发送到 Kindle 需要转换格式或通过 Send to Kindle
Expert Next.js App Router
Developpement
Un skill qui transforme Claude en expert Next.js App Router.
Générateur de README
Developpement
Crée des README.md professionnels et complets pour vos projets.
Rédacteur de Documentation API
Developpement
Génère de la documentation API complète au format OpenAPI/Swagger.