翻译工具包:word+txt 完结篇

天涯浪子 提交于 2020-02-27 18:33:28

目录

起源

前言

软件整体

项目结构

代码

main.py

baidu_tra.py

error.py

 txt_tra.py

 word_tra.py

详细步骤

后记


起源

翻译工具包:txt文件专场(一)

前言

这是一篇充满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)

详细步骤

  1. 原理其实很简单,没啥技术含量,只是各种逻辑关系的控制
  2. 分模块学习的话很容易上手,但关键是各种语法要比较熟
  3. 先了解os模块的各种操作,百度翻译接口的调用,然后处理txt文档,处理word文档,最后是界面的建成,这些详细操作CSDN里有一堆教程,我就不再去多说了
  4. 最后是耐心,讲真的,真要写下来一个项目人都要懵好久,停下来时整个大脑还是项目的各种构造,怎么处理,怎么优化,但是写下来了对自己还是挺有帮助的
  5. 当然这其中肯定有一堆槽点,各种bug,但是好歹还是成型了。

后记

这个想法在起源是在找翻译文档时遇到一堆收费的啊或者有限制的,就想着自己弄一个,然后一步一步成型,但是当做下来却发现没那么简单,顿时大失所望,最后还是老老实实回到了百度翻译的怀抱,哈哈哈,有兴趣的同学可以弄一下,bug的话我估计是调用百度接口哪里返回值出现的错误,我选的字符编码统一是utf-8的,有些语言它可能返回的是gbk的,所以框架大概没啥问题了,就改下baidu_tra.py这个文件。源码我都上传到资源了,设置了1积分的要求,当然这里每个文件都有,可以这里直接复制,省的花积分了。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!