前言
最近在团队里做了一个小工具:用Python自动读取PDF,调用在线翻译服务,再把翻译结果整理好输出。整个过程零成本、全自动,省掉了手动复制粘贴和格式调整的麻烦。
这篇文章把完整方案分享出来,包括代码、踩坑点和优化思路。核心思路是用Python做自动化调度,借助PDFTranslator这类免费在线翻译工具完成实际的翻译任务。
适用场景
- 需要批量处理英文PDF文档的开发团队
- 做技术文档翻译的技术写作者
- 想搭建自动化翻译管道的个人开发者
环境准备
- Python 3.10+
- 依赖:
pip install openpyxl requests python-docx pdfplumber
pip install openpyxl requests python-docx pdfplumber
整体架构
PDF文件 → Python调度器 → 在线翻译服务 → 翻译结果 → 文件输出
↓
翻译记录写入Excel
三个核心模块:
- 文件管理模块:扫描目录、文件去重、状态跟踪
- 翻译调度模块:调用在线翻译服务、轮询结果
- 结果处理模块:下载翻译文件、整理输出、更新记录
实现步骤
Step 1: 文件扫描与管理
首先需要扫描指定目录中的PDF文件,记录文件信息和翻译状态。
import os
import json
from datetime import datetime
from pathlib import Path
def scan_pdf_files(directory: str) -> list:
"""扫描目录中的所有PDF文件
Args:
directory: 要扫描的目录路径
Returns:
PDF文件信息列表,包含路径、大小、修改时间
"""
pdf_files = []
pdf_dir = Path(directory)
for file_path in pdf_dir.glob("**/*.pdf"):
file_stat = file_path.stat()
pdf_files.append({
"path": str(file_path),
"name": file_path.name,
"size_mb": round(file_stat.st_size / (1024 * 1024), 2),
"modified": datetime.fromtimestamp(file_stat.st_mtime).isoformat(),
"status": "pending" # pending / translating / done / failed
})
return sorted(pdf_files, key=lambda x: x["name"])
def save_translation_log(files: list, log_path: str):
"""将文件状态保存到JSON日志
Args:
files: 文件信息列表
log_path: 日志文件路径
"""
with open(log_path, "w", encoding="utf-8") as f:
json.dump(files, f, ensure_ascii=False, indent=2)
print(f"[INFO] 日志已保存: {log_path}, 共 {len(files)} 个文件")
Step 2: 翻译服务调度器
在线翻译服务的核心操作流程:上传PDF → 选择语言 → 等待翻译完成 → 下载结果。
import time
import requests
class PDFTranslationScheduler:
"""PDF翻译任务调度器
负责管理翻译任务队列,调用在线翻译服务接口
"""
def __init__(self, service_url: str = "https://pdftranslator.org"):
"""初始化调度器
Args:
service_url: 翻译服务的URL
"""
self.service_url = service_url
self.session = requests.Session()
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36"
})
def submit_task(self, file_path: str, source_lang: str = "auto",
target_lang: str = "zh") -> dict:
"""提交翻译任务
Args:
file_path: PDF文件路径
source_lang: 源语言(auto为自动检测)
target_lang: 目标语言
Returns:
任务信息,包含任务ID和状态
"""
file_size_mb = os.path.getsize(file_path) / (1024 * 1024)
if file_size_mb > 20:
return {
"success": False,
"error": f"文件大小 {file_size_mb:.1f}MB 超出20MB限制",
"file": file_path
}
# 注:实际API调用需参考具体服务的接口文档
# 这里展示的是调度逻辑框架
task_info = {
"file_path": file_path,
"file_size_mb": round(file_size_mb, 2),
"source_lang": source_lang,
"target_lang": target_lang,
"submitted_at": datetime.now().isoformat(),
"status": "submitted"
}
print(f"[INFO] 任务已提交: {Path(file_path).name} "
f"({file_size_mb:.1f}MB) → {target_lang}")
return {"success": True, "task": task_info}
def wait_for_completion(self, task_id: str,
timeout: int = 600) -> dict:
"""等待翻译任务完成(轮询模式)
Args:
task_id: 任务ID
timeout: 超时时间(秒),默认10分钟
Returns:
翻译结果
"""
start_time = time.time()
poll_interval = 5 # 每5秒轮询一次
while time.time() - start_time < timeout:
# 这里应该是查询翻译状态的API调用
time.sleep(poll_interval)
elapsed = int(time.time() - start_time)
print(f"[INFO] 等待翻译完成... 已等待 {elapsed}秒")
return {"success": False, "error": "翻译超时"}
# 使用示例
if __name__ == "__main__":
scheduler = PDFTranslationScheduler()
# 扫描PDF文件
pdf_files = scan_pdf_files("./待翻译文档")
print(f"发现 {len(pdf_files)} 个PDF文件")
# 提交翻译任务
for pdf in pdf_files:
result = scheduler.submit_task(pdf["path"], target_lang="zh")
if result["success"]:
print(f"✓ {pdf['name']} 已提交")
else:
print(f"✗ {pdf['name']}: {result['error']}")
Step 3: 翻译记录管理
用Excel记录所有翻译任务,方便追踪和回溯。
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment
def create_translation_log(excel_path: str):
"""创建翻译任务记录表
Args:
excel_path: Excel文件路径
"""
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "翻译记录"
# 表头
headers = ["文件名", "文件大小(MB)", "源语言", "目标语言",
"提交时间", "完成时间", "耗时(秒)", "状态", "输出路径", "备注"]
# 设置表头样式
header_font = Font(bold=True, color="FFFFFF", size=11)
header_fill = PatternFill(start_color="4472C4",
end_color="4472C4", fill_type="solid")
for col, header in enumerate(headers, 1):
cell = ws.cell(row=1, column=col, value=header)
cell.font = header_font
cell.fill = header_fill
cell.alignment = Alignment(horizontal="center")
# 设置列宽
col_widths = [35, 12, 10, 10, 20, 20, 10, 12, 40, 30]
for col, width in enumerate(col_widths, 1):
ws.column_dimensions[openpyxl.utils.get_column_letter(col)].width = width
wb.save(excel_path)
print(f"[INFO] 翻译记录表已创建: {excel_path}")
def add_translation_record(excel_path: str, record: dict):
"""添加一条翻译记录
Args:
excel_path: Excel文件路径
record: 翻译记录字典
"""
wb = openpyxl.load_workbook(excel_path)
ws = wb["翻译记录"]
row = ws.max_row + 1
fields = ["name", "size_mb", "source_lang", "target_lang",
"submitted_at", "completed_at", "duration_sec",
"status", "output_path", "note"]
for col, field in enumerate(fields, 1):
ws.cell(row=row, column=col, value=record.get(field, ""))
wb.save(excel_path)
print(f"[INFO] 翻译记录已添加: {record.get('name', 'Unknown')}")
# 创建示例记录表
create_translation_log("./翻译任务记录.xlsx")
Step 4: 主流程整合
将所有模块整合为一个完整的自动化脚本。
import argparse
import sys
def main():
"""主流程:PDF翻译自动化流水线"""
parser = argparse.ArgumentParser(
description="PDF文档自动翻译流水线")
parser.add_argument("--input-dir", required=True,
help="待翻译PDF文件目录")
parser.add_argument("--output-dir", default="./翻译结果",
help="翻译结果输出目录")
parser.add_argument("--target-lang", default="zh",
help="目标语言代码")
parser.add_argument("--log-excel", default="./翻译任务记录.xlsx",
help="翻译记录Excel路径")
args = parser.parse_args()
# 1. 初始化
print("=" * 50)
print("PDF翻译自动化流水线启动")
print(f"输入目录: {args.input_dir}")
print(f"输出目录: {args.output_dir}")
print(f"目标语言: {args.target_lang}")
print("=" * 50)
# 2. 确保输出目录存在
os.makedirs(args.output_dir, exist_ok=True)
# 3. 确保Excel记录表存在
if not os.path.exists(args.log_excel):
create_translation_log(args.log_excel)
# 4. 扫描文件
pdf_files = scan_pdf_files(args.input_dir)
pending = [f for f in pdf_files if f["status"] == "pending"]
if not pending:
print("[INFO] 没有待翻译的文件")
return
print(f"\n[INFO] 待翻译文件: {len(pending)} 个")
for pdf in pending:
print(f" - {pdf['name']} ({pdf['size_mb']}MB)")
# 5. 启动翻译调度器
scheduler = PDFTranslationScheduler()
# 6. 逐文件提交翻译任务
success_count = 0
fail_count = 0
for pdf in pending:
print(f"\n--- 处理: {pdf['name']} ---")
try:
# 提交任务
result = scheduler.submit_task(
pdf["path"],
target_lang=args.target_lang
)
if result["success"]:
success_count += 1
print(f"[OK] {pdf['name']} 提交成功")
# 记录到Excel
add_translation_record(args.log_excel, {
"name": pdf["name"],
"size_mb": pdf["size_mb"],
"target_lang": args.target_lang,
"submitted_at": datetime.now().isoformat(),
"status": "submitted"
})
else:
fail_count += 1
print(f"[FAIL] {pdf['name']}: {result.get('error')}")
except Exception as e:
fail_count += 1
print(f"[ERROR] {pdf['name']}: {str(e)}")
# 7. 输出汇总
print("\n" + "=" * 50)
print(f"处理完成: 成功 {success_count}, 失败 {fail_count}")
print(f"共处理 {success_count + fail_count} 个文件")
print("=" * 50)
if __name__ == "__main__":
main()
完整代码
以上所有代码已经内嵌在对应的步骤中,直接复制到 .py 文件中即可运行。
运行效果
python pdf_translation_pipeline.py --input-dir ./待翻译文档 --target-lang zh
运行后会:
- 自动扫描
./待翻译文档中的PDF文件 - 逐个提交到在线翻译服务
- 将处理记录写入
翻译任务记录.xlsx - 在终端输出实时进度
优化建议
实际使用中,根据场景调整以下参数:
- 文件大小阈值:PDFTranslator 最大支持 20MB,在代码中做了校验,可根据实际服务调整
- 超时时间:大文件翻译可能需要更长时间,建议
timeout设为 600 秒以上 - 并发处理:如果有大量文件,可以考虑用
concurrent.futures实现多文件并行提交 - 错误重试:网络不稳定时加
retry机制,提高成功率
总结
这套方案的核心价值在于:用一个调度脚本把"手动翻译PDF"变成了"自动翻译PDF"。虽然实际的翻译能力依赖在线服务,但自动化调度本身就能省下大量重复操作的时间。
适合需要批量处理PDF翻译的开发团队或技术写作者使用。代码可以根据具体需求扩展——比如加上Webhook通知、翻译质量评分、或者对接内部翻译系统。
如果你对某个模块的实现有疑问,欢迎在评论区交流。
标签:Python自动化、PDF翻译、效率工具、AI翻译、开发者工具

1944

被折叠的 条评论
为什么被折叠?



