在处理大型PDF文档翻译时,直接上传整份文件有时会遇到超时、内存占用高或部分页面格式异常的问题。一个实用的思路是:先把PDF按页拆分成小文件,逐个翻译,最后再把结果合并起来。这篇文章分享一个基于Python的完整流水线实现,代码可直接运行。

前言

我之前翻译过一份300多页的产品手册,直接上传整份PDF时遇到了两个问题:

  1. 翻译时间过长,HTTP连接超时;
  2. 中间某一页格式复杂,导致整份文档的排版都受影响。

后来改成"拆分-翻译-合并"的流水线方式,稳定性和成功率都明显提升。这个方案特别适合:

  • 超过100页的大文档;
  • 页面版式差异较大的混合文档;
  • 需要部分页面单独处理的场景。

环境准备

pip install pypdf requests

完整代码

import os
import time
import requests
from pathlib import Path
from pypdf import PdfReader, PdfWriter

UPLOAD_DIR = Path("uploads")
SPLIT_DIR = Path("split")
TRANS_DIR = Path("translated")
MERGE_DIR = Path("merged")

for d in [UPLOAD_DIR, SPLIT_DIR, TRANS_DIR, MERGE_DIR]:
    d.mkdir(exist_ok=True)

API_URL = "https://api.example.com/translate"
API_KEY = "your_api_key"


def split_pdf(input_path: str, chunk_size: int = 10):
    """按chunk_size页拆分PDF"""
    reader = PdfReader(input_path)
    total = len(reader.pages)
    chunks = []

    for start in range(0, total, chunk_size):
        writer = PdfWriter()
        end = min(start + chunk_size, total)
        for i in range(start, end):
            writer.add_page(reader.pages[i])

        chunk_path = SPLIT_DIR / f"chunk_{start+1}_{end}.pdf"
        with open(chunk_path, "wb") as f:
            writer.write(f)
        chunks.append(str(chunk_path))

    return chunks


def translate_pdf(pdf_path: str, source_lang="auto", target_lang="zh"):
    """调用翻译API翻译单个PDF"""
    with open(pdf_path, "rb") as f:
        resp = requests.post(
            API_URL,
            files={"file": f},
            data={
                "source_lang": source_lang,
                "target_lang": target_lang,
                "api_key": API_KEY,
            },
            timeout=120,
        )

    if resp.status_code != 200:
        raise RuntimeError(f"Translation failed: {resp.text}")

    # 假设API返回下载链接
    result = resp.json()
    download_url = result.get("download_url")

    # 下载翻译后的文件
    file_name = Path(pdf_path).stem + "_translated.pdf"
    output_path = TRANS_DIR / file_name

    r = requests.get(download_url, timeout=60)
    with open(output_path, "wb") as f:
        f.write(r.content)

    return str(output_path)


def merge_pdfs(pdf_paths: list, output_path: str):
    """合并多个PDF文件"""
    writer = PdfWriter()
    for p in pdf_paths:
        reader = PdfReader(p)
        for page in reader.pages:
            writer.add_page(page)

    with open(output_path, "wb") as f:
        writer.write(f)


def process_pdf(input_path: str, chunk_size: int = 10):
    """完整流水线:拆分 -> 翻译 -> 合并"""
    print(f"[1/4] 开始拆分: {input_path}")
    chunks = split_pdf(input_path, chunk_size)
    print(f"[2/4] 拆分为 {len(chunks)} 个子文件")

    translated = []
    for idx, chunk in enumerate(chunks, 1):
        print(f"[3/4] 正在翻译第 {idx}/{len(chunks)} 个子文件...")
        try:
            out = translate_pdf(chunk)
            translated.append(out)
        except Exception as e:
            print(f"第 {idx} 个子文件翻译失败: {e}")
            # 失败时保留原文,避免合并缺失
            translated.append(chunk)
        time.sleep(1)

    output_name = MERGE_DIR / f"{Path(input_path).stem}_final.pdf"
    print(f"[4/4] 合并结果到: {output_name}")
    merge_pdfs(translated, str(output_name))

    return str(output_name)


if __name__ == "__main__":
    pdf_file = UPLOAD_DIR / "manual.pdf"
    if not pdf_file.exists():
        print(f"请把待翻译PDF放到: {pdf_file}")
    else:
        result = process_pdf(str(pdf_file), chunk_size=10)
        print(f"完成: {result}")

代码说明

split_pdf:使用pypdf按指定页数拆分PDF,生成多个小文件。chunk_size可根据实际情况调整,通常10-20页一组比较均衡。

translate_pdf:调用翻译API,上传单个PDF并下载翻译后的文件。示例假设API返回download_url,实际接口请根据具体情况调整。

merge_pdfs:使用pypdf按顺序合并所有翻译后的子文件。

process_pdf:主流程,包含错误处理——如果某个子文件翻译失败,保留原文件继续合并,避免整份文档作废。

注意事项

  1. 拆分后的页眉页脚:如果原文页眉页脚包含页码,拆分翻译合并后页码可能不连续。可以在合并后重新生成页眉页脚,或者在上传时选择保留原页眉页脚的翻译模式。

  2. 跨页表格:如果表格跨页存在,拆分后可能出现表格被截断的情况。建议先检查文档结构,对跨页表格做合并处理。

  3. 批注和书签:pypdf默认不会保留书签大纲,如果文档有目录,合并后需要重新添加。

  4. API调用频率:批量上传时注意控制频率,避免触发限流。示例中每次翻译后sleep 1秒,可根据接口限制调整。

优化方向

  • 使用线程池并行翻译多个子文件,缩短总耗时;
  • 引入任务队列(如Celery),支持断点续传;
  • 对翻译失败的分片支持单独重试;
  • 增加文件MD5校验,避免重复翻译。

总结

"拆分-翻译-合并"是一种务实的大文档处理策略,尤其适合几百页的PDF翻译场景。它不能完全替代整篇翻译,但在稳定性、失败容忍度和处理效率上都有明显优势。配合合适的翻译API,这条流水线可以无缝融入现有的文档处理系统中。

标签:PDF翻译、Python自动化、AI翻译、文档处理、效率工具

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐