Skip to content

Commit

Permalink
Add new API: YouDaoWeb
Browse files Browse the repository at this point in the history
Update the default API to YouDaoWeb
  • Loading branch information
HaleShaw committed Jan 5, 2025
1 parent 0cdb4f0 commit f721388
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 43 deletions.
46 changes: 25 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,78 +77,82 @@
- <https://m.youdao.com>
- 属于移动端网页 API,精准度不是非常高。
- 为页面模式,翻译结果较多时显示效果更好。
2. 谷歌
2. 有道翻译
- <https://dict.youdao.com/webtranslate>
- 属于网页版 API,单次翻译字数限制为 5000 字。
3. 谷歌
- <https://translate.googleapis.com>
- 翻译内容较少,仅有基本翻译。
- 若不能直接访问谷歌,可修改 hosts。
3. 谷歌
4. 谷歌
- <https://translate.google.com>
- 翻译内容较少,仅有基本翻译。
- 若不能直接访问谷歌,可修改 hosts,或设置代理。
4. 必应
5. 必应
- <http://cn.bing.com/dict>
- 必应词典,仅支持单词,不支持句子。
5. 爱词霸
6. 爱词霸
- <https://ifanyi.iciba.com>
- 翻译内容较少,仅有基本翻译。
6. 腾讯交互翻译
7. 腾讯交互翻译
- <https://transmart.qq.com>
- 翻译内容较少,仅有基本翻译。
- 支持 21 种语言互译。
- 法语、西班牙语、英语和中文能互译,其他语言都只能与英语和中文互译。
7. 微软
8. 微软
- <https://api-edge.cognitive.microsofttranslator.com/translate>
- 翻译内容较少,仅有基本翻译。
8. 福昕
9. 福昕
- <https://fanyi.pdf365.cn>
- 翻译内容较少,仅有基本翻译。
9. CNKI
- <https://dict.cnki.net>
- 学术翻译
10. DeepL
10. CNKI
- <https://dict.cnki.net>
- 学术翻译
11. DeepL
- <https://www2.deepl.com/jsonrpc?method=LMT_handle_jobs>
- 免费 API,响应相对较慢。
11. DeepL X
12. DeepL X
- <https://github.com/OwO-Network/DeepLX>
- 将 DeepL API 逆向之后的三方包,不再需要 Auth Key,基于 DeepL Free 版。
- 需要配置 API 的地址。
12. DeepL API
13. DeepL API
- <https://api-free.deepl.com/v2/translate>
- <https://api.deepl.com/v2/translate>
- <https://api.deepl.com/v2/translate>
- 官方 API,分别对应 Free 和 Pro 版,需要到[DeepL API](https://www.deepl.com/pro-api)订阅方案并获取 Auth Key。
13. 有道翻译
14. 有道翻译
- <http://openapi.youdao.com/api>
- 支持 112 种语言互译,其中自动可以识别中文、英文、日文、韩文、法文、西班牙文、葡萄牙文、俄文、越南文、德文、阿拉伯文、印尼文、意大利文
- 支持术语表
- 需要到[有道智云](https://ai.youdao.com/doc.s)申请获取应用 ID 和应用密钥。
14. 百度翻译
15. 百度翻译
- <https://fanyi-api.baidu.com/api/trans/vip/translate>
- 翻译内容较少,仅有基本翻译。
- 需要到[百度翻译开放平台](https://fanyi-api.baidu.com)申请获取 APP ID 和密钥。
15. 阿里翻译
16. 阿里翻译
- <https://mt.cn-hangzhou.aliyuncs.com/api/translate/web/general>
- 翻译内容较少,仅有基本翻译。
- 支持 214 种语言互译。
- 除繁体中文、蒙语、粤语外,其他 212 种语言,可支持任意两种语言之间互译。
- 繁体中文、蒙语、粤语仅支持与中文之间的互译。
- 需要到[阿里云](https://www.aliyun.com/product/ai/base_alimt)申请获取 Access Key ID 和 Secret Access Key。
16. 腾讯翻译君
17. 腾讯翻译君
- <https://tmt.tencentcloudapi.com>
- 翻译内容较少,仅有基本翻译。
- 需要到[腾讯云](https://cloud.tencent.com/product/tmt)申请获取 Secret ID 和 Secret Key。
17. 火山翻译
18. 火山翻译
- <https://www.volcengine.com/product/machine-translation>
- 翻译内容较少,仅有基本翻译。
- 需要到[火山引擎](https://www.volcengine.com/docs/4640/130262)开通服务并获取 Access Key ID 和 Secret Access Key。
18. 华为翻译
19. 华为翻译
- <https://support.huaweicloud.com/api-nlp/nlp_03_0024.html>
- 翻译内容较少,仅有基本翻译。
- 需要到[华为云](https://www.huaweicloud.com/product/nlpf.html)开通服务并获取 AK、SK 和 Project ID。
19. 彩云小译
20. 彩云小译
- <http://api.interpreter.caiyunai.com/v1/translator>
- 翻译内容较少,仅有基本翻译。
- 需要到[彩云科技](https://fanyi.caiyunapp.com/#/api)申请获取应用 Token。
20. 小牛翻译
21. 小牛翻译
- <https://niutrans.com/text_trans>
- 翻译内容较少,仅有基本翻译。
- 需要到[小牛翻译](https://niutrans.com/cloud/account_info/info)获取 API-KEY。
Expand Down
Binary file added assets/images/youDaoWeb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
126 changes: 126 additions & 0 deletions assets/js/api/youDaoWeb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
const errorCodeMsgYouDaoWeb = {
103: "翻译文本过长",
104: "获取密钥失败",
4411: "API请求太过频繁,请稍后再试。可进入设置页面切换其他API",
9999: "其他错误,可进入设置页面切换其他API",
};

async function lookupYouDaoWeb(word) {
let data = [];
if (word.length > 5000) {
data.push({
title: errTitle,
description: errorCodeMsgYouDaoWeb[103],
});
return data;
}

let keys = await getKeys();
if (!keys || !keys.secretKey || !keys.aesKey || !keys.aesIv) {
data.push({
title: errTitle,
description: errorCodeMsgYouDaoWeb[104],
});
return data;
}

let payload = {
i: word,
from: "auto",
keyid: "webfanyi",
appVersion: "1.0.0",
vendor: "web",
pointParam: "client,mysticTime,product",
keyfrom: "fanyi.web",
};
let queryParams = getQueryParams(
options.youDaoWeb.client,
options.youDaoWeb.product,
keys.secretKey
);
let param = Object.assign(payload, queryParams);
let headers = {
Accept: "application/json, text/plain, */*",
Cookie: "[email protected]",
Referer: "https://fanyi.youdao.com/",
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
};

const api = options.youDaoWeb.api;
const path = options.youDaoWeb.path + "?" + stringify(param);

let response;
try {
response = await window.doPost(api, path, null, headers, encodeURIComponent(stringify(param)));
let decryptedText = decryptText(response, keys.aesKey, keys.aesIv);
let resData = JSON.parse(decryptedText);
console.log(resData);
let sentences = resData?.translateResult[0];
let langs = resData.type.replace("zh-CHS", "zh-CN").split("2");
let langSource = langs[0];
let langTarget = langs[1];
let trans;
if (sentences && sentences.length != 0) {
trans = sentences.map(item => item.tgt);
}
if (trans && trans.length != 0) {
const tran = trans.join("");
let phoneticHtml = getPhoneticHtml(word, tran, langSource, langTarget);
let dataTitle = `<span class="translation">${tran}</span>${phoneticHtml}`;
data.push({ title: dataTitle, description: "基本释义" });
}

let trs = resData?.dictResult?.ec?.word?.trs;
if (trs && trs.length != 0) {
for (let i = 0; i < trs.length; i++) {
data.push({
title: trs[i].tran,
description: `变形 ${trs[i].pos}`,
});
}
}
} catch (error) {
data.push({
title: errTitle,
description: errorCodeMsgYouDaoWeb[9999],
});
}
return data;
}

async function getKeys() {
const keyURL = "https://dict.youdao.com/webtranslate/key";
const baseParams = { keyid: "webfanyi-key-getter", pointParam: "client,mysticTime,product" };
let queryParams = getQueryParams(
options.youDaoWeb.client,
options.youDaoWeb.product,
options.youDaoWeb.key
);

let params = Object.assign(baseParams, queryParams);
let keyRes;
try {
keyRes = await get(keyURL + "?" + stringify(params));
return keyRes?.data;
} catch (error) {
console.error(error);
return null;
}
}

function getQueryParams(client, product, key) {
const time = getTimestamp();
let signStr = window.MD5(`client=${client}&mysticTime=${time}&product=${product}&key=${key}`);
return {
client: client,
product: product,
mysticTime: time,
sign: signStr,
};
}

function decryptText(str, aesKey, aesIv) {
const txt = str.replace(/-/g, "+").replace(/_/g, "/");
return window.AES_CBC_Decrypt(txt, aesKey, aesIv);
}
44 changes: 24 additions & 20 deletions assets/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ async function switchApi(word) {
option == Object.keys(options)[17] ||
option == Object.keys(options)[18] ||
option == Object.keys(options)[19] ||
option == Object.keys(options)[20]
option == Object.keys(options)[20] ||
option == Object.keys(options)[21]
) {
$("#page").addClass("hide");
$("#setting").addClass("hide");
Expand All @@ -158,63 +159,66 @@ async function switchApi(word) {
let data = [];
switch (option) {
case Object.keys(options)[1]:
data = await lookupGoogleAPI(word);
data = await lookupYouDaoWeb(word);
break;
case Object.keys(options)[2]:
data = await lookupGoogle(word);
data = await lookupGoogleAPI(word);
break;
case Object.keys(options)[3]:
data = await lookupBing(word);
data = await lookupGoogle(word);
break;
case Object.keys(options)[4]:
data = await lookupICiBa(word);
data = await lookupBing(word);
break;
case Object.keys(options)[5]:
data = await lookupTranSmart(word);
data = await lookupICiBa(word);
break;
case Object.keys(options)[6]:
data = await lookupMicrosoft(word);
data = await lookupTranSmart(word);
break;
case Object.keys(options)[7]:
data = await lookupFoxIT(word);
data = await lookupMicrosoft(word);
break;
case Object.keys(options)[8]:
data = await lookupCNKI(word);
data = await lookupFoxIT(word);
break;
case Object.keys(options)[9]:
data = await lookupDeepL(word);
data = await lookupCNKI(word);
break;
case Object.keys(options)[10]:
data = await lookupDeepLX(word);
data = await lookupDeepL(word);
break;
case Object.keys(options)[11]:
data = await lookupDeepLAPI(word, "free");
data = await lookupDeepLX(word);
break;
case Object.keys(options)[12]:
data = await lookupDeepLAPI(word, "pro");
data = await lookupDeepLAPI(word, "free");
break;
case Object.keys(options)[13]:
data = await lookupYouDao(word);
data = await lookupDeepLAPI(word, "pro");
break;
case Object.keys(options)[14]:
data = await lookupBaiDu(word);
data = await lookupYouDao(word);
break;
case Object.keys(options)[15]:
data = await lookupAliYun(word);
data = await lookupBaiDu(word);
break;
case Object.keys(options)[16]:
data = await lookupTencent(word);
data = await lookupAliYun(word);
break;
case Object.keys(options)[17]:
data = await lookupHuoShan(word);
data = await lookupTencent(word);
break;
case Object.keys(options)[18]:
data = await lookupHuaWei(word);
data = await lookupHuoShan(word);
break;
case Object.keys(options)[19]:
data = await lookupCaiYun(word);
data = await lookupHuaWei(word);
break;
case Object.keys(options)[20]:
data = await lookupCaiYun(word);
break;
case Object.keys(options)[21]:
data = await lookupXiaoNiu(word);
break;
default:
Expand Down
11 changes: 10 additions & 1 deletion assets/js/setting.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ const options = {
api: "https://m.youdao.com/dict?le=eng&q=",
logo: "youDaoWap.png",
},
youDaoWeb: {
name: "有道网页版",
api: "dict.youdao.com",
path: "/webtranslate",
logo: "youDaoWeb.png",
client: "fanyideskweb",
product: "webfanyi",
key: "asdjnjfenknafdfsdfsd",
},
googleAPI: {
name: "谷歌",
api: "https://translate.googleapis.com/translate_a/single?client=gtx&ie=UTF-8&oe=UTF-8&dt=bd&dt=t&sl=auto",
Expand Down Expand Up @@ -635,7 +644,7 @@ const options = {
};

// Set the default API.
const defaultAPI = Object.keys(options)[4];
const defaultAPI = Object.keys(options)[1];

const DEFAULT_SPEAK = {
speakSwitch: true,
Expand Down
Loading

0 comments on commit f721388

Please sign in to comment.