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,实现自动国际化 的相关文章

  • 在 JavaScript 中生成 RSA 密钥对

    我最近发现了这个 RSA JavaScript 库 http www ohdave com rsa http www ohdave com rsa 但是 它要求预先生成密钥 这是我的问题 问题 我想在 JavaScript 中生成 RSA
  • 使用 javascript 更改 div 颜色

    div style height 20px width 100 background color 000000 div br
  • 如何防止 gulp-notify 破坏 Windows 中的 gulp-watch?

    我正在使用吞咽通知 https www npmjs org package gulp notify插入 这是我如何在 gulpfile js 中实现它的示例 您可以看到我也在使用 gutil 和 livereload 我不知道它们是否发挥任
  • 打开 md-calendar 时滚动到当前日期

    目前正在构建一个使用 Angular Material 的应用程序 我们需要一个 md calendar 组件 我们想要自定义按钮样式和内容 因此不使用普通的 md datepicker 问题是 当 md calender 打开时 滚动位置
  • 了解 sort() 比较函数

    我正在使用一个电子商务平台 该平台无法重新排序产品属性字段的选项 这真的很糟糕 因为要插入新选项 您几乎必须删除所有现有选项并重新开始 我正在尝试在客户端进行操作 这是我正在处理的内容 这是针对鞋码的 9 EE 9 1 2 EE 10 EE
  • 如何导入和导出 javascript ES6 类

    我是 javascript 和 nodejs 的新手 我正在使用这个项目来发展我的技能并学习新技术 目前我的项目使用多个相互依赖的类 类文件位于不同的目录中 我当前正在尝试使用 export 和 require 语句来允许在其他文件中引用类
  • 通过JS Laravel访问存储目录

    有没有办法访问storage目录 该目录已经链接到publicJS 中的目录 我正在尝试制作一个上传图片的表单 验证脚本 if request gt hasFile photos marker gt photos request gt ph
  • 循环遍历元素并逐步为每个元素应用 CSS 规则

    我有一个网格布局 每个网格布局中都有不同数量的元素 我想动态添加内联grid column通过循环遍历 div 中存在的每个元素的 CSS 规则 ul 与一类 list 所以 HTML 代码的输出需要是 ul class list ul u
  • 如何调用 google 的 getBasicProfile() 来仅单击按钮即可登录 google?

    我在我的网站上使用谷歌登录
  • 了解 JavaScript - 资源

    使用 StackOverflow 的微型 Digit Blog 功能进行描述here https stackoverflow com about 我想发布以下我刚刚看到的 我觉得很有趣的谷歌技术谈话视频 我一直在理解 javascript
  • JavaScript 测验在提出所有问题之前结束

    我现在正在学习 JavaScript 并且正在创建一个测验 我的测验运行正常 控制台中没有任何错误 但它会跳过问题 有时会在回答所有问题之前结束测验 即使给出正确答案 也会减少时间 我不太确定为什么它会这样做 因为在我看来它的编码是正确的
  • 在 React Navigation 中将 props 传递给自定义抽屉导航器

    在反应导航抽屉菜单中 我想显示用户名 John Doe 它处于我的主要组件的状态 Router 我怎样才能将自定义抽屉内容组件传递给它 额外信息 我从 AsyncStorage 中获取此名称 组件已挂载 这是我的代码 export defa
  • Google 地图 API:忽略 DirectionService 请求中的季节性限制

    我目前正在开发一张地图 其中显示两点之间的最短路线 使用不同的交通工具 我注意到 有时 例如在冬季关闭的道路不会被考虑在内 我发现我可以使用方向服务 下面的代码 忽略高速公路 收费站和渡轮 但我一生都无法弄清楚如何 是否可以忽略季节性限制
  • 获取点击的的DOM路径

    HTML div class lol a class rightArrow href a div 伪代码 rightArrow click function rightArrowParents this dom dom is the pse
  • 如何在 ASP.NET MVC 3 的 Razor 视图中编码嵌入的 javascript?

    如何在以下上下文中正确编码 JavaScript 我的 JSON 对象中的值是由应用程序管理员设置的 因此我假设它们需要正确编码 对于 HTML 和 JavaScript 都是如此 我在用着System Web Script Seriali
  • 禁用特定 div 上的 Tab 键

    我有以下结构 div div Some content div div Some content div div 我想 禁用 div2 上的 tab 键 我的意思是按下 tab 键时 div2 的元素不会获得焦点 有没有简单的方法可以使用
  • Knockout.js 安全绑定

    我想使用带有淘汰赛的安全绑定 为此我使用敲除安全绑定 js https github com brianmhunt knockout secure binding 谁能解释一下为什么下面的代码不起作用 它会抛出一个错误 未捕获 淘汰 安全
  • JavaScript 数组扩展语法的时间复杂度是多少?

    我想知道在 JavaScript 中使用数组扩展的时间复杂度是多少 是线性 O n 还是常数 O 1 下面的语法示例 let lar Math max nums 传播称为 Symbol iterator 有关对象的属性 对于数组 这将迭代数
  • 在 HTML5 iOS 7 / iOS 8 中显示十进制键盘

    经过几个小时的搜索后 我只是有一个简单的问题 是否有可能在网络浏览器输入字段中显示小数键盘 input type number 只显示数字 但我需要在左下角使用逗号或点 我尝试过任何事情 pattern step等等 但没有显示十进制键盘
  • 将 RequireJS 与遗留代码结合使用

    我正在处理一个非常大的项目 该项目使用 包含带有脚本标记的 javascript 文件的旧版 JSP 页面 使用其他 javascript 模块而不使用 RequireJS 的骨干模型和视图 现在 我们希望开始将 RequireJS 与 j

随机推荐

  • 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 谷