首页 > 教程攻略 > ai资讯 >扫描书籍PDF文件转Markdown/EPUB工具pdf-craft

扫描书籍PDF文件转Markdown/EPUB工具pdf-craft

来源:互联网 时间:2026-06-22 17:57:04

日常处理PDF文档时,最头疼的莫过于格式转换——尤其是遇到扫描版PDF或带复杂排版的出版物。今天聊的这个工具,可以完全离线运行,把PDF一键转成Markdown或EPUB格式,效果相当扎实。它背后用的是DocLayout-YOLO和OnnxOCR技术,专攻PDF正文内容的精准提取。下面详细拆解一下。

项目简介

这个工具的核心流程是这样的:它会将PDF逐页读入,然后借助DocLayout-YOLO以及作者自己写的一个算法,把书页里的正文部分提取出来,同时过滤掉页眉、页脚、脚注、页码这些干扰元素。跨页处理时,算法会智能判断前后文的衔接关系,确保生成的文本语义通顺。页面上的文字则依靠OnnxOCR进行识别。至于阅读顺序,用了layoutreader来排定,符合人类从左到右、从上到下的习惯。

安装

准备环境很简单,得先确保Python版本是3.10或以上(推荐3.10.16)。然后执行一条pip命令即可:

pip install pdf-craft

功能

PDF 转化为 MarkDown

整个过程不需要调用远程的大语言模型,纯粹靠本地算力(CPU或显卡)就能搞定。第一次运行时会联网下载所需的模型。遇到文档中的插图、表格、公式,系统会直接截取图片并插入到生成的Markdown文件中。代码调用示例:

from pdf_craft import PDFPageExtractor, MarkDownWriter

extractor = PDFPageExtractor(
    device="cpu",  # 如果希望使用 CUDA,请改为 device="cuda:0" 这样的格式。
    model_dir_path="/path/to/model/dir/path",  # AI 模型下载和安装的文件夹地址
)
with MarkDownWriter(markdown_path, "images", "utf-8") as md:
    for block in extractor.extract(pdf="/path/to/pdf/file"):
        md.write(block)

执行完成后,目标地址会生成一个*.md文件。如果原PDF中有插图、表格或公式,会自动在*.md同级目录下创建一个assets文件夹来保存图片,Markdown文件以相对路径引用这些图片。

转换效果相当不错,无论排版多复杂,正文都能保持完整。

PDF 转化为 EPUB

这个功能的逻辑前半部分和PDF转Markdown相同:先用OCR从PDF中扫描识别文字。因此需要先构建PDFPageExtractor对象:

from pdf_craft import PDFPageExtractor

extractor = PDFPageExtractor(
    device="cpu",  # 如果希望使用 CUDA,请改为 device="cuda:0" 这样的格式。
    model_dir_path="/path/to/model/dir/path",  # AI 模型下载和安装的文件夹地址
)

之后需要配置一个LLM对象。推荐使用DeepSeek——本库的Prompt是基于其V3模型调试的。配置示例如下:

from pdf_craft import LLM

llm = LLM(
    key="sk-XXXXX",                # LLM 供应商提供的 key
    url="https://api.deepseek.com", # LLM 供应商提供的 URL
    model="deepseek-chat",          # LLM 供应商提供的模型
    token_encoding="o200k_base",    # 进行 tokens 估算的本地模型名(不关心可保留此项)
)

两个对象准备好后,就可以扫描并分析PDF书籍了:

from pdf_craft import analyse

analyse(
    llm=llm,
    pdf_page_extractor=pdf_page_extractor,
    pdf_path="/path/to/pdf/file",
    analysing_dir_path="/path/to/analysing/dir",
    output_dir_path="/path/to/output/files",
)

这里有两个文件夹参数需要注意。output_dir_path用于保存扫描和分析的结果文件(会有多个),需指向一个空文件夹,若不存在则自动创建。analysing_dir_path用来存储分析过程中的中间状态。分析成功完成后,这个文件夹及其内容就不再有用,可以删除。但它的一个实用价值是:如果某次分析意外中断,通过将analysing_dir_path配置到上次中断时产生的分析文件夹,就可以从断点处恢复继续分析。特别提醒:要开始一个全新的任务时,记得手动删除或清空该文件夹,避免误触中断恢复功能。

分析结束后,将output_dir_path文件夹地址传给以下代码即可生成EPUB文件:

from pdf_craft import generate_epub_file

generate_epub_file(
    from_dir_path=output_dir_path,
    epub_file_path="/path/to/output/epub",
)

这一步会根据之前分析的书本结构在EPUB中分章节,并匹配恰当的目录结构。原本书页底部的注释和引用也会以合适的方式呈现在EPUB中。

功能进阶

前面提到LLM的构建,其实可以添加更多参数来实现更丰富的功能,比如断线重连或指定超时时间:

llm = LLM(
    key="sk-XXXXX",
    url="https://api.deepseek.com",
    model="deepseek-chat",
    token_encoding="o200k_base",
    temperature=0.3,          # 温度(可选)
    timeout=360,               # 超时时间,单位秒(可选)
    retry_times=10,            # 网络原因或格式不完整时,最大重试次数(可选)
    retry_interval_seconds=6.0, # 重试间隔,单位秒(可选)
)

更有意思的一个进阶用法:可以将temperature设置成一个范围。一般运行时使用范围最左边的值作为温度。一旦LLM返回断裂的内容,重试时会逐渐增加温度(不超过范围右边的值)。这样可以有效避免LLM陷入总返回断裂内容的循环。配置示例:

llm = LLM(
    key="sk-XXXXX",
    url="https://api.deepseek.com",
    model="deepseek-chat",
    token_encoding="o200k_base",
    temperature=(0.3, 1.0),   # 温度范围(可选)
)

相关下载