node调用谷歌翻译Api,实现自动国际化

2023-11-10

原因:
项目国际化过程繁琐,每次都需要人工去google翻译,导致工作效率不高。
需求:
1.减少人工的重复劳动,提高工作效率。
2.使用脚本调用谷歌翻译接口自动化翻译。
3.free,作为程序员肯定接受不了付费服务,找方法解决限制。

前期准备:
1.谷歌翻译api:https://translate.google.cn/translate_a/single
2.一系列参数,
我们需要找到 tk 这个参数;这个参数决定着是否能调通翻译api;

大佬提供的代码:(非常感谢)
/**

  • 获取 google token

  • @param {*} a
    */
    function token(a) {
    var k = “”;
    var b = 406644;
    var b1 = 3293161072;

    var jd = “.”;
    var sb = “±a^+6”;
    var Zb = “±3^+b±f”;

    for (var e = [], f = 0, g = 0; g < a.length; g++) {
    var m = a.charCodeAt(g);
    128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023),
    e[f++] = m >> 18 | 240,
    e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224,
    e[f++] = m >> 6 & 63 | 128),
    e[f++] = m & 63 | 128)
    }
    a = b;
    for (f = 0; f < e.length; f++)
    a += e[f],
    a = RL(a, sb);
    a = RL(a, Zb);
    a ^= b1 || 0;
    0 > a && (a = (a & 2147483647) + 2147483648);
    a %= 1E6;
    return a.toString() + jd + (a ^ b)
    };
    function RL(a, b) {
    var t = “a”;
    var Yb = “+”;
    for (var c = 0; c < b.length - 2; c += 3) {
    var d = b.charAt(c + 2),
    d = d >= t ? d.charCodeAt(0) - 87 : Number(d),
    d = b.charAt(c + 1) == Yb ? a >>> d : a << d;
    a = b.charAt© == Yb ? a + d & 4294967295 : a ^ d
    }
    return a
    }

(我们这里就可以直接使用这段代码,可以解决我们80%的问题了,接下来我们需要针对自己的项目做进一步细化);
3.在这里我使用的是 node 去做这件事
需要用到 fs,moment,commander,https;这几个模块;
fs: 读、写文件;
https:发送请求到Google 翻译 Api;
moment:格式化时间,我是用来添加日志时用到的;
commander:用来操作命令行参数

实现:

  1. 翻译主函数:
    /**
  • 翻译方法
  • @param {*} language 语言
  • @param {*} txt 需翻译的文本
    */
    function translate_google(language, txt, callback) {
    var url = https://translate.google.cn/translate_a/single?client=t&sl=zh-CN&tl=${language}&hl=${language}&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&source=btn&ssel=0&tsel=1&kc=1&tk=${token(txt)}&q=${txt};
    var options = new URL(url);
    var req = https.request(options, function (res) {
    console.log('STATUS: ’ + res.statusCode);
    res.setEncoding(‘utf8’);
    var val = ‘’;
    res.on(‘data’, function (chunk) {
    val += chunk;
    // 数据流,读取的时候会分布读取下来,我们需要在读取完毕的时候操作数据。
    //(一开始我在这里操作数据,会致使代码报错,是因为数据的不完整性导致)
    });
    res.on(‘end’, () => {
    callback(JSON.parse(val)[0][0][0]) // 拿去返回的参数,得到翻译值
    });
    });
    req.on(‘error’, function (e) {
    errorLog(e.message);
    });
    req.end();
    }
  1. 向文件中写入数据
    /**
  • 向文件中写入数据
  • @param {*} path 文件路径
  • @param {*} val 文本
    */
    function appendFile(path, val) {
    fs.appendFile(path, ${val}\n, ‘utf8’, function (err) {
    if (err) {
    errorLog(err);
    return false;
    }
    errorLog(数据写入 ${path} 文件成功!)
    })
    }
  1. 错误日志
    /**
  • 错误日志
  • @param {*} error 错误信息
    */
    function errorLog(error) {
    var path = ‘./translate_google_error_log.txt’;
    var val = ${getDate()}${error}
    appendFile(path, val);
    }

4.获取当前时间
function getDate() {
var timer = moment(Date.now()).format(‘YYYY-MM-DD HH:mm:ss’)
console.log(timer)
return [${timer}]:;
}

  1. 处理翻译
    function creteTranlate(language) {
    var path = ./src/languages/${language}.locale.json;
    var datas_one = {};
    var datas_two = {};
    var dataObj;
    var i = 1;
    fs.readFile(’./src/languages/zh.locale.json’, ‘utf8’, (err, dataOne) => {
    if (err) {
    errorLog(err);
    return false;
    }
    datas_one = JSON.parse(dataOne);
    fs.readFile(path, ‘utf8’, (err, dataTwo) => {
    if (err) {
    errorLog(err);
    return false;
    }
    datas_two = JSON.parse(dataTwo);
    for (let key in datas_one) {
    if (!datas_two[key]) {
    i++;
    errorLog(没有 ${key} 这个字段);
    setTimeout(() => {
    translate_google(language, datas_one[key], (res) => {
    var a = {};
    a[key] = res;
    dataObj = Object.assign(datas_two, a);
    fs.writeFile(path, JSON.stringify(dataObj), (err) => {
    if (err) {
    errorLog(err);
    return false;
    }
    errorLog(${language}语言,写入成功:*** ${key}: ${res} *** 数据。);
    })
    })
    }, i * 500) // 加上延时,降低被封ip的概率,(测试的时候,被封了好几个ip)
    // 最后是通过联手机热点完成项目改造
    }
    }
    })
    })

}

到这里基本上就已经差不多可以正常使用了
但又觉得每次修改 翻译语言很麻烦 就使用了命令行参数来进一步修改整体代码;

这里我们就需要 commander 这个模块来处理 我们的命令参数了

var program = require(‘commander’);
//定义参数,以及参数内容的描述
program
.version(‘0.0.1’)
.usage(’[option][value …]’)
.option(’-p, -path ', ‘a string argument’)
//解析commandline arguments
program.parse(process.argv)

到这里,我们就基本上可以上测试了。

附上整个代码及使用方法:
代码:
var fs = require(‘fs’);
var moment = require(‘moment’);
var program = require(‘commander’);
var https = require(‘https’);

//定义参数,以及参数内容的描述
program
.version(‘0.0.1’)
.usage(’[option][value …]’)
.option(’-p, -path ', ‘a string argument’)
//解析commandline arguments
program.parse(process.argv)
function getDate() {
var timer = moment(Date.now()).format(‘YYYY-MM-DD HH:mm:ss’)
console.log(timer)
return [${timer}]:;
}
/**

  • 获取 google token

  • @param {*} a
    */
    function token(a) {
    var k = “”;
    var b = 406644;
    var b1 = 3293161072;

    var jd = “.”;
    var sb = “±a^+6”;
    var Zb = “±3^+b±f”;

    for (var e = [], f = 0, g = 0; g < a.length; g++) {
    var m = a.charCodeAt(g);
    128 > m ? e[f++] = m : (2048 > m ? e[f++] = m >> 6 | 192 : (55296 == (m & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (m = 65536 + ((m & 1023) << 10) + (a.charCodeAt(++g) & 1023),
    e[f++] = m >> 18 | 240,
    e[f++] = m >> 12 & 63 | 128) : e[f++] = m >> 12 | 224,
    e[f++] = m >> 6 & 63 | 128),
    e[f++] = m & 63 | 128)
    }
    a = b;
    for (f = 0; f < e.length; f++)
    a += e[f],
    a = RL(a, sb);
    a = RL(a, Zb);
    a ^= b1 || 0;
    0 > a && (a = (a & 2147483647) + 2147483648);
    a %= 1E6;
    return a.toString() + jd + (a ^ b)
    };
    function RL(a, b) {
    var t = “a”;
    var Yb = “+”;
    for (var c = 0; c < b.length - 2; c += 3) {
    var d = b.charAt(c + 2),
    d = d >= t ? d.charCodeAt(0) - 87 : Number(d),
    d = b.charAt(c + 1) == Yb ? a >>> d : a << d;
    a = b.charAt© == Yb ? a + d & 4294967295 : a ^ d
    }
    return a
    }
    /**

  • 翻译方法

  • @param {*} language 语言

  • @param {*} txt 需翻译的文本
    /
    function translate_google(language, txt, callback) {
    var url = https://translate.google.cn/translate_a/single?client=t&sl=zh-CN&tl=${language}&hl=${language}&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&source=btn&ssel=0&tsel=1&kc=1&tk=${token(txt)}&q=${txt};
    var options = new URL(url);
    var req = https.request(options, function (res) {
    console.log('STATUS: ’ + res.statusCode);
    res.setEncoding(‘utf8’);
    var val = ‘’;
    res.on(‘data’, function (chunk) {
    val += chunk;
    });
    res.on(‘end’, () => {
    callback(JSON.parse(val)[0][0][0])
    });
    });
    req.on(‘error’, function (e) {
    errorLog(e.message);
    });
    req.end();
    }
    /
    *

  • 错误日志

  • @param {*} error 错误信息
    /
    function errorLog(error) {
    var path = ‘./translate_google_error_log.txt’;
    var val = ${getDate()}${error}
    appendFile(path, val);
    }
    /
    *

  • 向文件中写入数据

  • @param {*} path 文件路径

  • @param {*} val 文本
    */
    function appendFile(path, val) {
    fs.appendFile(path, ${val}\n, ‘utf8’, function (err) {
    if (err) {
    errorLog(err);
    return false;
    }
    console.log(数据写入 ${path} 文件成功!)
    })
    }

function creteTranlate(language) {
var path = ./src/languages/${program.Path}.locale.json;
var datas_one = {}; // 翻译源文件
var datas_two = {}; // 翻译目标文件
var dataObj;
var i = 1;
fs.readFile(’./src/languages/zh.locale.json’, ‘utf8’, (err, dataOne) => {
if (err) {
errorLog(err);
return false;
}
datas_one = JSON.parse(dataOne);
fs.readFile(path, ‘utf8’, (err, dataTwo) => {
if (err) {
errorLog(err);
return false;
}
datas_two = JSON.parse(dataTwo);
for (let key in datas_one) {
if (!datas_two[key]) { // 若已存在,则不去翻译
i++;
errorLog(没有 ${key} 这个字段);
setTimeout(() => {
translate_google(language, datas_one[key], (res) => {
var a = {};
a[key] = res;
dataObj = Object.assign(datas_two, a);
fs.writeFile(path, JSON.stringify(dataObj), (err) => {
if (err) {
errorLog(err);
return false;
}
errorLog(${language}语言,写入成功:*** ${key}: ${res} *** 数据。);
})
})
}, i * 500)
}
}
})
})

}

let language = program.Path === ‘ba’ ? ‘id’ : program.Path; // 这里是因为 谷歌翻译印尼文使用的是‘id’这个参数,我们项目中使用的是“ba”来命名印尼语文件的,做了个转换
creteTranlate(language);

使用方法:
node node_translate.js -p ‘ba’ // 将中文翻译为印尼文
node node_translate.js -p ‘vi’ // 将中文翻译为越南文
node node_translate.js -p ‘en’ // 将中文翻译为英文

截图:
在这里插入图片描述
在这里插入图片描述

不足之处,还请大佬指点一下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

node调用谷歌翻译Api,实现自动国际化 的相关文章

  • Angular - 如何从 DOM 中删除我使用过 $compile 的元素?

    我需要的是两个 ng views 的功能 因为我不能 我想更改某些内容的innerHTML 并编译它 我遇到的问题是 当我再次更改内容时 我可以编译 但是 Angular 是否会自行删除绑定 或者我必须手动执行此操作 如果是这样 怎么办 编
  • 暂停除了已激活的玩家之外的所有其他玩家。

    我有这个插件 它可以将不同的样式应用于 html5
  • 使用 jquery 远程图像属性

    目前我正在尝试获取远程图像宽度 高度 我正在开发一个链接共享模块 就像当你在 Facebook 上粘贴链接时 你可以看到标题 描述和图像 所以我尝试使用 php getimagesize 来获取图像宽度 高度 但速度非常慢 所以我正在考虑使
  • 将鼠标悬停时的鼠标光标更改为锚状样式

    如果我将鼠标悬停在div鼠标光标将更改为 HTML 锚点中的光标 我怎样才能做到这一点 假设你的div has an id myDiv 将以下内容添加到您的 CSS 中 这cursor pointer指定光标应与用于锚点 超链接 的手形图标
  • Chart.js 在初始化时设置活动段

    我正在使用 Chart js v2 并且尝试在加载图表时模拟圆环图上某个段的 悬停状态 因此看起来有一个部分已突出显示 我已经搜索和梳理了代码一天 但找不到一个好的方法来做到这一点 提前致谢 设置片段的悬停样式有点令人困惑 因为它没有真正记
  • JavaScript 中的埃拉托斯特尼筛法对大量数据无限运行

    我一直在尝试写埃拉托斯特尼筛法 http en wikipedia org wiki Sieve of EratosthenesJavaScript 中的算法 基本上我只是按照以下步骤操作 创建从 2 到 n 1 的连续整数列表 令第一个素
  • 在新的 Google 协作平台 <嵌入 HTML> 中使用 localStorage 和 IndexedDB 不起作用

    我正在尝试将新的 Google 协作平台用于我开发的网页 但是 我在存储本地数据时遇到了问题 本地文件在 Windows 和 Apple safari chrome 中运行良好 从 Google 协作平台尝试一下 没有什么乐趣 此外 在 s
  • Chrome 中的性能问题

    我目前正在从事一个相对较大的项目 使用 AngularJs 构建 应用程序的一部分是一个表单 您可以向其中添加任意数量的页面 不幸的是 添加了很多不必要的垃圾 即表示表单模型的对象可能会变得非常大 在某些时候 Chrome 基本上无法处理它
  • 摩卡 - Chai Karma“套件未定义”

    我对 jscript tdd 很陌生 遇到了问题 希望有人能告诉我我在做什么 在浏览器中运行测试 通过 HTML 文件 一切正常 通过节点和业力运行它们我得到以下异常 我想在 node js 主机的 karma 中使用 Mocha 和 Ch
  • 防止 iOS 键盘在 cordova 3.5 中滚动页面

    我正在使用 Cordova 3 5 和 jQuery mobile 构建 iOS 应用程序 我在大部分应用程序中禁用了滚动功能 但是 当我选择输入字段时 iOS 键盘会打开并向上滚动页面 我不想要这个功能 由于输入足够高 键盘不会覆盖它 我
  • 将 GMT 时间转换为当地时间

    我以这种格式从我的服务器获取 GMT 时间 Fri 18 Oct 2013 11 38 23 GMT 我的要求是使用Javascript将此时间转换为本地时间 例如 如果用户来自印度 首先我需要采用时区 5 30并将其添加到我的服务器时间并
  • 在 HTML5 画布中,如何用我选择的背景遮盖图像?

    我试图用画布来实现这一点 globalCompositeOperation 但没有运气 所以我在这里问 这里有类似的问题 但我没有在其中找到我的案例 我的画布区域中有图层 从下到上的绘制顺序 画布底座填充纯白色 fff 用fillRect
  • DataTables row.add 到特定索引

    我正在替换这样的行项目 var targetRow entity row dataTable targetRow closest table dataTable DataTable dataTable row targetRow remov
  • Vuejs 2:去抖动不适用于手表选项

    当我在 VueJs 中反跳此函数时 如果我提供毫秒数作为原语 它就可以正常工作 但是 如果我将其提供为对 prop 的引用 它会忽略它 这是道具的缩写版本 props debounce type Number default 500 这是不
  • 可以设置标题样式吗? (并且使用CSS或js?)[重复]

    这个问题在这里已经有答案了 我想知道是否可以设计一个title a href title This is a title Hello a 样式问题有两个方面 文本格式 编码 我猜这是可能的 所以在问题中这样做 工具提示样式 你能把它弄大一点
  • Firebase 函数 onWrite 未被调用

    我正在尝试使用 Firebase 函数实现一个触发器 该触发器会复制数据库中的一些数据 我想观看所有添加的内容votes user vote 结构为 我尝试的代码是 const functions require firebase func
  • Javascript - 水波纹效果

    我需要 JS 上的脚本 它将以 水波纹 样式更改 images html 抱歉 6MB GIF 文件 http fcuunited ru temp listening2 gif http fcunited ru temp listening
  • 如何用另一个响应替换窗口的 URL 哈希?

    我正在尝试使用替换方法更改哈希 URL document location hash 但它不起作用 function var anchor document location hash this returns me a string va
  • 在 CKEditor 中设置字体大小和字体系列

    我正在使用 ckeditor 我想问一下这个插件如何设置font family和font size 我尝试过使用 CKEDITOR config font defaultLabel Arial CKEDITOR config fontSiz
  • 如何使用asm.js进行测试和开发?

    最近我读到asm js规范 看起来很酷 但是是否有任何环境 工具来开发和测试这个工具 这还只是处于规范阶段吗 您可以尝试使用 emscripten 和 ASM JS 1 并从侧分支在 firefox 构建中运行它 有关 asm js 的链接

随机推荐

  • PageHelper中的RowBounds

    RowBounds是处理ResultSet结果集进行分页 也就是说是mybatis默认实现是逻辑分页 并不是物理分页 但PageHelper将这个类利用起来进行了物理分页 PageHelper的其中一种使用方式就是将RowBounds参数获
  • DRM驱动代码分析:色彩管理

    高通PQ有哪些子模块 DSPP sub blocks SDE DSPP IGC DSPP Inverse gamma correction block SDE DSPP PCC Panel color correction block SD
  • Linux Ubuntu安装多个cuda版本

    因为pytorch版本与cuda版本有一定的对应要求 服务器上的cuda是不能自己随便动的 所以需要在自己账户中安装其他版本的cuda 而不能影响其他账户中已安装的cuda 这里参考了多篇博文总结出以下要点 1 nvcc和nvidia sm
  • 攻防世界 shrine 详解

    打开题目 整理源码 代码审计 目标 config FLAG 过滤了 config self 这两个函数的过滤没看懂 总之好像也没过滤掉 应该是过滤了后面的变量 圆括号是彻底的被过滤掉了 URL编码都没用 刚开始想测试XSS来着 做完后 拿编
  • JS数组过滤 简单------->多条件筛选

    在前端部分完成筛选功能 一次拿到所有数据 然后根据条件筛选 通常情况下筛选是后台给接口 在数据量不大的情况下 也有人可能会遇到前端筛选这样的情况 这个是例子中的被筛选数组 var aim name Anne age 23 gender fe
  • 最强大脑(9-10)

    目录 第九季 团队冲击赛 乾坤魔方 运Q帷幄 光影残卷 光柱霓虹 六宫数局 双面拼图 索玛秘图 康斯迭代 第九季 淘汰赛 慧眼识金 连杆曲线 光点密钥 希尔伯特旋涡 移星掠形 星阵潜袭 明灯谜局 彩虹雪花 光图谜笼 战旗阵地 时间旅人 数字
  • [开发] 认证的几种方式简介

    LDAP 认证 LDAP 轻量级目录访问协议 是一种用于访问和维护分布式目录信息的开放标准协议 它最初由电子数据系统公司 Netscape 开发 现在被广泛用于企业和组织中的身份认证和授权管理 LDAP的目标是为不同类型的应用程序 如电子邮
  • 创作灵感打卡

    打卡 打卡 打卡 重要的事情说三遍 作为一个CSDN新手 目标就是 坚持下来 每日分享关于C语言知识 希望在CSDN平台上可以走的更远 今日刚刚发布几篇博客 兴趣大发 希望同僚可以给以鼓励 使得坚持下来
  • RPNet 分割

    46m https github com ooooverflow BiSeNet 网络好像比较大 无模型 https github com superlxt RPNet Pytorch solov2 还未开源 yolact map不到30
  • VS Code 配置C/C++环境 出现问题 could not find the task 'g++' / 'gcc'

    前言 由于新电脑未装VSCode C C 配置环境 刚好手头有些东西想在上面验证 于是开启安装之旅 耗时大概4h 最后还是拷了旧电脑的配置 修改过后才解决的问题 如果你是被标题 骗 进来的 请直接跳转到tasks json部分 推荐先序阅读
  • csu 1803 2016 2016湖南省赛 A

    Problem acm csu edu cn csuoj problemset problem pid 1803 vjudge net contest 161962 problem A Reference www cnblogs com w
  • Day【3】设计一个支持增量功能的栈

    原题链接 文章目录 思路 代码 用数组来模拟栈 思路 题目中已经确切的告诉了我们 数组中会放入多少个元素 这种情况并且只有添加操作 这种情况之下 使用数组模拟效率会更高一点 代码 用数组模拟栈 击败100 class CustomStack
  • 多链生态中的跨链桥是如何运行的?

    在以太坊升级之前 它网络拥堵 手续费高昂等问题逐渐难以满足人们的需求 因此 市场中出现了许多以太坊之外的公链 其中甚至不乏有一些号称 以太坊杀手 项目 尽管以太坊很快反应过来了 并开始对其自身进行升级优化 但一个多链的生态已然形成 在多链态
  • 牛客网 之 数列还原(数列的全排列算法)

    题目描述 牛牛的作业薄上有一个长度为 n 的排列 A 这个排列包含了从1到n的n个数 但是因为一些原因 其中有一些位置 不超过 10 个 看不清了 但是牛牛记得这个数列顺序对的数量是 k 顺序对是指满足 i lt j 且 A i lt A
  • 基于yolov5的物流托盘实时检测方法研究

    摘要 传统物流作业主要依靠人工操作叉车对托盘进行搬运 自动化程度低 工厂实际环境复杂多样 导致现有的托盘检测算法的模型复杂 耗时较长 无法同时达到准确性和实时性要求 难以实际运用 针对浙江某机械 搬运 设备有限公司下属的电动车工业园实际工厂
  • 基于Web日志挖掘的个性化推荐系统(附源码)

    个性化推荐系统 实现该系统主要是使用的编程语言主要是R 然后配合css在样式上进行一定优化 使用shiny开发的一款web程序 主要实现的核心功能是基于spark的ALS算法的课程个性化推荐系统 首页界面如下图所示 该系统中的所有课程名称
  • 低代码点亮普惠数字化转型之路,助力企业数字化转型实践

    在国家大力提倡下 新一代信息技术持续迭代 企业数字化转型被推到风口 现在步入了信息化时代 尤其是2022年 在十四五的政策规划下更是有利好前景 对于企业来说 低代码开发平台是一种通用的解决方案 成为了企业进行信息化管理的首选 现在 越来越多
  • 鸡啄米VS2010/MFC编程入门教程——学习2关于VS2010/MFC/VC/C++

    2015年5月17日15 21 11 VS2010 MFC编程入门之前言 http www jizhuomi com software 137 html 在大学里 有面向对象程序设计这门课程 主要介绍的是C 基础编程 那时候大家虽然都学习了
  • Freemarker中文指南

    序言 目录 一 什么是FreeMarker 二 阅读指南 三 文档约定 四 联系方式 五 关于本文档 一 什么是FreeeMarker FreeMarker是一个模板引擎 是一个基于模板生成文本的通用工具 任何文件都可以基于html自动产生
  • node调用谷歌翻译Api,实现自动国际化

    原因 项目国际化过程繁琐 每次都需要人工去google翻译 导致工作效率不高 需求 1 减少人工的重复劳动 提高工作效率 2 使用脚本调用谷歌翻译接口自动化翻译 3 free 作为程序员肯定接受不了付费服务 找方法解决限制 前期准备 1 谷