作这个记录以前,刚完成使用drone做为公司前端项目的持续交付工具的实践,打算写的教程前先把官方文档扒下来作个翻译站。在实践一番后,卡在不能频密调取google翻译这块上,项目没法进行下去。最后以为经历的过程涉及的内容挺多的因此记录一下同时分享给你们。html
此次经历涉及如下知识:前端
wget
抓取网站python
的翻译工具nodejs
调取命令行nodejs
读写文件express
添加jwt
express
实现上传文件nodejs
环境下读取并编辑html文件咱们一点点来讲。node
wget
抓取网站最初是寻找有什么带可视化的工具来达到目的的,后来在寻找的过程当中看到原来wget
能实现整站抓取,因此怎样简单怎样来!python
# 抓取整站 wget -r -p -np -k -E http://www.xxx.com # w抓取第一级 wget -l 1 -p -np -k http://www.xxx.com
-r
递归抓取-k
抓取后修正连接,适合本地浏览-e robots=off
忽略robots协议,强制抓取(流氓抓取)-E
将text/html
类型的文档保存为.html
的文件python
的翻译工具这个在github
上找了几个工具,同时也考虑过使用官方提供的API(微软和google均有提供),最后得出使用soimort/translate-shell
(并不想花钱和花时间再看文档上了>w<)git
这个trans shell
工具提供几个翻译源(google, bing, yandex, apertium),不知道为什么能用的只有google Σ(!゚д゚)。google也颇有保证了,问题不大。github
安装并不复杂,只须要安装gawk
,其余在ubuntu系统下默认都有包含的:web
gawk安装shell
$ sudo apt-get install gawk
尝试:express
$ gawk -f <(curl -Ls git.io/translate) -- -shell
安装trans本体,官方文档提供三种方式,方式1
不知道为什么有bug,方式2
并不太熟悉,最后选择方式3
:npm
$ git clone https://github.com/soimort/translate-shell $ cd translate-shell/ $ make $ [sudo] make install
使用起来也是简单:
$ trans 'Saluton, Mondo!' Saluton, Mondo! Hello, World! Translations of Saluton, Mondo! [ Esperanto -> English ] Saluton , Hello, Mondo ! World!
简短输出方式:
$ trans -brief 'Saluton, Mondo!' Hello, World!
翻译文件:
$ trans -b en:zh -i input.txt -o output.txt
使用trans
调取google translate
进行翻译不能频频调用,频频调用以后会令后续请求503,被google限制请求!!
nodejs
调取命令行完成翻译的调研后,感受本地实现翻译须要安装各类东西,不如作成web应用好了。用express
快速创建网站应用,关于在nodejs
下调用命令实际上是没啥头绪的,搜索得出结果发现可使用Child Process
模块实现:
const util = require('util') const exec = util.promisify(require('child_process').exec) exec(`trans -V`) .then(({stdout, stderr}) => { if(stdout.indexOf("not installed") > -1) return Error(stdout) }) .then(()=>exec(`trans -b ${language} -i ${input} -o ${output}`)) .then(({stdout, stderr})=>{ return { input, output, message: stdout } })
nodejs
读写文件这个就不详细说明了,简单列一下用到的函数:
fs.readFileSync(path)
同步读取文件
例子:
const data = fs.readFileSync('./test.txt') console.log(data.toString()) // testing!
fs.writeFileSync(path, data)
同步写入文件
例子:
try{ fs.writeFileSync('./test.txt', 'testing!!') }catch(e){ console.error(e) }
fs.unlinkSync(path)
同步删除文件
例子:
try{ fs.unlinkSync('./test.txt') }catch(e){ console.error(e) }
express
添加jwt
先说一下jwt
,全名叫JSON Web Tokens,是一种开放的,行业标准的RFC 7519方法,用于表示两端之间的应用安全。
RFC是由Internet Society(ISOC)赞助发行的互联网通讯协议规范,包含各类各样的协议,同时包含互联网新开发的协议及发展中全部的记录。
jwt
这种实现已经成为互联网通信安全标准,那么在express
怎样实现?
首先安装下面两个包:
npm i -S express-jwt jsonwebtoken
使用:
const { router } = require('express') const decode_jwt = require('express-jwt') const jwt = require('jsonwebtoken') const secret = "your-secret" //盐 // 登陆 router.get('/login', function(req, res, next) { /**+[登陆逻辑]...**/ const token = jwt.sign(user, secret) res.status(200).send({ user, token }) }) //受限的接口 router.get('/user/star', decode_jwt({secret: secret}), (req, res)=>{ const { user } = req const stars = [] /**+[获取用户star列表]**/ res.status(200).send(stars) })
解释一下,jsonwebtoken
包为加密做用, secret
做为盐用来混淆内容(出于安全是不能对客户端公开),而后通过express-jwt
解密处理http header
里带有的authorization: Bearer [token]
中的token
来得到user
信息。这样在/user/star
接口中就能获取到用户资料作后续的业务处理了。
express
实现上传文件忘了说明这里说起的express
版本为4,那么在新版的express 4
文档中说起了这么一段关于上传文件的处理说明:
In Express 4, req.files is no longer available on the req object by default. To access uploaded files on the req.files object, use multipart-handling middleware like busboy, multer, formidable, multiparty, connect-multiparty, or pez.
意思是:express 4 版本req.files
字段不在有效,须要使用上面说起的中间件提供支持才能实现读取上传来的文件。
看了一番文档,最后选择了multer
。
下面讲一下如何使用:
安装
npm i -S multer
使用
const multer = require('multer') const limits = { fieldSize: 1024*1024*3 } const extname = 'html' //建立本地储存 const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, './uploads'); }, //储存文件时自定义文件名称 filename: function (req, file, cb) { cb(null, file.fieldname + '-' + Date.now()); } }) //建立上传处理 const uploader = require('multer')({ storage, limits, fileFilter(req, file, cb){ if(path.extname(file.originalname) === `.${extname}`) cb(null, true) else cb(new Error(`upload file extname must be ${extname}`)) } }) /** * 上传接口 * 只接受http头是`content-type: multipart/form-data`的数据 * 这里设定获取字段是`file`的内容储存成文件来完成文件上传工做 **/ router.post('/trans_on_upload', uploader.single('file'), (req, res)=>{ const { file } = req const fileData = fs.readFileSync(file.path) console.log(fileData.toString()) res.status(200) })
multer
接受多种文件上传方式:
uploader.single(fieldname)
接受一个以 fieldname 命名的文件。这个文件的信息保存在 req.fileuploader.array(fieldname[, maxCount])
接受一个以 fieldname 命名的文件数组。能够配置 maxCount 来限制上传的最大数量。这些文件的信息保存在 req.files。uploader.fields(fields)
接受指定 fields 的混合文件。这些文件的信息保存在 req.files。fields 应该是一个对象数组,应该具备 name 和可选的 maxCount 属性。
例子:
[ { name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 } ]
uploader.none()
只接受文本域。若是任何文件上传到这个模式,将发生 "LIMIT_UNEXPECTED_FILE" 错误。这和 upload.fields([]) 的效果同样。uploader.any()
接受一切上传的文件。文件数组将保存在 req.files。multer
使用起来有必定限制,并非全部项目合适使用,因此不作深刻说明。
nodejs
环境下读取并编辑html文件这里处理的流程是使用fs.readFileSync(path)
读取html文件内容后,但愿能以dom方式编辑内容,使用jsdom/jsdom
能像在浏览器同样的方式处理DOM,是很是好用的工具。
好比个人需求是获取全部TextNode
提取内容进行翻译并替换原来内容,最后导出html内容:
const { JSDOM } = require("jsdom") const { minify } = require("html-minifier") //递归得到全部TextNode const getAllTextNode = (node)=>{ var all = []; for (node=node.firstChild;node;node=node.nextSibling){ const { parentNode } = node if (node.nodeType==3){ all.push(node) } else all = all.concat(getAllTextNode(node)); } return all; } const html = "" /**+[获取html内容]**/ const vbrows = new JSDOM(minify(html, { collapseWhitespace: true })) const { document } = vbrows.window const textNodes = getAllTextNode(document.body) textNodes.forEach(textNodes=>{ const transStr = textNodes.textContent /**翻译处理**/ textNodes.textContent = transStr }) //翻译结果 console.log('trans result', vbrows.serialize())
完成一个应用涉及的范围其实挺广的,内容若是再深刻讨论应该能写更多内容吧。因为手上还有其余工做,只能大体记录关键词和使用的方式,原理方向等有时间再深刻研究。