
有道翻译非官方API文档(基于逆向工程)
版本: 1.0
适用范围: 中英互译、流式翻译结果拼接、翻译对齐信息获取
重要提示: 本文档描述的接口并非官方公开API,仅供学习研究使用。使用前请确保遵守有道翻译服务条款。
1. 概述
该API模拟有道翻译Web端(https://fanyi.youdao.com)的行为,通过三个连续步骤完成翻译:获取Token/SecretKey → 流式翻译(SSE) → 增强翻译(返回对齐信息)。整个流程依赖JavaScript加密函数生成动态签名。
2. 前置准备
2.1 环境依赖
- Python 3.6+
- 依赖库:
requests,execjs,urllib - JavaScript运行时(如Node.js)用于执行加密脚本
- 加密脚本文件:
encrypt.js(需从有道翻译Web端逆向获取)
2.2 固定Cookie与Headers
以下Cookie和Header字段在请求中基本保持不变,但实际使用时请替换为您自己浏览器中的有效值,并注意脱敏。
cookies = {
'OUTFOX_SEARCH_USER_ID': '1884948652@223.73.16.63', # 示例,已脱敏
'OUTFOX_SEARCH_USER_ID_NCOO': '1463695026.302421',
'_uetsid': 'd45262404eda11f1bcdcb1....',
'_uetvid': 'd452d1804eda11f19c77dd....',
'DICT_DOCTRANS_SESSION_ID': 'ZmFhZjM3MTMtNjRmYy00Z....', # 会话ID,会定期失效
}
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Origin': 'https://fanyi.youdao.com',
'Referer': 'https://fanyi.youdao.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36',
'sec-ch-ua': '"Google Chrome";v="147", "Not.A/Brand";v="8", "Chromium";v="147"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
}
2.3 加密函数说明
需要实现三个加密函数(具体逻辑请从有道翻译Web端静态文件逆向获得):
encrypt(mysticTime)– 用于获取Token接口的签名,返回[sign, pointParam]encrypt2(mysticTime, encodedWord, secretKey, token)– 用于流式翻译接口的签名,返回[sign, pointParam]encrypt3(secretKey, token, mysticTime)– 用于增强翻译接口的签名,返回[sign, pointParam]
所有时间戳 mysticTime 均为毫秒级整数(例如 int(time.time() * 1000))。
3. 接口列表
3.1 获取Token与SecretKey
该接口用于初始化翻译会话,返回后续请求所需的 token 和 secretKey。
请求信息
- URL:
https://dict-trans.youdao.com/translate/key - 方法: POST
- Content-Type: 无请求体(空POST)
URL参数
| 参数名 | 类型 | 必选 | 说明 |
|---|---|---|---|
| product | string | 是 | 固定值 webfanyi |
| appVersion | string | 是 | 固定值 12.0.0 |
| client | string | 是 | 固定值 webmain |
| mid | string | 是 | 固定值 1 |
| vendor | string | 是 | 固定值 web |
| screen | string | 是 | 固定值 1 |
| model | string | 是 | 固定值 1 |
| imei | string | 是 | 固定值 1 |
| network | string | 是 | 固定值 wifi |
| keyfrom | string | 是 | 固定值 webfanyi.webmain |
| keyid | string | 是 | 固定值 translate-webmain-key-getter |
| mysticTime | int | 是 | 当前毫秒时间戳 |
| yduuid | string | 是 | 固定值 07a53194756be08bdd18ce11e49fb147 |
| abtest | string | 是 | 固定值 0 |
| targetKeyid | string | 是 | 固定值 translate-webfanyi-webmain |
| sign | string | 是 | 由 encrypt(mysticTime) 生成的签名 |
| pointParam | string | 是 | 固定字符串:abtest,appVersion,client,imei,keyfrom,keyid,mid,model,mysticTime,network,product,screen,targetKeyid,vendor,yduuid,key |
请求示例(Python)
import time, execjs
import requests
ctx = execjs.compile(open("encrypt.js", encoding='utf-8').read())
t1 = int(time.time() * 1000)
sign = ctx.call('encrypt', t1)[0]
url = f'https://dict-trans.youdao.com/translate/key?product=webfanyi&appVersion=12.0.0&client=webmain&mid=1&vendor=web&screen=1&model=1&imei=1&network=wifi&keyfrom=webfanyi.webmain&keyid=translate-webmain-key-getter&mysticTime={t1}&yduuid=07a53194756be08bdd18ce11e49fb147&abtest=0&targetKeyid=translate-webfanyi-webmain&sign={sign}&pointParam=abtest,appVersion,client,imei,keyfrom,keyid,mid,model,mysticTime,network,product,screen,targetKeyid,vendor,yduuid,key'
response = requests.post(url, cookies=cookies, headers=headers)
data = response.json()
token = data['data']['token']
secretKey = data['data']['secretKey']
响应示例
{
"code": 0,
"msg": "OK",
"data": {
"secretKey": "BdCYRtHAJxO7yNm9RHwU....", // 示例,已脱敏
"token": "62d9f6631d4f4dc8b77128ac...."
}
}
3.2 流式翻译(SSE)
该接口以Server-Sent Events(SSE)格式返回翻译结果,响应为文本流,每次更新部分译文(transIncre字段)。需要解析所有 event:message 中的 transIncre 并拼接。
请求信息
- URL:
https://dict-trans.youdao.com/webtranslate/sse - 方法: POST
- Content-Type:
multipart/form-data(由requests库自动生成boundary)
表单字段
所有字段均为字符串类型,且必须按照以下顺序和名称提交:
| 字段名 | 必选 | 示例/固定值 | 说明 |
|---|---|---|---|
| product | 是 | webfanyi | 固定 |
| appVersion | 是 | 1 | 固定为字符串”1″ |
| client | 是 | webmain | 固定 |
| mid | 是 | 1 | 固定 |
| vendor | 是 | web | 固定 |
| screen | 是 | 1 | 固定 |
| model | 是 | 1 | 固定 |
| imei | 是 | 1 | 固定 |
| network | 是 | wifi | 固定 |
| keyfrom | 是 | webfanyi.webmain | 固定 |
| keyid | 是 | translate-webfanyi-webmain | 固定 |
| mysticTime | 是 | 当前毫秒时间戳 | 整数转字符串 |
| yduuid | 是 | 07a53194756be08bdd18c…. | 固定 |
| modelName | 是 | llmLite | 固定 |
| useTerm | 是 | false | 固定 |
| i | 是 | URL编码后的原文 | 例如 %E6%89%8B%E6%9C%BA |
| from | 是 | zh-CHS | 源语言(中文) |
| to | 是 | en | 目标语言(英文) |
| signSecretKey | 是 | 从上一接口获得的secretKey | 明文 |
| keyId | 是 | translate-webfanyi-webmain | 固定 |
| token | 是 | 从上一接口获得的token | 明文 |
| source | 是 | webmain | 固定 |
| sign | 是 | 签名 | 由 encrypt2(mysticTime, i, secretKey, token) 生成 |
| pointParam | 是 | 固定字符串 | appVersion,client,from,i,imei,keyId,keyfrom,keyid,mid,model,modelName,mysticTime,network,product,screen,signSecretKey,source,to,token,useTerm,vendor,yduuid,key |
请求示例(Python)
t2 = int(time.time() * 1000)
word_cn = "手机"
word = urllib.parse.quote(word_cn)
sign2 = ctx.call('encrypt2', t2, word, secretKey, token)[0]
files = {
'product': (None, 'webfanyi'),
'appVersion': (None, '1'),
'client': (None, 'webmain'),
'mid': (None, '1'),
'vendor': (None, 'web'),
'screen': (None, '1'),
'model': (None, '1'),
'imei': (None, '1'),
'network': (None, 'wifi'),
'keyfrom': (None, 'webfanyi.webmain'),
'keyid': (None, 'translate-webfanyi-webmain'),
'mysticTime': (None, t2),
'yduuid': (None, '07a53194756be08bdd18ce11....'),
'modelName': (None, 'llmLite'),
'useTerm': (None, 'false'),
'i': (None, word),
'from': (None, 'zh-CHS'),
'to': (None, 'en'),
'signSecretKey': (None, secretKey),
'keyId': (None, 'translate-webfanyi-webmain'),
'token': (None, token),
'source': (None, 'webmain'),
'sign': (None, sign2),
'pointParam': (None, 'appVersion,client,from,i,imei,keyId,keyfrom,keyid,mid,model,modelName,mysticTime,network,product,screen,signSecretKey,source,to,token,useTerm,vendor,yduuid,key'),
}
response = requests.post('https://dict-trans.youdao.com/webtranslate/sse', cookies=cookies, headers=headers, files=files)
响应处理(SSE解析)
响应为文本流,格式如下:
id:179a8cd9-99be-423f-8262-6574312a00bd
event:begin
data:{"requestId":"...","type":"zh-CHS2en"}
retry:3000
id:179a8cd9-99be-423f-8262-6574312a00bd
event:message
data:{"transIncre":"M"}
retry:3000
id:179a8cd9-99be-423f-8262-6574312a00bd
event:message
data:{"transIncre":"obile phon"}
retry:3000
...
event:end
提取所有 event:message 中的 transIncre 字段并拼接即可得到完整译文。
def extract_translation_from_sse(sse_text):
import re
pattern = r'"transIncre":"([^"]*)"'
fragments = re.findall(pattern, sse_text)
return ''.join(fragments)
result = extract_translation_from_sse(response.text) # 返回 "Mobile phone"
3.3 增强翻译(提交原文+译文)
将原始文本和从流式翻译得到的完整译文提交至该接口,返回对齐信息(alignData),可用于词级或短语级对齐。
请求信息
- URL:
https://dict-trans.youdao.com/translate/enhance - 方法: POST
- Content-Type:
multipart/form-data
表单字段
| 字段名 | 必选 | 示例/固定值 | 说明 |
|---|---|---|---|
| srcArticle | 是 | 原文(未编码) | 例如 手机 |
| tgtArticle | 是 | 译文(完整) | 例如 Mobile phone |
| from | 是 | zh-CHS | 源语言 |
| to | 是 | en | 目标语言 |
| product | 是 | webfanyi | 固定 |
| appVersion | 是 | 12.0.0 | 固定 |
| client | 是 | webmain | 固定 |
| mid | 是 | 1 | 固定 |
| vendor | 是 | web | 固定 |
| screen | 是 | 1 | 固定 |
| model | 是 | 1 | 固定 |
| imei | 是 | 1 | 固定 |
| network | 是 | wifi | 固定 |
| keyfrom | 是 | webfanyi.webmain | 固定 |
| keyid | 是 | translate-webfanyi-webmain | 固定 |
| mysticTime | 是 | 当前毫秒时间戳 | 整数转字符串 |
| yduuid | 是 | 07a53194756be08bdd18ce1…. | 固定 |
| abtest | 是 | 0 | 固定 |
| signSecretKey | 是 | secretKey | 明文 |
| keyId | 是 | translate-webfanyi-webmain | 固定 |
| token | 是 | token | 明文 |
| source | 是 | webmain | 固定 |
| sign | 是 | 签名 | 由 encrypt3(secretKey, token, mysticTime) 生成 |
| pointParam | 是 | 固定字符串 | abtest,appVersion,client,imei,keyId,keyfrom,keyid,mid,model,mysticTime,network,product,screen,signSecretKey,source,token,vendor,yduuid,key |
请求示例(Python)
t3 = int(time.time() * 1000)
sign3 = ctx.call('encrypt3', secretKey, token, t3)[0]
files = {
'srcArticle': (None, word_cn), # 原文原始字符串
'tgtArticle': (None, result), # 完整译文
'from': (None, 'zh-CHS'),
'to': (None, 'en'),
'product': (None, 'webfanyi'),
'appVersion': (None, '12.0.0'),
'client': (None, 'webmain'),
'mid': (None, '1'),
'vendor': (None, 'web'),
'screen': (None, '1'),
'model': (None, '1'),
'imei': (None, '1'),
'network': (None, 'wifi'),
'keyfrom': (None, 'webfanyi.webmain'),
'keyid': (None, 'translate-webfanyi-webmain'),
'mysticTime': (None, t3),
'yduuid': (None, '07a53194756be08bdd18ce1....'),
'abtest': (None, '0'),
'signSecretKey': (None, secretKey),
'keyId': (None, 'translate-webfanyi-webmain'),
'token': (None, token),
'source': (None, 'webmain'),
'sign': (None, sign3),
'pointParam': (None, 'abtest,appVersion,client,imei,keyId,keyfrom,keyid,mid,model,mysticTime,network,product,screen,signSecretKey,source,token,vendor,yduuid,key'),
}
response = requests.post('https://dict-trans.youdao.com/translate/enhance', cookies=cookies, headers=headers, files=files)
print(response.json())
响应示例
{
"code": 0,
"msg": "OK",
"data": {
"alignData": [
{
"src": "手机",
"tgt": "Mobile phone"
}
]
}
}
4. 错误处理
所有接口响应均包含 code 字段,非0表示失败。常见错误码:
| 错误码 | 含义 | 可能原因及解决办法 |
|---|---|---|
| 0 | 成功 | – |
| 101 | 签名错误 | 时间戳不一致或加密函数有误;确保 mysticTime 与生成签名时使用的值完全相同 |
| 102 | Token无效或过期 | 重新调用获取Token接口 |
| 103 | 频率限制 | 降低请求频率,增加随机延迟 |
5. 完整调用流程示例
import time, urllib, requests, execjs
# 初始化加密上下文
ctx = execjs.compile(open("encrypt.js", encoding='utf-8').read())
# 固定Cookie和Headers(需替换为有效值)
cookies = { ... }
headers = { ... }
# 步骤1:获取token和secretKey
t1 = int(time.time() * 1000)
sign1 = ctx.call('encrypt', t1)[0]
url1 = f'https://dict-trans.youdao.com/translate/key?...&mysticTime={t1}&sign={sign1}...'
resp1 = requests.post(url1, cookies=cookies, headers=headers)
token = resp1.json()['data']['token']
secretKey = resp1.json()['data']['secretKey']
# 步骤2:流式翻译
t2 = int(time.time() * 1000)
word_cn = "手机"
word = urllib.parse.quote(word_cn)
sign2 = ctx.call('encrypt2', t2, word, secretKey, token)[0]
files2 = { ... } # 见上文完整字段
resp2 = requests.post('https://dict-trans.youdao.com/webtranslate/sse', cookies=cookies, headers=headers, files=files2)
translation = extract_translation_from_sse(resp2.text)
# 步骤3:增强翻译
t3 = int(time.time() * 1000)
sign3 = ctx.call('encrypt3', secretKey, token, t3)[0]
files3 = { 'srcArticle': word_cn, 'tgtArticle': translation, 'sign': sign3, ... }
resp3 = requests.post('https://dict-trans.youdao.com/translate/enhance', cookies=cookies, headers=headers, files=files3)
print(resp3.json())
6. 注意事项
- 时间戳一致性: 每个接口的
mysticTime必须与生成签名时使用的毫秒值完全一致,且与服务器时间误差不超过10秒。 - pointParam顺序: 参数列表的字符串顺序决定了签名计算时的参数拼接顺序,不可随意更改。
- Cookie有效期:
DICT_DOCTRANS_SESSION_ID会定期失效,建议从浏览器中定期获取最新Cookie。 - 加密函数逆向: 本文档不提供具体加密算法的实现,您需要从有道翻译Web端静态资源(如
main.js)中逆向获得。 - 隐私保护: 文档中展示的Cookie、token、secretKey均为示例,实际使用时请替换为您自己的有效凭证,并注意不要泄露。
更新日期: 2026-05-14
基于版本: 有道翻译Web端(2026年5月)







暂无评论内容