很多网站都实现了国际化。而且很多基于国际化的解决方法是建立多个语言文件。
这对开发而言就很不友好啦,每次都要考虑到多个语言包。而且key还不能写错,语言也不能写错。就比较麻烦。
可不可以自动生成语言包。
结合之前写的翻译全栈的方法。获取浏览器全部中文,通过第三方翻译网站翻译之后保存成一个系统想要的文件格式就可以啦。
const cheerio = require('cheerio');
const request = require('request');
const fs = require('fs');
const MD5 = require('./MD5');
const path = require('path');
const superagent= require('superagent');
const url = 'http://192.168.0.46:8015/';
getHtml(url,false);
function getHtml(url,ifMume) {
let cookies = {
Cookie: 'ASP.NET_SessionId=dz0s3e4pnmzm4bie3uqcl0dp; X1.Core.Language.Current=zh-CN; MENU_ID=; .ASPXAUTH=2449D191C89B823A5AC172A9FDA15AF4A288656BCEE0DDE84BBD9A7F33CD038C1BEA0BF8E168FBB77BBE84D5ED81E62CEF01052834B2ACA1F678454F5E1EC52511F5B535A2E92240FB4D604DA89D7E207B586290C46443605A5D5CB125FF14D0ABA3EA807B1DDE520498245BE8ACF0B9602CD2514F56FC0FFF2AD79563842F60B4021DFAE6AB8E4441D605590D4ABB0F16760BCC94574A9F43642A6016D82349932F726B34EEC684C5D26C1C3ABC5CFCBC86E59B136E72CD03F9556A9DC84832'
}
// 引入所需要的第三方包
let hotNews = [];
superagent.get(url).set('Cookie',cookies.Cookie).end((err, data) => {
if (err) {
// 如果访问失败或者出错,会这行这里
console.log(`抓取失败 - ${err}`);
} else {
// 首先获取菜单
if(ifMume) {
let hotNews = [];
let $ = cheerio.load(data.text);
// 找到目标数据所在的页面元素,获取数据
$('html').children().each((idx, ele) => {
$(ele).html()
// 保存所有HTML
let strChineseList = [];
// strChineseList = $(ele).html().split(/[\u4e00-\u9fa5]/g);
strChineseList = splitStr($(ele).html());
hotNews.push(...strChineseList)
});
let ifMumeNo = ifMume.replace(new RegExp("/","g"),'')
let ifMumeSplit = ifMume.split('/')[1]
getTranslateData(hotNews,ifMumeNo,ifMumeSplit, $);
}else {
getHotNews(data);
}
// hotNews = getHotNews(data)
// res.json(hotNews);
}
});
}
// 获取菜单遍历菜单去获取里面的内容
let getHotNews = (res) => {
let $ = cheerio.load(res.text);
// 保存菜单
let mume = [];
$('.page-sidebar-menu li a').each((idx, ele) => {
if($(ele).attr('href') != 'javascript:;') {
mume.push($(ele).attr('href'))
}
})
for(let i = 0; i < mume.length; i++) {
setTimeout(() => {
getHtml(url + mume[i],mume[i]);
},3000*(i+1))
}
};
function getTranslateData(list,mkdir,splitMkdir,$) {
let appid = '*********************';
let key = '*******************';
let salt = (new Date).getTime();
let query = list.toString();
let from = 'zh';
let to = 'en';
let str1 = appid + query + salt + key;
let sign = MD5.MD5(str1);
let url = `http://api.fanyi.baidu.com/api/trans/vip/translate?q=${encodeURI(query)}&sign=${sign}&from=${from}&to=${to}&appid=${appid}&salt=${salt}`;
request.get(url, (err,data) => {
if(data.body == '') {
console.log(mkdir+'页面数据过大,没有翻译成功');
return;
}
let trans_resultEn = JSON.parse(data.body);
if(trans_resultEn.error_code) {
return;
}
let transSplit = trans_resultEn.trans_result[0].dst.split(',');
// decodeURI(JSON.parse(data.body).trans_result[0].src);
fs.mkdir(`./${mkdir}`,function(err) {
if(err) {
console.log(err);
return;
}
// 生成cshtml
let strchHtml = $('html').html();
// 先换页面
let strHtmlDiv = $('html .page-content').html();
strHtmlDiv = unescape(strHtmlDiv.replace(/&#x/g,'%u').replace(/;/g,''))
for(let i = 0; i < transSplit.length; i++) {
let transSplitList = transSplit[i].replace(/\s*/g,"");
if(list[i] != undefined) {
// console.log(strHtmlDiv.indexOf(list[i]))
// strHtmlDiv = strHtmlDiv.replace(list[i],`@LanguageService.Translate("${splitMkdir +'.'+ transSplitList}")`)
}
}
strchHtml = strchHtml.replace($('html .page-content').html(),strHtmlDiv);
// 在换js
for(let i = 0; i < transSplit.length; i++) {
let transSplitList = transSplit[i].replace(/\s*/g,"");
if(list[i] != undefined){
strchHtml = strchHtml.replace(`"${list[i]}"`, `$.Translate("${splitMkdir +'.'+ transSplitList}")`)
}
}
fs.writeFile(`./${mkdir}/index.cshtml`,strchHtml, function(err) {
if(err) {
console.log(err);
return;
}
})
// 生成英文
let data = {};
for(let i = 0; i < transSplit.length; i++) {
let transSplitList = transSplit[i].replace(/\s*/g,"");
data[splitMkdir +'.'+ transSplitList] = transSplit[i].replace(/(^\s*)/g,"");
}
fs.writeFile(`./${mkdir}/en-US.js`,"var data = " + JSON.stringify(data), function(err) {
if(err) {
console.log(err);
return;
}
})
// 生成中文
let dataZnCh = {};
for(let i = 0; i < transSplit.length; i++) {
transSplit[i] = transSplit[i].replace(/\s*/g,"");
dataZnCh[splitMkdir+'.'+transSplit[i]] = list[i];
}
fs.writeFile(`./${mkdir}/zh-cn.js`,"var data = " + JSON.stringify(dataZnCh), function(err) {
if(err) {
console.log(err);
return;
}
})
})
});
}
function splitStr(str) {
var arr = new Array();
var i = 0;
let arrList = [];
while (i<str.length) {
var s="";
while (str.charCodeAt(i) < 256) {
s=s+str.charAt(i);
i++;
}
arr.push(s);
var s="";
while (str.charCodeAt(i) > 256) {
s=s+str.charAt(i);
i++;
}
arr.push(s);
}
let re= /[\u4e00-\u9fa5]/g;
for (var i = 0; i < arr.length; i++) {
var obj = arr[i];
// 中文
if(re.test(obj)) {
arrList.push(obj);
}
}
return arrList;
}
里面的MD5.js 是百度翻译的md5.js 直接拿过来就OK。
简单讲一个逻辑吧,应该是通过登录获取cookie的,但是因为这是我们自己的系统。所以就直接登录上写死了cookie,登录之后获取所有的菜单,然后循环每一个菜单,获取里面的中文,去翻译,翻译之后保存成自己想要的格式。node写爬虫很方便,使用cheerio就像使用jq一样获取dom之后直接操作就OK啦。而且这样还有一个好处,如果我要翻译日语等别的语言,直接改成日语就OK啦。