You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Node.js代码获取EPUB第二章前三段内容?

解决EPUB章节内容"File not found"问题并提取第二章前三段

问题根源分析

  • 直接用fs读取章节href对应的路径,忽略了EPUB内部文件的相对路径基准(相对于OPF文件位置)
  • Multer上传的文件路径未正确传递给epub.js,导致EPUB实例无法定位内部资源
  • 章节href可能包含URL编码或特殊字符,直接拼接路径会出错

修复后的完整代码实现

const express = require('express');
const multer = require('multer');
const fs = require('fs');
const Epub = require('epubjs');
const { JSDOM } = require('jsdom'); // 用于解析HTML段落

const app = express();

// Multer配置:存储上传的EPUB文件到临时目录
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDir = './uploads';
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir);
    }
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    cb(null, `${Date.now()}-${file.originalname}`);
  }
});
const upload = multer({ storage });

// 处理EPUB上传和解析的接口
app.post('/upload-epub', upload.single('epub'), async (req, res) => {
  if (!req.file) {
    return res.status(400).send('No file uploaded');
  }

  const epubPath = req.file.path;
  let book;

  try {
    // 初始化EPUB实例,使用文件路径直接加载
    book = Epub(epubPath);
    await book.ready; // 等待EPUB解析完成

    // 获取元数据(已成功部分,保留)
    const metadata = book.metadata;
    console.log('Metadata:', metadata);

    // 获取目录(已成功部分,保留)
    const toc = book.navigation.toc;
    console.log('Table of Contents:', toc);

    // 找到第二章(优先按标题匹配,无匹配则取索引1的项)
    const chapter2 = toc.find(item => item.label.includes('第二章')) || toc[1];
    if (!chapter2) {
      return res.status(404).send('第二章未找到');
    }

    // 通过epub.js的render方法获取章节内容,自动处理内部路径
    const rendition = book.renderTo('div');
    const chapterContent = await rendition.display(chapter2.href);

    // 使用JSDOM解析HTML,提取前三段文本
    const dom = new JSDOM(chapterContent);
    const paragraphs = dom.window.document.querySelectorAll('p');
    const firstThreeParagraphs = Array.from(paragraphs)
      .slice(0, 3)
      .map(p => p.textContent.trim());

    // 返回结果
    res.json({
      metadata,
      chapter2Title: chapter2.label,
      firstThreeParagraphs
    });

  } catch (error) {
    console.error('解析错误:', error);
    res.status(500).send(`解析失败: ${error.message}`);
  } finally {
    // 清理临时文件和EPUB实例资源
    if (fs.existsSync(epubPath)) {
      fs.unlinkSync(epubPath);
    }
    book?.destroy();
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

关键修复点说明

  • 放弃直接fs读取:使用epub.js内置的renderTo和display方法获取章节内容,内部自动处理EPUB内部的相对路径和资源定位逻辑
  • 等待解析完成:必须等待book.ready状态后再操作目录和章节,确保所有EPUB资源解析完毕
  • 精准提取段落:借助jsdom解析章节HTML,直接定位<p>标签提取文本,避免手动处理HTML字符串的混乱
  • 资源清理:在finally块中删除临时上传文件、销毁EPUB实例,避免内存泄漏和磁盘空间占用

依赖安装

确保安装所有必要依赖:

npm install express multer epubjs jsdom

内容的提问来源于stack exchange,提问作者SirBT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 05:22:48