目錄
起源
前言
這是一篇充滿bug,充滿作者內心無能狂怒的文章,而這隻能怪自己的才疏學淺,哈哈哈哈。具體原因呢是因爲今天下午剛弄好進行整體測試的時候發現當翻譯成有些語言的時候會產生編碼錯誤,導致中斷翻譯,一開始我測試的只有英語或者日語或者粵語等常見的語言,可沒想到最後想發了發現其他語言時發生錯誤,不過鑑於學習的目的,打算不管了,扔上來記錄一下搓搓的一天。具體原因如下圖
軟件整體
項目結構
- main.py -> baidu_tra.py -> error.py -> txt_tra.py -> word_tra.py
代碼
main.py
# #!/usr/bin/env python
# # -*- coding: utf-8 -*-
# # @Time : 2020/02/27 12:21
# # @Author : Cxk
# # @File : main.py
import os
from tkinter import *
from tkinter.messagebox import *
from tkinter import filedialog
from tkinter import ttk # 導入ttk模塊,因爲下拉菜單控件在ttk中
import threading
import webbrowser
from baidu_tra import requests_for_dst
from error import save_error
from txt_tra import *
from word_tra import *
class Rootpage(object):
def __init__(self, master=None):
self.root = master
winWidth = 400
winHeight = 400
screenWidth = self.root.winfo_screenwidth()
screenHeight = self.root.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 設置窗口初始位置在屏幕居中
self.root.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
# 設置窗口圖標
# root.iconbitmap("./image/icon.ico")
# 設置窗口寬高固定
self.root.resizable(0, 0)
self.Filepath=""
self.From=""
self.To=""
self.createPage()
def createPage(self):
def open_url(event):
webbrowser.open("https://me.csdn.net/Cxk___", new=0)
Label(root,font=("微軟雅黑", 12),text="點擊聯繫作者@Cxk").pack()
link=Label(root,font=("微軟雅黑", 12),fg='blue',text="CSDN博客@半盞清茶℡")
link.pack()
link.bind("<Button-1>", open_url)
Label(root,font=("微軟雅黑", 10),fg='red',text="該軟件可進行txt文檔與後綴名爲.docx的word文檔的翻譯").pack()
Button(root,text='選擇文件', bd =5,command=self.open_file).pack()
Label(root,font=("微軟雅黑", 10),text="文件語言").pack()
# 創建下拉菜單
cmb = ttk.Combobox(root,width=7)
cmb.pack()
# 設置下拉菜單中的值
cmb['value'] = ('無','中文', '英語', '粵語', '文言文', '日語', '韓語',
'法語', '西班牙語', '泰語', '阿拉伯語', '俄語',
'葡萄牙語', '德語', '意大利語', '希臘語', '荷蘭語',
'波蘭語', '保加利亞語', '愛沙尼亞語', '丹麥語',
'芬蘭語', '捷克語', '羅馬尼亞語', '斯洛文尼亞語', '瑞典語',
'匈牙利語', '繁體中文', '越南語')
# 設置默認值,即默認下拉框中的內容
cmb.current(0)
# 默認值中的內容爲索引,從0開始
# 執行函數
def func(event):
#獲取選中的值然後再去與語言字典匹對,返回簡寫英文
self.From=list(language.keys())[list(language.values()).index(cmb.get())]
cmb.bind("<<ComboboxSelected>>",func)
Label(root,font=("微軟雅黑", 10),text="目標語言").pack()
# 創建下拉菜單
cmb2 = ttk.Combobox(root,width=7)
cmb2.pack()
# 設置下拉菜單中的值
cmb2['value'] = ('無','中文', '英語', '粵語', '文言文', '日語', '韓語',
'法語', '西班牙語', '泰語', '阿拉伯語', '俄語',
'葡萄牙語', '德語', '意大利語', '希臘語', '荷蘭語',
'波蘭語', '保加利亞語', '愛沙尼亞語', '丹麥語',
'芬蘭語', '捷克語', '羅馬尼亞語', '斯洛文尼亞語', '瑞典語',
'匈牙利語', '繁體中文', '越南語')
# 設置默認值,即默認下拉框中的內容
cmb2.current(0)
# 默認值中的內容爲索引,從0開始
# 執行函數
def func2(event):
#獲取選中的值然後再去與語言字典匹對,返回簡寫英文
self.To=list(language.keys())[list(language.values()).index(cmb2.get())]
cmb2.bind("<<ComboboxSelected>>",func2)
Button(root,text='開始翻譯', bd =5,command=self.fun).pack()
def open_file(self):
self.Filepath = filedialog.askopenfilename() #獲得選擇好的文件
try:
size = os.path.getsize(self.Filepath)
if size == 0:
showinfo(title='錯誤', message='你所選擇的文件爲空,請重新選擇!')
elif self.Filepath=="":
showinfo(title='錯誤', message='你並未選擇文件,請重新選擇!')
else:
pass
except Exception as e:
cuowu="open_file "+str(e)
save_error(cuowu)
else:
Label(root,font=("微軟雅黑", 10),text=self.Filepath).pack()
def start(self):
try:
if self.From=='' or self.To=='':
showinfo(title='錯誤', message='請先選擇翻譯語言!')
else:
if '.txt' in self.Filepath:
showinfo(title='提示', message='翻譯已開始,稍後完成會爲你打開文件夾!')
original_text(self.Filepath,self.From,self.To)
path=os.path.abspath(os.path.join(self.Filepath,".."))#返回上一目錄
os.startfile(path)
showinfo(title='提示', message='翻譯已完成,已爲你打開翻譯文件所在文件夾!')
if '.docx' in self.Filepath:
showinfo(title='提示', message='翻譯已開始,稍後完成會爲你打開文件夾!')
original_word(self.Filepath,self.From,self.To)
path=os.path.abspath(os.path.join(self.Filepath,".."))#返回上一目錄
os.startfile(path)
showinfo(title='提示', message='翻譯已完成,已爲你打開翻譯文件所在文件夾!')
else:
showinfo(title='錯誤', message='請選擇txt文件或者docx文件!')
except Exception as e:
cuowu="start "+str(e)
save_error(cuowu)
def fun(self):
th=threading.Thread(target=self.start)
th.setDaemon(True)#守護線程
th.start()
if __name__ == "__main__":
language={'': '無', 'zh': '中文', 'en': '英語', 'yue': '粵語',
'wyw': '文言文', 'jp': '日語', 'kor': '韓語', 'fra': '法語',
'spa': '西班牙語', 'th': '泰語', 'ara': '阿拉伯語',
'ru': '俄語', 'pt': '葡萄牙語', 'de': '德語', 'it': '意大利語',
'el': '希臘語', 'nl': '荷蘭語', 'pl': '波蘭語', 'bul': '保加利亞語',
'est': '愛沙尼亞語', 'dan': '丹麥語', 'fin': '芬蘭語',
'cs': '捷克語', 'rom': '羅馬尼亞語', 'slo': '斯洛文尼亞語',
'swe': '瑞典語', 'hu': '匈牙利語', 'cht': '繁體中文', 'vie': '越南語'}
root = Tk()
root.title('文檔翻譯')
Rootpage(root)
root.mainloop()
baidu_tra.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/2/27 12:50
# @Author : Cxk
# @File : baidu_tra.py
import requests
import string
import time
import hashlib
import json
import re
import os
from error import save_error
api_url = "http://api.fanyi.baidu.com/api/trans/vip/translate"
my_appid = '20191210000364883'
cyber = 'OLXV4XqUj9vhXSSem70K'
lower_case = list(string.ascii_lowercase)
def requests_for_dst(word,From,To):
"""
word:翻譯內容
From:翻譯語言
To:返回語言
'en':英語
'zh':中文
"""
try:
salt = str(time.time())[:10]
final_sign = str(my_appid)+word+salt+cyber
final_sign = hashlib.md5(final_sign.encode("utf-8")).hexdigest()
#區別en,zh構造請求參數
paramas = {
'q':word,
'from':From,
'to':To,
'appid':'%s'%my_appid,
'salt':'%s'%salt,
'sign':'%s'%final_sign
}
my_url = api_url+'?appid='+str(my_appid)+'&q='+word+'&from='+'en'+'&to='+'zh'+'&salt='+salt+'&sign='+final_sign
response = requests.get(api_url,params = paramas).content
content = str(response,encoding = "utf-8")
json_reads = json.loads(content)
# print(json_reads)
return json_reads['trans_result'][0]['dst']
except Exception as e:
cuowu="requests_for_dst "+str(e)
save_error(cuowu)
error.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2020/2/27 11:50
# @Author : Cxk
# @File : error.py
import datetime
times = datetime.datetime.now()
times_str = datetime.datetime.strftime(times,'%Y-%m-%d %H:%M:%S')
def save_error(cuowu):
with open('error.txt','a') as file_handle:
# .txt可以不自己新建,代碼會自動新建
file_handle.write(times_str)
file_handle.write('\n')
file_handle.write("函數: "+cuowu) # 寫入
file_handle.write('\n')
file_handle.write('\n')
txt_tra.py
# #!/usr/bin/env python
# # -*- coding: utf-8 -*-
# # @Time : 2020/02/26 12:21
# # @Author : Cxk
# # @File : txt_tra.py
import os
from baidu_tra import requests_for_dst
from error import save_error
import time
#先讀取
#翻譯
#寫入
#需要設置延時,不然無法返回
def translation_text(path,oldstr,newstr):
try:
path='%s_譯文'%path[:-4]+".txt"
with open(path,'a') as file_handle:
file_handle.write(oldstr)
file_handle.write('\n')
file_handle.write(newstr)
file_handle.write('\n')
except Exception as e:
cuowu="translation_text "+str(e)
save_error(cuowu)
def original_text(path,From,To):
file=open(path)
try:
for i in file:
if i=='\n':
continue
else:
translation_text(path,i.strip('\n'),requests_for_dst(i.strip('\n'),From,To))
time.sleep(1)
except Exception as e:
cuowu="original_text "+str(e)
save_error(cuowu)
file.close
word_tra.py
# #!/usr/bin/env python
# # -*- coding: utf-8 -*-
# # @Time : 2020/02/26 12:21
# # @Author : Cxk
# # @File : word_tra.py
import docx
import os
import time
from zipfile import ZipFile
from bs4 import BeautifulSoup
from baidu_tra import requests_for_dst
from error import save_error
#先讀取
#翻譯
#寫入
#需要設置延時,不然無法返回
def translation_word(path,oldstr,newstr):
try:
path='%s_譯文'%path[:-5]+".docx"
if not os.path.isfile(path):
# 無文件時創建
new_word=docx.Document()
new_word.save(path)
file=docx.Document(path) #創建內存中的word文檔對象
file.add_paragraph(oldstr) #寫入原文
file.add_paragraph(newstr)#寫入譯文
file.save(path) #保存才能看到結果
except Exception as e:
cuowu="translation_word "+str(e)
save_error(cuowu)
def original_word(path,From,To):
try:
document=ZipFile(path)#將docx變爲zip文件
xml=document.read("word/document.xml")#找到xml文件,存放內容處
wordObj=BeautifulSoup(xml.decode("utf-8"),"html.parser")
texts=wordObj.findAll("w:t")#找到所有文字
for text in texts:
# print(text.text)
translation_word(path,text.text,requests_for_dst(text.text,From,To))
time.sleep(1)
except Exception as e:
cuowu="original_word "+str(e)
save_error(cuowu)
詳細步驟
- 原理其實很簡單,沒啥技術含量,只是各種邏輯關係的控制
- 分模塊學習的話很容易上手,但關鍵是各種語法要比較熟
- 先了解os模塊的各種操作,百度翻譯接口的調用,然後處理txt文檔,處理word文檔,最後是界面的建成,這些詳細操作CSDN裏有一堆教程,我就不再去多說了
- 最後是耐心,講真的,真要寫下來一個項目人都要懵好久,停下來時整個大腦還是項目的各種構造,怎麼處理,怎麼優化,但是寫下來了對自己還是挺有幫助的
- 當然這其中肯定有一堆槽點,各種bug,但是好歹還是成型了。
後記
這個想法在起源是在找翻譯文檔時遇到一堆收費的啊或者有限制的,就想着自己弄一個,然後一步一步成型,但是當做下來卻發現沒那麼簡單,頓時大失所望,最後還是老老實實回到了百度翻譯的懷抱,哈哈哈,有興趣的同學可以弄一下,bug的話我估計是調用百度接口哪裏返回值出現的錯誤,我選的字符編碼統一是utf-8的,有些語言它可能返回的是gbk的,所以框架大概沒啥問題了,就改下baidu_tra.py這個文件。源碼我都上傳到資源了,設置了1積分的要求,當然這裏每個文件都有,可以這裏直接複製,省的花積分了。