摘要:做這個(gè)記錄之前,剛完成使用作為公司前端項(xiàng)目的持續(xù)交付工具的實(shí)踐,打算寫(xiě)的教程前先把官方文檔扒下來(lái)做個(gè)翻譯站。在實(shí)踐一番后,卡在不能頻密調(diào)取翻譯這塊上,項(xiàng)目無(wú)法進(jìn)行下去。
做這個(gè)記錄之前,剛完成使用drone作為公司前端項(xiàng)目的持續(xù)交付工具的實(shí)踐,打算寫(xiě)的教程前先把官方文檔扒下來(lái)做個(gè)翻譯站。在實(shí)踐一番后,卡在不能頻密調(diào)取google翻譯這塊上,項(xiàng)目無(wú)法進(jìn)行下去。最后覺(jué)得經(jīng)歷的過(guò)程涉及的內(nèi)容挺多的所以記錄一下同時(shí)分享給大家。
這次經(jīng)歷涉及以下知識(shí):
wget抓取網(wǎng)站
使用基于python的翻譯工具
使用nodejs調(diào)取命令行
使用nodejs讀寫(xiě)文件
為express添加jwt
基于express實(shí)現(xiàn)上傳文件
在nodejs環(huán)境下讀取并編輯html文件
我們一點(diǎn)點(diǎn)來(lái)說(shuō)。
wget抓取網(wǎng)站最初是尋找有什么帶可視化的工具來(lái)達(dá)到目的的,后來(lái)在尋找的過(guò)程中看到原來(lái)wget能實(shí)現(xiàn)整站抓取,所以怎樣簡(jiǎn)單怎樣來(lái)!
# 抓取整站 wget -r -p -np -k -E http://www.xxx.com # w抓取第一級(jí) wget -l 1 -p -np -k http://www.xxx.com
-r 遞歸抓取
-k 抓取后修正鏈接,適合本地瀏覽
-e robots=off 忽略robots協(xié)議,強(qiáng)制抓?。髅プト。?/p>
-E 將text/html類(lèi)型的文檔保存為.html的文件
使用基于python的翻譯工具這個(gè)在github上找了幾個(gè)工具,同時(shí)也考慮過(guò)使用官方提供的API(微軟和google均有提供),最后得出使用soimort/translate-shell(并不想花錢(qián)和花時(shí)間再看文檔上了>w<)
這個(gè)trans shell工具提供幾個(gè)翻譯源(google, bing, yandex, apertium),不知道為何能用的只有g(shù)oogle Σ(!?д?)。google也很有保證了,問(wèn)題不大。
安裝并不復(fù)雜,只需要安裝gawk,其他在ubuntu系統(tǒng)下默認(rèn)都有包含的:
GNU Awk
gawk安裝
$ sudo apt-get install gawk
嘗試:
$ gawk -f <(curl -Ls git.io/translate) -- -shell
安裝trans本體,官方文檔提供三種方式,方式1不知道為何有bug,方式2并不太熟悉,最后選擇方式3:
$ git clone https://github.com/soimort/translate-shell $ cd translate-shell/ $ make $ [sudo] make install
使用起來(lái)也是簡(jiǎn)單:
$ trans "Saluton, Mondo!" Saluton, Mondo! Hello, World! Translations of Saluton, Mondo! [ Esperanto -> English ] Saluton , Hello, Mondo ! World!
簡(jiǎn)短輸出方式:
$ trans -brief "Saluton, Mondo!" Hello, World!
翻譯文件:
$ trans -b en:zh -i input.txt -o output.txt
使用trans調(diào)取google translate進(jìn)行翻譯不能頻頻調(diào)用,頻頻調(diào)用之后會(huì)令后續(xù)請(qǐng)求503,被google限制請(qǐng)求!!使用nodejs調(diào)取命令行
完成翻譯的調(diào)研后,感覺(jué)本地實(shí)現(xiàn)翻譯需要安裝各種東西,不如做成web應(yīng)用好了。用express快速建立網(wǎng)站應(yīng)用,關(guān)于在nodejs下調(diào)用命令其實(shí)是沒(méi)啥頭緒的,搜索得出結(jié)果發(fā)現(xiàn)可以使用Child Process模塊實(shí)現(xiàn):
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讀寫(xiě)文件
這個(gè)就不詳細(xì)說(shuō)明了,簡(jiǎn)單列一下用到的函數(shù):
fs.readFileSync(path)同步讀取文件
例子:
const data = fs.readFileSync("./test.txt") console.log(data.toString()) // testing!
fs.writeFileSync(path, data) 同步寫(xiě)入文件
例子:
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
先說(shuō)一下jwt,全名叫JSON Web Tokens,是一種開(kāi)放的,行業(yè)標(biāo)準(zhǔn)的RFC 7519方法,用于表示兩端之間的應(yīng)用安全。
RFC是由Internet Society(ISOC)贊助發(fā)行的互聯(lián)網(wǎng)通信協(xié)議規(guī)范,包含各種各樣的協(xié)議,同時(shí)包含互聯(lián)網(wǎng)新開(kāi)發(fā)的協(xié)議及發(fā)展中所有的記錄。
jwt這種實(shí)現(xiàn)已經(jīng)成為互聯(lián)網(wǎng)通訊安全標(biāo)準(zhǔn),那么在express怎樣實(shí)現(xiàn)?
首先安裝下面兩個(gè)包:
auth0/node-jsonwebtoken
auth0/express-jwt
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 = [] /**+[獲取用戶(hù)star列表]**/ res.status(200).send(stars) })
解釋一下,jsonwebtoken包為加密作用, secret作為鹽用來(lái)混淆內(nèi)容(出于安全是不能對(duì)客戶(hù)端公開(kāi)),然后經(jīng)過(guò)express-jwt解密處理http header里帶有的authorization: Bearer [token]中的token來(lái)獲得user信息。這樣在/user/star接口中就能獲取到用戶(hù)資料做后續(xù)的業(yè)務(wù)處理了。
基于express實(shí)現(xiàn)上傳文件忘了說(shuō)明這里提及的express版本為4,那么在新版的express 4文檔中提及了這么一段關(guān)于上傳文件的處理說(shuō)明:
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字段不在有效,需要使用上面提及的中間件提供支持才能實(shí)現(xiàn)讀取上傳來(lái)的文件。
看了一番文檔,最后選擇了multer。
下面講一下如何使用:
安裝
npm i -S multer
使用
const multer = require("multer") const limits = { fieldSize: 1024*1024*3 } const extname = "html" //創(chuàng)建本地儲(chǔ)存 const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, "./uploads"); }, //儲(chǔ)存文件時(shí)自定義文件名稱(chēng) filename: function (req, file, cb) { cb(null, file.fieldname + "-" + Date.now()); } }) //創(chuàng)建上傳處理 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`的數(shù)據(jù) * 這里設(shè)定獲取字段是`file`的內(nèi)容儲(chǔ)存成文件來(lái)完成文件上傳工作 **/ 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) 接受一個(gè)以 fieldname 命名的文件。這個(gè)文件的信息保存在 req.file
uploader.array(fieldname[, maxCount]) 接受一個(gè)以 fieldname 命名的文件數(shù)組??梢耘渲?maxCount 來(lái)限制上傳的最大數(shù)量。這些文件的信息保存在 req.files。
uploader.fields(fields) 接受指定 fields 的混合文件。這些文件的信息保存在 req.files。fields 應(yīng)該是一個(gè)對(duì)象數(shù)組,應(yīng)該具有 name 和可選的 maxCount 屬性。
例子:
[ { name: "avatar", maxCount: 1 }, { name: "gallery", maxCount: 8 } ]
uploader.none() 只接受文本域。如果任何文件上傳到這個(gè)模式,將發(fā)生 "LIMIT_UNEXPECTED_FILE" 錯(cuò)誤。這和 upload.fields([]) 的效果一樣。
uploader.any() 接受一切上傳的文件。文件數(shù)組將保存在 req.files。
警告: 確保你總是處理了用戶(hù)的文件上傳。 永遠(yuǎn)不要將 multer 作為全局中間件使用,因?yàn)閻阂庥脩?hù)可以上傳文件到一個(gè)你沒(méi)有預(yù)料到的路由,應(yīng)該只在你需要處理上傳文件的路由上使用。
multer使用起來(lái)有一定限制,并不是所有項(xiàng)目合適使用,所以不做深入說(shuō)明。
在nodejs環(huán)境下讀取并編輯html文件這里處理的流程是使用fs.readFileSync(path)讀取html文件內(nèi)容后,希望能以dom方式編輯內(nèi)容,使用jsdom/jsdom能像在瀏覽器一樣的方式處理DOM,是非常好用的工具。
比如我的需求是獲取所有TextNode提取內(nèi)容進(jìn)行翻譯并替換原來(lái)內(nèi)容,最后導(dǎo)出html內(nèi)容:
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內(nèi)容]**/ 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 }) //翻譯結(jié)果 console.log("trans result", vbrows.serialize())總結(jié)
完成一個(gè)應(yīng)用涉及的范圍其實(shí)挺廣的,內(nèi)容如果再深入討論應(yīng)該能寫(xiě)更多內(nèi)容吧。由于手上還有其他工作,只能大致記錄關(guān)鍵詞和使用的方式,原理方向等有時(shí)間再深入研究。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/43046.html
摘要:身為一個(gè)前端打字員,一直沒(méi)有寫(xiě)博客的習(xí)慣,但是,今兒是忍不了了,且為自個(gè)兒今后提個(gè)醒。 身為一個(gè)前端打字員,一直沒(méi)有寫(xiě)博客的習(xí)慣,但是,今兒是忍不了了,且為自個(gè)兒今后提個(gè)醒。 最近用vue全家桶開(kāi)發(fā)了一個(gè)網(wǎng)站,眼看一切都順順利利的,馬上都要領(lǐng)盒飯了,突然發(fā)現(xiàn)一個(gè)bug,當(dāng)我點(diǎn)擊其他的標(biāo)簽頁(yè)再點(diǎn)擊回來(lái)的時(shí)候,神奇的事情發(fā)生了,網(wǎng)站的title會(huì)自動(dòng)切換到上次所設(shè)置的! 瞬間盒飯也不吃了,...
摘要:今天小伙伴們遇到了一個(gè)概率問(wèn)題朝一列米長(zhǎng)的列車(chē)開(kāi)一炮,把它分成兩段。假設(shè)分段點(diǎn)是隨機(jī)的,問(wèn)截列車(chē)長(zhǎng)度都大于米的概率。于是乎寫(xiě)了一個(gè)計(jì)算程序,結(jié)構(gòu)很簡(jiǎn)單,循環(huán)千萬(wàn)次,很快就得出了正確答案。能用這些小小的程序完成一些繁瑣的工作,就感到挺幸福的。 今天小伙伴們遇到了一個(gè)概率問(wèn)題:朝一列100米長(zhǎng)的列車(chē)開(kāi)一炮,把它分成兩段。再對(duì)兩段分別開(kāi)炮,共分成四段。假設(shè)分段點(diǎn)是隨機(jī)的,問(wèn)4截列車(chē)長(zhǎng)度都大于...
摘要:今天小伙伴們遇到了一個(gè)概率問(wèn)題朝一列米長(zhǎng)的列車(chē)開(kāi)一炮,把它分成兩段。假設(shè)分段點(diǎn)是隨機(jī)的,問(wèn)截列車(chē)長(zhǎng)度都大于米的概率。于是乎寫(xiě)了一個(gè)計(jì)算程序,結(jié)構(gòu)很簡(jiǎn)單,循環(huán)千萬(wàn)次,很快就得出了正確答案。能用這些小小的程序完成一些繁瑣的工作,就感到挺幸福的。 今天小伙伴們遇到了一個(gè)概率問(wèn)題:朝一列100米長(zhǎng)的列車(chē)開(kāi)一炮,把它分成兩段。再對(duì)兩段分別開(kāi)炮,共分成四段。假設(shè)分段點(diǎn)是隨機(jī)的,問(wèn)4截列車(chē)長(zhǎng)度都大于...
摘要:再看下的的權(quán)限就是的查看下幾個(gè)站的日志發(fā)現(xiàn)是利用最近爆出的遠(yuǎn)程代碼執(zhí)行漏洞漏洞細(xì)節(jié)修復(fù)一下問(wèn)題解決但是這個(gè)站點(diǎn)是測(cè)試站點(diǎn)端口監(jiān)聽(tīng)的是,難道現(xiàn)在黑客能開(kāi)始嗅探非常規(guī)端口了來(lái)源 昨天發(fā)現(xiàn) 一臺(tái)服務(wù)器突然慢了 top 顯示 幾個(gè)進(jìn)程100%以上的cpu使用 執(zhí)行命令為 : /tmp/php -s /tmp/p2.conf 基本可以確定是被掛馬了 下一步確定來(lái)源 last 沒(méi)有登陸記錄 先...
閱讀 4758·2021-11-15 11:39
閱讀 2700·2021-11-11 16:55
閱讀 2208·2021-10-25 09:44
閱讀 3512·2021-09-22 16:02
閱讀 2444·2019-08-30 15:55
閱讀 3132·2019-08-30 13:46
閱讀 2674·2019-08-30 13:15
閱讀 1959·2019-08-30 11:12