国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

記一次翻譯站經歷

seasonley / 3395人閱讀

摘要:做這個記錄之前,剛完成使用作為公司前端項目的持續交付工具的實踐,打算寫的教程前先把官方文檔扒下來做個翻譯站。在實踐一番后,卡在不能頻密調取翻譯這塊上,項目無法進行下去。

做這個記錄之前,剛完成使用drone作為公司前端項目的持續交付工具的實踐,打算寫的教程前先把官方文檔扒下來做個翻譯站。在實踐一番后,卡在不能頻密調取google翻譯這塊上,項目無法進行下去。最后覺得經歷的過程涉及的內容挺多的所以記錄一下同時分享給大家。

這次經歷涉及以下知識:

wget抓取網站

使用基于python的翻譯工具

使用nodejs調取命令行

使用nodejs讀寫文件

express添加jwt

基于express實現上傳文件

nodejs環境下讀取并編輯html文件

我們一點點來說。

wget抓取網站

最初是尋找有什么帶可視化的工具來達到目的的,后來在尋找的過程中看到原來wget能實現整站抓取,所以怎樣簡單怎樣來!

# 抓取整站
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協議,強制抓取(流氓抓取)

-Etext/html類型的文檔保存為.html的文件

使用基于python的翻譯工具

這個在github上找了幾個工具,同時也考慮過使用官方提供的API(微軟和google均有提供),最后得出使用soimort/translate-shell(并不想花錢和花時間再看文檔上了>w<)

這個trans shell工具提供幾個翻譯源(google, bing, yandex, apertium),不知道為何能用的只有google Σ(!?д?)。google也很有保證了,問題不大。

安裝并不復雜,只需要安裝gawk,其他在ubuntu系統下默認都有包含的:

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

使用起來也是簡單:

$ 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怎樣實現?

首先安裝下面兩個包:

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 = []
  /**+[獲取用戶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.file

uploader.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 作為全局中間件使用,因為惡意用戶可以上傳文件到一個你沒有預料到的路由,應該只在你需要處理上傳文件的路由上使用。

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())
總結

完成一個應用涉及的范圍其實挺廣的,內容如果再深入討論應該能寫更多內容吧。由于手上還有其他工作,只能大致記錄關鍵詞和使用的方式,原理方向等有時間再深入研究。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43046.html

相關文章

  • 一次bug經歷-document.title

    摘要:身為一個前端打字員,一直沒有寫博客的習慣,但是,今兒是忍不了了,且為自個兒今后提個醒。 身為一個前端打字員,一直沒有寫博客的習慣,但是,今兒是忍不了了,且為自個兒今后提個醒。 最近用vue全家桶開發了一個網站,眼看一切都順順利利的,馬上都要領盒飯了,突然發現一個bug,當我點擊其他的標簽頁再點擊回來的時候,神奇的事情發生了,網站的title會自動切換到上次所設置的! 瞬間盒飯也不吃了,...

    dockerclub 評論0 收藏0
  • 為人的幸福————一次編寫計算程序的經歷

    摘要:今天小伙伴們遇到了一個概率問題朝一列米長的列車開一炮,把它分成兩段。假設分段點是隨機的,問截列車長度都大于米的概率。于是乎寫了一個計算程序,結構很簡單,循環千萬次,很快就得出了正確答案。能用這些小小的程序完成一些繁瑣的工作,就感到挺幸福的。 今天小伙伴們遇到了一個概率問題:朝一列100米長的列車開一炮,把它分成兩段。再對兩段分別開炮,共分成四段。假設分段點是隨機的,問4截列車長度都大于...

    MSchumi 評論0 收藏0
  • 為人的幸福————一次編寫計算程序的經歷

    摘要:今天小伙伴們遇到了一個概率問題朝一列米長的列車開一炮,把它分成兩段。假設分段點是隨機的,問截列車長度都大于米的概率。于是乎寫了一個計算程序,結構很簡單,循環千萬次,很快就得出了正確答案。能用這些小小的程序完成一些繁瑣的工作,就感到挺幸福的。 今天小伙伴們遇到了一個概率問題:朝一列100米長的列車開一炮,把它分成兩段。再對兩段分別開炮,共分成四段。假設分段點是隨機的,問4截列車長度都大于...

    Profeel 評論0 收藏0
  • 一次掛馬清除經歷:處理一個利用thinkphp5遠程代碼執行漏洞挖礦的木馬

    摘要:再看下的的權限就是的查看下幾個站的日志發現是利用最近爆出的遠程代碼執行漏洞漏洞細節修復一下問題解決但是這個站點是測試站點端口監聽的是,難道現在黑客能開始嗅探非常規端口了來源 昨天發現 一臺服務器突然慢了 top 顯示 幾個進程100%以上的cpu使用 執行命令為 : /tmp/php -s /tmp/p2.conf 基本可以確定是被掛馬了 下一步確定來源 last 沒有登陸記錄 先...

    incredible 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<