[应用开发] 用Deepseek翻译一本原版书

[应用开发] 用Deepseek翻译一本原版书

[应用开发] 用Deepseek翻译一本原版书 [应用开发] 用Deepseek翻译一本原版书 Modified December 10, 2025 1638 1754 Code block Python def extract text from pdf(pdf path): try: with pdfplumber.open(pdf path) as pdf: text = "" total pages = len(pdf.pages) logger.info(f"开始从PDF提取文本,共 {total pages} 页") for i, page in enumerate(pdf.pages): page text = page.extract text() or "" text += page text + "\n" 显示进度 if i % 5 == 0 or i == total pages 1: print(show progress bar(i + 1, total pages), end='') print() 换行 logger.info(f"成功从PDF提取文本,长度: {len(text)} 字符") return text except Exception as e: logger.error(f"PDF提取失败: {e}") return "" def save text to docx(text, docx path): try: doc = Document() paragraphs = text.split("\n") for para in paragraphs: if para.strip(): doc.add paragraph(para) doc.save(docx path) logger.info(f"成功保存临时DOCX文件: {docx path}") except Exception as e: logger.error(f"保存DOCX失败: {e}") def extract text from word(word path): try: doc = Document(word path) text = "" for para in doc.paragraphs: if para.text.strip(): text += para.text + "\n" logger.info(f"成功从Word提取文本,长度: {len(text)} 字符") return text except Exception as e: logger.error(f"Word提取失败: {e}") return "" async def translate with deepseek async(paragraphs, api key, api url, api model, temperature=0.3, retries=3, delay=2): """异步版本的deepseek翻译函数""" 改进系统提示以获得更好的翻译 system prompt = """你是一个专业的翻译助手。请将以下英文文本翻译成中文。 要求: 1. 保持专业术语的准确性 2. 确保翻译通顺易读 3. 保留原文的段落结构 4. 对专业术语进行适当解释 5. 确保翻译准确无误,不要遗漏内容 """ paragraph text = "\n".join(paragraphs) messages = [ {"role": "system", "content": system prompt}, {"role": "user", "content": f"请将以下文本翻译成中文:\n\n{paragraph text}"} ] headers = { "Content Type": "application/json", "Authorization": f"Bearer {api key}" } data = { "model": api model, "messages": messages, "temperature": temperature } for attempt in range(retries): try: logger.info(f"正在进行第 {attempt + 1} 次翻译尝试...") async with aiohttp.ClientSession() as session: async with session.post(api url, json=data, headers=headers) as response: if response.status != 200: error text = await response.text() logger.error(f"API响应错误 (HTTP {response.status}): {error text}") raise Exception(f"API响应错误: {response.status}") response json = await response.json() if "choices" not in response json or not response json["choices"]: logger.error(f"API响应格式错误: {response json}") raise Exception("API响应格式错误") translated text = response json["choices"][0]["message"]["content"] preview = translated text[:100] + "..." if len(translated text) 100 else translated text logger.info(f"翻译成功,结果预览: {preview}") return translated text except Exception as e: logger.error(f"翻译请求失败 (尝试 {attempt + 1}): {e}") if attempt < retries 1: logger.info(f"等待 {delay} 秒后重试...") await asyncio.sleep(delay) else: logger.error("所有重试都失败,跳过当前段落") return "" def translate with deepseek(paragraphs, api key, api url, api model, temperature=0.3, retries=3, delay=2): """同步版本的deepseek翻译函数(保留以便兼容)""" 改进系统提示以获得更好的翻译 system prompt = """你是一个专业的翻译助手。请将以下英文文本翻译成中文。 要求: 1. 保持专业术语的准确性 2. 确保翻译通顺易读 3. 保留原文的段落结构 4. 对专业术语进行适当解释 5. 确保翻译准确无误,不要遗漏内容 """ paragraph text = "\n".join(paragraphs) messages = [ {"role": "system", "content": system prompt}, {"role": "user", "content": f"请将以下文本翻译成中文:\n\n{paragraph text}"} ] headers = { "Content Type": "application/json", "Authorization": f"Bearer {api key}" } data = { "model": api model, "messages": messages, "temperature": temperature } for attempt in range(retries): try: logger.info(f"正在进行第 {attempt + 1} 次翻译尝试...") response = requests.post(api url, json=data, headers=headers) response.raise for status() response json = response.json() translated text = response json["choices"][0]["message"]["content"] preview = translated text[:100] + "..." if len(translated text) 100 else translated text logger.info(f"翻译成功,结果预览: {preview}") return translated text except requests.exceptions.RequestException as e: logger.error(f"翻译请求失败 (尝试 {attempt + 1}): {e}") if attempt < retries 1: logger.info(f"等待 {delay} 秒后重试...") time.sleep(delay) else: logger.error("所有重试都失败,跳过当前段落") return "" def save to word(translated texts, output path): """保存翻译结果到Word文档""" try: doc = Document() for text in translated texts: 分割并处理每个段落 paragraphs = text.split('\n') for para in paragraphs: if para.strip(): doc.add paragraph(para.strip()) doc.save(output path) logger.info(f"成功保存翻译结果到: {output path}") logger.info(f"文档包含 {len(translated texts)} 个翻译段落") except Exception as e: logger.error(f"保存翻译结果失败: {e}") def save to word with comparison(original paragraphs, translated texts, output path): """保存原文与翻译对照的Word文档""" try: doc = Document() 添加标题 doc.add heading('翻译对照文档', 0) 确保两个列表长度一致 min length = min(len(original paragraphs), len(translated texts)) for i in range(min length): 添加原文 doc.add heading(f'段落 {i+1} 原文', level=2) orig text = original paragraphs[i] doc.add paragraph(orig text) 添加翻译 doc.add heading(f'段落 {i+1} 翻译', level=2) translation = translated texts[i] paragraphs = translation.split('\n') for para in paragraphs: if para.strip(): doc.add paragraph(para.strip()) 添加分隔线 doc.add paragraph(' ') doc.save(output path) logger.info(f"成功保存翻译对照结果到: {output path}") logger.info(f"文档包含 {min length} 个翻译段落对照") except Exception as e: logger.error(f"保存翻译对照结果失败: {e}") def save progress(processed indices, progress file): """保存翻译进度""" try: os.makedirs(os.path.dirname(progress file), exist ok=True) with open(progress file, "w") as f: json.dump(processed indices, f) logger.info(f"进度保存成功,已处理 {len(processed indices)} 个段落") except Exception as e: logger.error(f"保存进度失败: {e}") def load progress(progress file): """加载翻译进度""" try: if os.path.exists(progress file): with open(progress file, "r") as f: progress = json.load(f) logger.info(f"加载已有进度,已处理 {len(progress)} 个段落") return progress except Exception as e: logger.error(f"加载进度失败: {e}") return [] def split paragraphs improved(text): """改进的段落分割算法,更好地保持语义完整性""" 预处理文本,处理不同类型的换行 text = re.sub(r'\r\n', '\n', text) 分割逻辑 1. 首先按照明显的段落分隔(多个换行) initial splits = re.split(r'\n\s \n', text) paragraphs = [] for split in initial splits: 处理长段落,按句子分割 if len(split.split()) 150: 如果段落太长 sentences = re.split(r'(?<=[.!?])\s+(?=[A Z])', split) 重新组合句子成为合适长度的段落 current para = "" for sentence in sentences: if len(current para.split()) + len(sentence.split()) < 100: current para += " " + sentence if current para else sentence else: paragraphs.append(current para.strip()) current para = sentence if current para: 添加最后一个段落 paragraphs.append(current para.strip()) else: 短段落直接添加 paragraphs.append(split.strip()) 过滤太短的段落或合并到相邻段落 filtered paragraphs = [] for para in paragraphs: para = para.strip() if para and len(para.split()) = 3: 至少有三个单词 filtered paragraphs.append(para) logger.info(f"分段完成,共 {len(filtered paragraphs)} 个有效段落") 增加配置文件支持其他自定义配置,储存为config.py,与主程序在同一文件夹 Code block Python """ 配置文件 """ 文件路径配置 PDF PATH = "C:\\Users\\admin\\Desktop\\Input\\testV1.pdf" 本地文件路径 OUTPUT DIR = "C:\\Users\\admin\\Desktop\\Output" 输出路径 PROGRESS FILE = "C:\\Users\\admin\\Desktop\\Output\\translation progress.json" 翻译进度 其他自定义API配置,如无,则运行默认配置 API KEY = "xxxxx" 你的API密钥 API URL = "xxxxx" API URL API MODEL = "xxxxx" 模型名称 翻译配置 BATCH SIZE = 3 每批处理的段落数量 MAX CONCURRENT REQUESTS = 3 最大并发请求数 TEMPERATURE = 0.3 翻译随机性(0.0 1.0) RETRIES = 3 失败重试次数 RETRY DELAY = 2 重试间隔时间(秒) 分页配置 PARAGRAPHS PER PAGE = 10 每页段落数量 运行主程序开始翻译 尝试制作前端交互 氪了个cursor,把脚本丢给Claude 3.7,补全了前端的UI界面,还有登录系统,挺强的,还在探索中,项目地址 https://github.com/Chaoshcx/PDFTranslate 增加配置文件支持其他自定义配置,储存为config.py,与主程序在同一文件夹 运行主程序开始翻译 尝试制作前端交互 氪了个cursor,把脚本丢给Claude 3.7,补全了前端的UI界面,还有登录系统,挺强的,还在探索中,项目地址 https://github.com/Chaoshcx/PDFTranslate 💡 作者:吵爷 上礼拜Indigo发了一本英文的原版书,因为某些xxx原因,可能国内不会出翻译版本。之前尝试用Deepseek翻译小型段落,在中文语境的表达相当不错,所以做了个尝试,用Deepseek翻译整本原版书。 作者:吵爷 上礼拜Indigo发了一本英文的原版书,因为某些xxx原因,可能国内不会出翻译版本。之前尝试用Deepseek翻译小型段落,在中文语境的表达相当不错,所以做了个尝试,用Deepseek翻译整本原版书。 运行逻辑 通常原始版本都是PDF格式的文件,所以这里就以PDF为原始文件做样本。PDF翻译通常面临一些问题,比如分段逻辑(PDF里的分行是根据边距来的)。所以翻译器做了个基础规则,以标点符号和换行符为依据来获得完整的句子。然后通过句子的叠加来获得段落。(跟原来的段落还是有一些差别,后续会再做一些改进) 前期准备 1. 安装依赖 Python应该都有了,需要提前安装一些依赖 2. API准备 上周正好火山送了50万Token,API就接的火山的,具体获得方式可以参考 🐏 获取字节火山DeepSeek系列 API完整教程,及使用方法,邀请可拿3000万tokens 不过现在不知道还有没有白嫖额度。其实DS的API已经非常便宜了 🐏 获取字节火山DeepSeek系列 API完整教程,及使用方法,邀请可拿3000万tokens 1.0 完整脚本和可变参数(标黄) 注意事项(重要) 有一些原版书会涉及一些敏感内容(比如ZZ相关),国内的大模型有比较多的过滤机制,这部分内容是DS处理不了的。碰到这种可以转移去Grok或者其他模型,这里就不具体说了,大家可以自己魔改 也欢迎找我聊优化建议。 一些潜在优化项 • 关于敏感话题:当输出不成功时,可以选择调用Grok或者其他境外模型做备选(比如捕获关键字段来判断) • 关于排版,现在是按照标点来排版,转成word以后,可以获取段落换行符作为辅助(不过实测中英文的分段习惯可能不大一样,这个看具体需求) • 关于一些分栏的格式(论文期刊比较多,这个过两天空了会试一试) 1.1 版本更新 这个版本用claude 3.7做了一次优化(强的变态): • 异步翻译处理:多个段落同时翻译,大幅提高效率 • 原文 翻译对照模式:可以生成包含原文和翻译的对照文档 • 改进的分段算法:更智能地分割文本,保持语义完整性 • 进度条显示:展示处理进度 • 日志系统:记录翻译过程与错误 • 配置文件支持:自定义各项参数 • 命令行参数:灵活控制翻译行为 • 错误处理增强:更好地应对各种异常情况 主程序文件:比如保存为 translate book.py

在 小宇宙note 阅读完整内容