用python写一个PDF翻译软件
前期工作:
注册
百度翻译api的账户(个人-高级版),注册后,每个月有2百万的免费翻译字符数。安装pdfminer3k
一、UI界面设计
点击路径按钮时弹出文件目录选择窗口,参考文章:
PYQT5实现文件目录浏览
PyQt5-对话框控件使用(QFileDialog)
二、主程序
参考文章:python如何提取英语pdf内容并翻译
知道怎么调用百度翻译的api之后,把各个功能绑定到UI控件上。程序比较简单,结合注释理解即可。
# app.py
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'app.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(577, 469)self.groupBox = QtWidgets.QGroupBox(Form)self.groupBox.setGeometry(QtCore.QRect(10, 120, 391, 241))self.groupBox.setObjectName("groupBox")self.bnt_add_file = QtWidgets.QPushButton(self.groupBox)self.bnt_add_file.setGeometry(QtCore.QRect(290, 30, 75, 23))self.bnt_add_file.setObjectName("bnt_add_file")self.bnt_translate = QtWidgets.QPushButton(self.groupBox)self.bnt_translate.setGeometry(QtCore.QRect(290, 200, 75, 23))self.bnt_translate.setObjectName("bnt_translate")self.files_listWidget = QtWidgets.QListWidget(self.groupBox)self.files_listWidget.setGeometry(QtCore.QRect(10, 30, 256, 192))self.files_listWidget.setObjectName("files_listWidget")self.bnt_delete_file = QtWidgets.QPushButton(self.groupBox)self.bnt_delete_file.setGeometry(QtCore.QRect(290, 70, 75, 23))self.bnt_delete_file.setObjectName("bnt_delete_file")self.groupBox_2 = QtWidgets.QGroupBox(Form)self.groupBox_2.setGeometry(QtCore.QRect(10, 10, 391, 101))self.groupBox_2.setObjectName("groupBox_2")self.label = QtWidgets.QLabel(self.groupBox_2)self.label.setGeometry(QtCore.QRect(30, 30, 54, 12))self.label.setObjectName("label")self.account = QtWidgets.QLineEdit(self.groupBox_2)self.account.setGeometry(QtCore.QRect(90, 30, 241, 21))self.account.setObjectName("account")self.password = QtWidgets.QLineEdit(self.groupBox_2)self.password.setGeometry(QtCore.QRect(90, 60, 241, 21))self.password.setObjectName("password")self.label_2 = QtWidgets.QLabel(self.groupBox_2)self.label_2.setGeometry(QtCore.QRect(30, 60, 54, 12))self.label_2.setObjectName("label_2")self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Translate"))self.groupBox.setTitle(_translate("Form", "选择文件"))self.bnt_add_file.setText(_translate("Form", "添加文件"))self.bnt_translate.setText(_translate("Form", "全部翻译"))self.bnt_delete_file.setText(_translate("Form", "删除文件"))self.groupBox_2.setTitle(_translate("Form", "百度翻译"))self.label.setText(_translate("Form", "帐号"))self.label_2.setText(_translate("Form", "密码"))
# translate.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# @Author : {Jan__}
# @Time : 2021/2/11 15:17import sys
from PyQt5.QtWidgets import QWidget, QFileDialog, QApplication
from app import Ui_Form
import importlib
importlib.reload(sys)from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed#
import requests
import string
import time
import hashlib
import json##初始化api_url = "http://api.fanyi.baidu.com/api/trans/vip/translate"
api_id = "" ##申请的百度翻译接口的id
cyber = "" ##申请的百度翻译接口的password# 处理PDF
# 读取PDF的内容 filename是待处理的PDF的名字class MyUi(QWidget, Ui_Form):def __init__(self):super(MyUi, self).__init__() # 分别调用了2个父类的初始化函数self.setupUi(self) # UI界面控件的初始化self.signal_connect() # 信号与槽函数绑定def signal_connect(self):self.account.setText(api_id)self.password.setText(cyber)self.bnt_add_file.clicked.connect(self.bnt_add_file_slot)self.bnt_delete_file.clicked.connect(self.bnt_delete_file_slot)self.bnt_translate.clicked.connect(self.bnt_translate_slot)def bnt_add_file_slot(self):fnames, _ = QFileDialog.getOpenFileNames(self, '选择文件', "./", "Files(*.pdf *.txt)")"""参数一:设置父组件参数二:QFileDialog的标题参数三:默认打开的目录,“.”点表示程序运行目录,/表示当前盘符根目录参数四:对话框的文件扩展名过滤器Filter,比如使用 Image files(*.jpg *.gif) 表示只能显示扩展名为.jpg或者.gif文件设置多个文件扩展名过滤,使用双引号隔开;“All Files(*);;PDF Files(*.pdf);;Text Files(*.txt)”"""try:if fnames:# 如果列表非空,则添加到文件列表中去for f in fnames:self.files_listWidget.addItem(f)except Exception as ex:print(ex)def bnt_translate_slot(self):Directory = QFileDialog.getExistingDirectory(self, '结果保存到目录', './')num = self.files_listWidget.count()# 遍历翻译所有文件print("# 遍历翻译所有文件")for _ in range(num):filename = self.files_listWidget.item(0).text()if filename.find('pdf') >= 3:content = self.getDataFromPDF(filename)elif filename.find('txt') >= 3:content = self.getDataFromTxt(filename)else:content = ""print("读取文件失败")returnprint("读取文件成功")f = filename.split('/')CNtextfile = Directory + '/CN_' + f[-1]CNtextfile = CNtextfile.replace('.pdf', '.txt')chinese = ""clist = content.split(".") # split() 通过指定.将英文分成多个句子# 遍历翻译所有句子print("# 遍历翻译所有句子")try:for i in range(clist.__len__()):chinese += (self.translate(clist[i] + '.'))chinese += '\n'self.saveText(chinese, CNtextfile)print("翻译结束,ok")self.files_listWidget.takeItem(0)print("删除文件")except Exception as ex:print(ex)def bnt_delete_file_slot(self):num = self.files_listWidget.currentRow()self.files_listWidget.takeItem(num)print("删除文件")###使用PDFminer读取def getDataFromPDF(self, filename):try:parser = PDFParser(open(filename, 'rb')) # 以二进制打开文件 ,并创建一个pdf文档分析器doc = PDFDocument() # 创建一个pdf文档# 将文档对象和连接分析器连接起来parser.set_document(doc)doc.set_parser(parser)# 初始化文档,当前文档没有密码,设为空字符串doc.initialize("")# 判断该pdf是否支持txt转换if doc.is_extractable:# 创建一个PDF资源管理器rsrcmgr = PDFResourceManager()# 创建一个参数分析器laparamas = LAParams()# 创建一个聚合器device = PDFPageAggregator(rsrcmgr, laparams=laparamas)# 创建一个PDF页面解释器对象interpreter = PDFPageInterpreter(rsrcmgr, device)contents = "" # 保存读取的text# 依次读取每个page的内容for page in doc.get_pages():interpreter.process_page(page)layout = device.get_result() # 这里layout是一个LTPage对象 里面存放着 这个page解析出的各种对象 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等等 想要获取文本就获得对象的text属性,# 在windows下,新文件的默认编码是gbk编码,所以我们在写入文件的时候需要设置一个编码格式,如下:for x in layout:if (isinstance(x, LTTextBoxHorizontal)):results = x.get_text()results = results.replace("(cid:2) ", "") # 去掉连词符results = results.replace("\n", "") # 去掉换行符 因为排版问题 有的换行导致句子中断contents += (results)return contentsexcept Exception as ex:print(ex)def getDataFromTxt(self, filename):try:with open(filename, "r", encoding='utf-8') as f:text = f.read()print(text)content = text.replace("\n", "") # 去掉换行符 因为排版问题 有的换行导致句子中断f.close()return contentexcept Exception as ex:print(ex)# 将读取的content以txt格式存放到本地def saveText(self, content, Textfile):with open(Textfile, "w", encoding='utf-8') as f:f.write(content)# 翻译从pdf提取的contentdef translate(self, content):try:salt = str(time.time())[:10]final_sign = str(self.account.text()) + content + salt + self.password.text()final_sign = hashlib.md5(final_sign.encode("utf-8")).hexdigest()# from to 代表翻译的语言paramas = {'q': content,'from': 'en','to': 'zh','appid': '%s' % self.account.text(),'salt': '%s' % salt,'sign': '%s' % final_sign}response = requests.get(api_url, params=paramas).contentcontent = str(response, encoding="utf-8")json_reads = json.loads(content)if 'trans_result' in json_reads:return json_reads['trans_result'][0]['dst'] + " "else:return str(json_reads)except Exception as ex:print(ex)if __name__ == '__main__':try:app = QApplication(sys.argv) # 实例化一个应用对象,sys.argv是一组命令行参数的列表。Python可以在shell里运行,这是一种通过参数来选择启动脚本的方式。myshow = MyUi()myshow.show()sys.exit(app.exec_()) # 确保主循环安全退出except Exception as ex:print(ex)
三、问题小结
选择文件时报错:
log4cplus:ERROR No appenders could be found for logger (AdSyncNamespace).
log4cplus:ERROR Please initialize the log4cplus system properly.
解决办法:
目录不要含有中文
打开txt文件时报错:
'utf-8' codec can't decode byte 0xa1 in position 8: invalid start byte
解决办法:
txt文件保存时,编码格式需选择utf-8,参考文章:python 报错"UnicodeDecodeError: ‘utf-8’ codec can’t decode byte"的解决办法
不足:
简单翻译英文段落没问题,想翻译期刊文献就不行了,图、表、分栏这些干扰太多了。
用python写一个PDF翻译软件相关推荐
- python写一个通讯录step by step V3.0
python写一个通讯录step by step V3.0 更新功能: 数据库进行数据存入和读取操作 字典配合函数调用实现switch功能 其他:函数.字典.模块调用 注意问题: 1.更优美的格式化输 ...
- python俄罗斯方块算法详解_用 Python 写一个俄罗斯方块游戏 (
@@ -2,34 +2,34 @@ > * 原文作者:[Dr Pommes](https://medium.com/@pommes) > * 译文出自:[掘金翻译计划](https://g ...
- python编写测试工具-python 写一个性能测试工具(一)
国庆重新学习了一下go的gin高性能测试框架. 用JMeter来测试gin与flask接口的性能,差别很大. 为什么我自己不尝试写一个性能工具,性能工具的核心就是 并发 和 请求. 请求可以选择Pyt ...
- pythongui登录界面密码显示_用python写一个带有gui界面的密码生成器
需要用到的库: tkinter:构建gui界面 pyperclip:复制功能 random:生成随机数 string:处理字符串 代码: from tkinter import * import ra ...
- python写一个通讯录V2.0
python写一个通讯录step by step V2.0 引用知识 list + dict用于临时存储用户数据信息 cPickle用于格式化文件存取 依旧使用file来进行文件的存储 解决问题 1. ...
- python软件界面-用Python写一个语音播放软件
原标题:用Python写一个语音播放软件 单位经常使用广播进行临时事项的通知(将文字转换为语音然后通过功放广播),但是市面上多数语音播放软件都是收费的,要么发音失真,要么不够稳定--经常出现莫名其妙的 ...
- python写一个系统-使用Python写一个量化股票提醒系统
大家在没有阅读本文之前先看下python的基本概念, Python是一种解释型.面向对象.动态数据类型的高级程序设计语言. Python由Guido van Rossum于1989年底发明,第一个公开 ...
- python写一个系统-熬了一晚上,小白用Python写了一个股票提醒系统
码农小马七夕节去相亲了,见了一个不错的姑娘,长的非常甜美!聊着聊着很投缘!通过介绍人了解到,对方也很满意--想着自己单身多年的生活就要结束啦,心里满是欢喜,美美哒!但是突然想起年初还有几万块在股市里面 ...
- python写一个表白程序-用Python写一个表白神器让你脱单
原标题:用Python写一个表白神器让你脱单 来自公众号:Python编程时光 今天是什么节日,就不用小明说了吧? 有女朋友的,该准备的礼物买了吗? 没有对象的,表白的套路学会了吗? 还没有?好吧,你 ...
最新文章
- 2021-07-15
- html语义化练习易牛课堂代码
- MacBookPro 关机花屏解决
- OpenCASCADE:形状愈合之概述
- orale用户角色管理
- 200820C阶段一通用链表
- java类与接口练习
- 《Linux高性能服务器编程》——2.4 IP路由
- OpenCV-图像锐化
- SQL语句详解(一)——基本增删改操作
- 《高等数学》练习题库含答案(大学期末复习资料)
- 柱状堆积图(论文绘制)
- 25 个习惯使你更开心
- MySQL学习笔记:upper、lower、ucase、lacase——字符串函数
- 燕山大学2019年计算机全国排名,燕山大学2019年排名第90位 较2018年下降6名
- Recovering a NOARCHIVELOG Database with Incremental Backups
- Linux运维:Shell脚本实现ssh免密登录远程服务器
- 解决:getReader() has already been called for this request
- LCD背光驱动 --Backlight
- hdu 2204 Eddy's爱好
热门文章
- js制作倒计时,天,小时,分,秒
- 史上最详细的LXR安装介绍
- 如何通过TXT文件批量生成汉信码
- html5密码确认属性,HTML5表单及其验证【html自带属性验证】
- ST推出 28nm MCU ,NXP更狠,推出16nm MCU
- Debian 官方发文庆祝 28 岁生日
- Windows添加自定义开机启动项
- T00LS MSF笔记
- 解决Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin
- 电信物联网平台,java后台对接电信北向应用,订阅平台消息