我的博客

分享技术与思想的点滴

数学相关PDF一步到位脚本(分页 + 转换一体化)

这个需求很实用。分页处理大 PDF 可以避免内存爆炸,也方便后续按章节处理。

我提供一套完整的两步走方案:先用 Python 切分 PDF,再批量转 HTML。


第一步:将大 PDF 按页拆分

#!/usr/bin/env python3
"""
split_pdf.py - 将大 PDF 按页拆分成单页文件
用法: python split_pdf.py 48.pdf --output_dir pages
"""

import fitz  # PyMuPDF
import os
import argparse

def split_pdf(input_pdf, output_dir="pages"):
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)

    doc = fitz.open(input_pdf)
    total_pages = len(doc)

    for page_num in range(total_pages):
        # 创建新 PDF,只包含当前页
        new_doc = fitz.open()
        new_doc.insert_pdf(doc, from_page=page_num, to_page=page_num)

        # 保存为 页码_原文件名.pdf
        base_name = os.path.splitext(os.path.basename(input_pdf))[0]
        output_path = os.path.join(output_dir, f"{base_name}_p{page_num+1:03d}.pdf")
        new_doc.save(output_path)
        new_doc.close()

        print(f"已生成: {output_path}")

    doc.close()
    print(f"\n✅ 完成!共拆分 {total_pages} 页,保存在 '{output_dir}' 目录")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="拆分 PDF 为单页文件")
    parser.add_argument("input", help="输入的 PDF 文件")
    parser.add_argument("--output_dir", default="pages", help="输出目录(默认: pages)")
    args = parser.parse_args()

    split_pdf(args.input, args.output_dir)

运行:

python split_pdf.py 48.pdf --output_dir pages_48

第二步:批量转换单页 PDF 为 HTML

方案 A:Docling 批量转换(推荐,公式渲染好)

#!/bin/bash
# batch_docling.sh - 批量用 Docling 转 HTML

INPUT_DIR="pages_48"
OUTPUT_DIR="html_48"

mkdir -p "$OUTPUT_DIR"

for pdf in "$INPUT_DIR"/*.pdf; do
    filename=$(basename "$pdf" .pdf)
    echo "转换: $filename"
    docling "$pdf" --to html --output "$OUTPUT_DIR/$filename.html"
done

echo "✅ 批量转换完成!"

Windows 批处理版本(batch_docling.bat):

@echo off
set INPUT_DIR=pages_48
set OUTPUT_DIR=html_48

if not exist "%OUTPUT_DIR%" mkdir "%OUTPUT_DIR%"

for %%f in (%INPUT_DIR%\*.pdf) do (
    echo 转换: %%~nf
    docling "%%f" --to html --output "%OUTPUT_DIR%\%%~nf.html"
)

echo 完成!
pause

方案 B:Pandoc 批量转换(更灵活,支持模板)

如果 Docling 的 HTML 样式不合心意,可以用 Pandoc 二次加工:

#!/bin/bash
# batch_pandoc.sh

INPUT_DIR="pages_48"
OUTPUT_DIR="html_48_pandoc"

mkdir -p "$OUTPUT_DIR"

for pdf in "$INPUT_DIR"/*.pdf; do
    filename=$(basename "$pdf" .pdf)
    echo "转换: $filename"

    # 先 PDF -> LaTeX -> HTML(保公式)
    docling "$pdf" --to latex --output temp.tex
    pandoc temp.tex -o "$OUTPUT_DIR/$filename.html" --mathjax --standalone
    rm temp.tex
done

echo "✅ 完成!"

一步到位脚本(分页 + 转换一体化)

如果你懒得手动两步走,这里有一个全自动 Python 脚本

#!/usr/bin/env python3
"""
pdf_to_html_batch.py - 分页 + 批量转 HTML 一体化
用法: python pdf_to_html_batch.py 48.pdf
"""

import fitz
import os
import subprocess
import argparse
import tempfile

def process_large_pdf(input_pdf, output_dir="html_output", method="docling"):
    os.makedirs(output_dir, exist_ok=True)

    doc = fitz.open(input_pdf)
    total_pages = len(doc)
    base_name = os.path.splitext(os.path.basename(input_pdf))[0]

    with tempfile.TemporaryDirectory() as tmpdir:
        for page_num in range(total_pages):
            # 1. 提取单页
            new_doc = fitz.open()
            new_doc.insert_pdf(doc, from_page=page_num, to_page=page_num)
            page_pdf = os.path.join(tmpdir, f"p{page_num+1:03d}.pdf")
            new_doc.save(page_pdf)
            new_doc.close()

            # 2. 转换为 HTML
            html_output = os.path.join(output_dir, f"{base_name}_p{page_num+1:03d}.html")

            if method == "docling":
                subprocess.run([
                    "docling", page_pdf, "--to", "html", "--output", html_output
                ], capture_output=True)
            elif method == "pandoc":
                # Docling -> LaTeX -> Pandoc -> HTML
                tex_output = os.path.join(tmpdir, f"p{page_num+1:03d}.tex")
                subprocess.run(["docling", page_pdf, "--to", "latex", "--output", tex_output])
                subprocess.run([
                    "pandoc", tex_output, "-o", html_output, 
                    "--mathjax", "--standalone"
                ])

            print(f"进度: {page_num+1}/{total_pages} -> {html_output}")

    doc.close()
    print(f"\n✅ 全部完成!HTML 文件保存在 '{output_dir}' 目录")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="大 PDF 分页转 HTML")
    parser.add_argument("input", help="输入 PDF")
    parser.add_argument("--output", default="html_output", help="输出目录")
    parser.add_argument("--method", choices=["docling", "pandoc"], default="docling")
    args = parser.parse_args()

    process_large_pdf(args.input, args.output, args.method)

使用:

# 一键处理
python pdf_to_html_batch.py 48.pdf --output html_48

# 使用 Pandoc 精细模式
python pdf_to_html_batch.py 48.pdf --method pandoc

最终建议

你的 48.pdf 大小 推荐策略
< 50 页 直接用 Docling 整体转换,不用分页
50-200 页 用一体化脚本分页转(防内存溢出)
> 200 页 先分页,再并行转换(多开几个终端窗口)

如果你的 48.pdf 页数特别多(比如 500+),我还可以帮你写一个多进程并行版本,速度能快 4-8 倍。需要吗?