别指望accept-language头让网站返回翻译内容,应先抓原文、检测语言、再批量翻译;需规避短文本检测失败、api限流及html结构破坏等问题。

Accept-Language 头让网站返回翻译后的内容,90% 的多语言站点根本不认这个;真正靠谱的做法是「先抓原文,再检测语言,最后批量翻译」——整个链路必须自己控制。
为什么不能只靠 requests 的 headers 参数切换语言?
Accept-Language: zh-CN 只是告诉服务器“我偏好中文”,但服务器是否响应、响应哪部分、是否动态渲染、有没有对应语言的静态资源,全看它自己。很多小语种站点压根没做内容协商,或者只在 JS 里异步加载翻译后的文案,requests 拿到的 HTML 里全是原始语言。
常见错误现象包括:
- 明明设了
Accept-Language: en,返回的仍是日文页面() - 页面主体是目标语言,但导航栏、页脚还是原始语言
- 用
BeautifulSoup提取文本后发现混杂多种语言,根本没法直接用
langdetect.detect() 识别失败怎么办?
短文本、代码片段、标题、纯数字或符号占比高的内容,langdetect.detect() 容易报 LangDetectException 或返回错误语言码(比如把德语识别成荷兰语)。这不是库的问题,是算法本身的局限。
实操建议:
- 至少凑够 50 字符再检测,太短直接跳过或打上
unknown标签 - 对失败样本加 fallback:用
langid.classify(text)再试一次,两个结果一致才采信 - 如果已知网页主语言(比如
example.com/fr/),优先信任 URL 路径或属性,而非文本检测 - 避免在循环里反复调用
detect(),可提前缓存结果,减少重复计算
批量调用翻译 API 时怎么避免被限流或超时?
逐条请求 Google Translate 或 DeepL API,100 条就要发 100 次 HTTP,既慢又容易触发频率限制。批量不是指“一次传 1000 行”,而是分组+重试+退避。
关键参数和做法:
- 单次请求文本长度控制在 5000 字符以内(Google API 硬上限),超出就切分
- 每组 10–20 条文本打包发送,比单条快 3–5 倍,也更省 token
- 用
requests.Session()复用连接,加timeout=(3, 10)防卡死 - 遇到
429 Too Many Requests,立刻 sleep 1–3 秒再重试,别硬刚 - 本地部署
transformers+opus-mt模型(如helsinki-nlp/opus-mt-en-zh)适合离线、高隐私、中低频场景,但注意显存和推理延迟
翻译后怎么保留原文结构不乱套?
网页文本不是纯段落,常含 HTML 标签、换行、缩进、列表符号。直接对整段 HTML 调用 translate(),会把 <p></p>、<strong></strong> 当普通字符翻成“段落”“粗体”,彻底毁掉结构。
正确做法是:
- 用
BeautifulSoup提取所有文本节点(.get_text()),但记录每个节点的父标签类型和位置索引 - 只翻译纯文本内容,译文再按原位置塞回对应标签内
- 对
@#@#@#@#@#@#@#@#@#@0这类带属性的标签,只翻内部文本,href 不动 - 如果原文有 Markdown 或 JSON 结构(比如 API 返回的富文本字段),先解析再翻译,别图省事直接喂给翻译器
最容易被忽略的一点:翻译后的标点习惯要适配目标语言。比如英文句号后空一格,中文不空;法语冒号前要空格。通用方案是翻译完再跑一遍轻量正则清洗,而不是指望模型自动处理。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











