99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁大數(shù)據(jù)時(shí)代用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?
用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?
2021-05-14
收藏

來源:早起Python

作者:陳熹

大家好,我是早起。

本文將給大家分享一個(gè)實(shí)用的Python辦公自動(dòng)化腳本 「利用Python批量翻譯英文Word文檔并保留格式」,最終效果甚至比部分收費(fèi)的軟件還要好!先來看看具體的工作內(nèi)容。

一、需求描述

手上有大量外文文檔(本案例以5份為例,分別命名為 test1.docx test2.docx 以此類推),其中一份如下:

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

基本需求「批量將這些文檔的內(nèi)容全部翻譯成中文,并轉(zhuǎn)存到新的文件中」,效果如下:

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

高級(jí)需求:基本需求滿足的同時(shí),要求 「保留原文檔的格式」,效果如下:

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

二、邏輯梳理

(一)翻譯 API

本需求的核心是翻譯,策略是利用網(wǎng)絡(luò)的翻譯 API,這里推薦百度翻譯開放平臺(tái),不考慮并發(fā)數(shù)的話可以用標(biāo)準(zhǔn)版,免費(fèi)使用不限字符量!

百度翻譯開放平臺(tái):
http://api.fanyi.baidu.com/api/trans/product/index

在使用百度的通用翻譯 API 之前需要完成以下工作:

  1. 使用百度賬號(hào)登錄百度翻譯開放平臺(tái)(http://api.fanyi.baidu.com);
  2. 注冊(cè)成為開發(fā)者,獲得APPID;
  3. 進(jìn)行開發(fā)者認(rèn)證(如僅需標(biāo)準(zhǔn)版可跳過);
  4. 開通通用翻譯API服務(wù):開通鏈接
  5. 參考技術(shù)文檔和Demo編寫代碼
用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

完成后在個(gè)人頁面在即可看到 ID 和密鑰,這個(gè)很重要!下面給出整理好的通用翻譯 API 的 demo,已經(jīng)對(duì)輸出做簡單修改,代碼拿走就能用!

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?
用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

可以看到,測試內(nèi)容準(zhǔn)確的被翻譯出來,注意如果需要多次訪問 API,免費(fèi)版有并發(fā)數(shù)和時(shí)間限制,可以用 time 模塊睡眠一秒

(二) 格式修改

高級(jí)需求的難點(diǎn)就是保留格式,簡單來說原文檔的頁面格式和段落格式是什么,翻譯后對(duì)應(yīng)的部分就是什么。

基于上述的邏輯關(guān)系,只需要獲取原文檔的對(duì)應(yīng)內(nèi)容再賦值給新翻譯的文檔即可。(暫時(shí)只能滿足頁面設(shè)置和段落設(shè)置的統(tǒng)一,針對(duì)一段中特定詞語的格式修改,保證精確性需要基于自然語言處理NLP,本文暫不涉及)

2.1 頁面樣式

頁面樣式只要包括邊距、方向、高度、寬度等等,從原文檔中可以看到,采取的是窄邊距。但我們無需知道窄邊距四個(gè)方向應(yīng)該如何設(shè)置,只需要在代碼中呈現(xiàn)新舊文檔的變量傳遞即可,具體如下

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

2.2 段落樣式

段落樣式包括對(duì)齊、縮進(jìn)、間距等等,原文檔中采取了段后縮進(jìn),標(biāo)題是居中對(duì)齊。這些設(shè)置在變量傳遞中能夠很好完成。如果原文檔中沒有設(shè)置的變量值為 None

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

2.3 文字塊樣式修改

對(duì)于字號(hào)、加粗、斜體、顏色等樣式調(diào)整,采取的策略是建立空列表,遍歷原文檔每一段每一個(gè)文字塊,獲取相應(yīng)屬性并放到各自的列表中,對(duì)同一段而言,其包含的文字塊屬性最多的選項(xiàng)賦值給翻譯后文檔的對(duì)應(yīng)段落(如同一段全部或大部分的文字是加粗,則翻譯后對(duì)應(yīng)段落所有文字塊均設(shè)置為加粗) 對(duì)NLP感興趣的讀者可自行嘗試如何高度還原英文文檔中某些特定詞語的樣式修改,并在翻譯后的文檔中體現(xiàn)出來

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

上面的代碼不包含對(duì)字體的設(shè)置,因?yàn)闆]必要把英文的字體傳遞給中文文檔。對(duì)中文字體的設(shè)置之前的文章有提到過,比較復(fù)雜,直接見代碼:

from docx.oxml.ns import qn

run.font.name = '微軟雅黑' r = run._element.rPr.rFonts
r.set(qn('w:eastAsia'), '微軟雅黑')

(三)整體實(shí)現(xiàn)步驟

現(xiàn)在每個(gè)部分操作均以完成,考慮到本例中有多個(gè)文檔均需要翻譯,故全部邏輯如下:

  1. 利用 glob 模塊批處理框架可獲取某個(gè)文件的絕對(duì)路徑
  2. 由 python-docx 完成 Word 文件實(shí)例化后對(duì)段落進(jìn)行解析
  3. 解析出的段落文本交給百度通用翻譯 API,解析返回的 Json 格式結(jié)果(上面的修改 demo 中已經(jīng)完成了這一步)并重新寫入新的文件
  4. 同個(gè)文件全部解析、翻譯并寫入新文件后保存文件

三、代碼實(shí)現(xiàn)

導(dǎo)入需要的模塊,除翻譯 demo 中需要的庫外還需要 glob 庫批量獲取文件、python-docx 讀取文件、time 模塊控制訪問并發(fā)。為什么要 os 模塊見下文:

import requests import random import json
from hashlib import md5 import time
from docx import Document import glob import os

對(duì)原 demo 的部分內(nèi)容進(jìn)行保留,涉及到 query 參數(shù)的代碼需要移動(dòng)到后面的循環(huán)中。保留的部分:

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

效果如下

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

獲取到段落文本后,可以將段落文本賦值給 query 參數(shù),調(diào)用 API demo 的后續(xù)代碼。輸出結(jié)果的同時(shí)用 add_paragraph 將結(jié)果寫入新文檔:

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

最后保存成新文件,期望命名為 原文件名_translated 的形式,可用 os.path.basename 方法獲取并經(jīng)字符串拼接達(dá)到目的:

wordfile_new.save(path + r'\' + os.path.basename(file)[:-5] + '_translated.docx')
用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

單個(gè)文件操作完成后將讀取和創(chuàng)建文件的代碼塊放到批處理框架內(nèi):

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

完成了上面的內(nèi)容后,基本需求就完成了。根據(jù)我們梳理的對(duì)樣式的修改知識(shí),再把樣式調(diào)整的代碼加進(jìn)來就行了,最終完整代碼如下:

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

代碼運(yùn)行完畢后得到五個(gè)新的翻譯后文件

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

翻譯效果如下,可以看到英文被翻譯成中文,并且樣式大部分保留!

用Python寫的文檔批量翻譯工具,效果竟然超越付費(fèi)軟件?

至此,所有文檔都被成功翻譯,當(dāng)然這是機(jī)器翻譯的,具體應(yīng)用時(shí)還需要對(duì)關(guān)鍵部分進(jìn)一步人工調(diào)整,不過整體來說還是一次成功的Python辦公自動(dòng)化嘗試!

數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請(qǐng)參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }