作为一名科研狗,经常需要读一些外文文献并且做笔记,有时还需要全文翻译以备后用。这时候会遇到一些问题:
PDF和CAJ文件直接复制出来的东西含有大量无用的换行符,手动删除十分麻烦;
有的文献是图片形式的,或者设置了权限导致无法复制,这个时候更麻烦,需要一个一个单词自己敲;
对于需要大量翻译的文献,经过本人测试发现一整段翻译效果不如一句一句单独翻译效果好,但是一句一句翻译起来实在太麻烦了。
基于以上的问题以及自己的英语水平,我开发了一个集去换行符,图片转文字,整段翻译于一体的文献阅读辅助工具,旨在提高自己的文献阅读效率,用最短的时间完成最多的工作。
Python是一种计算机程序设计语言。是一种动态的、面向对象的脚本语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。……………………
这一段摘自百度百科
https://baike.baidu.com/item/Python/407313?fr=aladdin
百度图片转文字API地址:https://cloud.baidu.com/product/ocr/general
你需要注册账号,创建图片转文字才能使用,在此之前需要在python安装对应的库:baidu-api。
后续步骤其实我也是从别的博客里学的,这里放上博客传送门:https://blog.csdn.net/wc781708249/article/details/78559448
在此感谢ID为风吴痕的大哥/大姐
关于selenium的基本信息可以参考百度。
本文使用selenium主要是用来做浏览器自动翻译。为什么不直接调用AIP翻译呢?我试过用有道和百度的API直接翻译,但是结果一点也不美好,翻译出来的东西完全不想人话~~~~这可能是免费版的原因吧,反正最后我是放弃这个思路了。
本文中使用Selenium的原因主要是本人的爬虫水平太低,只能选择selenium这样不需要太复杂操作和破解的爬虫工具来进行浏览器自动翻译。网上有很多大神可以不用selenium直接用爬虫翻译,这可能是我以后努力的目标吧,反正目前我还做不到~~~
PyQt5不多解释,具体见百度。
在开发之前需要准备好开发环境和浏览器驱动,我用的是火狐浏览器,因此准备了火狐驱动。开发环境需要安装selenium,PyQt5,pyinstaller,baidu-api等,具体见下图:
因为这个虚拟环境还用来做别的事,因此看起来乱七八糟的~,准确的库安装目录参考后边的代码。
只有黑框框的工具当然也是可以用的,但是既然会用PyQt5,为什么还要用黑框框呢,是吧?
GUI设计我的总体思想是能用,但是不要太显眼,不能搞得太大了挡住其他更重要的部分,也不能太小了,太小不方便拖拽,此外最好还能置顶桌面,不用在切换程序的时候老是找他。基于这样的想法我的界面设计成了这样:
主要可以分成两个大区:按钮区和状态栏。按钮区又可以分为左右两个部分,左边小,右边大,这样方便将界面放在桌面最右边使用,如下图:
这样做的好处是既不挡着主界面又好找,是不是很机智。此外为了方便放在右边,状态栏的提示也是尽可能短小精悍。
GUI设计的具体代码如下:
class Settings():
def __init__(self):
self.button_height=40
self.button_width_big=200
self.button_width_small=40
self.button_number=4
self.button_wall=10 self.window_width=self.button_wall*3+self.button_width_big+self.button_width_small self.window_height=(self.button_number+2)*self.button_wall+(self.button_number+0)*self.button_height
def cal_loc_width(self,before_num):
return self.button_width_small*before_num+self.button_wall*(before_num+1)
def cal_loc_height(self,before_num):
return self.button_wall*(before_num+1)+self.button_height*before_num
#kill_change_lineV4.0
#更新:有道翻译,selenium页面管理
#唐明弘 2019-01-09
import sys,threading
from PyQt5.QtWidgets import QApplication, QPushButton,QMainWindow
from PyQt5.QtCore import Qt
from Tools import *
from setting import Settings
from selenium import webdriver
class App(QMainWindow):
def __init__(self):
super().__init__()
self.title = 'KCL4.0'
self.left = 100
self.top = 100
self.width = 230
self.height = 200
self.initUI()
self.words=""
self.time=1
self.time2=1
self.time3=1
self.bro=webdriver.Firefox()
self.bro.minimize_window()
def initUI(self):
s=Settings()
self.setWindowTitle(self.title)
self.setFixedSize(s.window_width, s.window_height)
#self.setGeometry(self.left, self.top)
self.setWindowFlags(Qt.WindowStaysOnTopHint)
# Create a button in the window
self.button1 = QPushButton('K', self)
self.button1.move(s.cal_loc_width(0), s.cal_loc_height(0))
self.button1.resize(s.button_width_small, s.button_height)
self.button = QPushButton('去掉换行符', self)
self.button.move(s.cal_loc_width(1), s.cal_loc_height(0))
self.button.resize(s.button_width_big,s.button_height)
self.pic2words1=QPushButton("C",self)
self.pic2words1.move(s.cal_loc_width(0), s.cal_loc_height(1))
self.pic2words1.resize(s.button_width_small,s.button_height)
self.pic2words=QPushButton("图片转文字",self)
self.pic2words.move(s.cal_loc_width(1), s.cal_loc_height(1))
self.pic2words.resize(s.button_width_big,s.button_height)
self.translate_google_button_small = QPushButton("GT", self)
self.translate_google_button_small.move(s.cal_loc_width(0), s.cal_loc_height(2))
self.translate_google_button_small.resize(s.button_width_small,s.button_height)
self.translate_google_button_big= QPushButton("谷歌翻译", self)
self.translate_google_button_big.move(s.cal_loc_width(1), s.cal_loc_height(2))
self.translate_google_button_big.resize(s.button_width_big,s.button_height)
self.translate_youdao_small=QPushButton("YT",self)
self.translate_youdao_small.move(s.cal_loc_width(0),s.cal_loc_height(3))
self.translate_youdao_small.resize(s.button_width_small,s.button_height)
self.translate_youdao_big=QPushButton("有道翻译",self)
self.translate_youdao_big.move(s.cal_loc_width(1),s.cal_loc_height(3))
self.translate_youdao_big.resize(s.button_width_big,s.button_height)
self.button1.clicked.connect(self.on_click)
self.pic2words1.clicked.connect(self.pic2word)
self.button.clicked.connect(self.on_click)
self.pic2words.clicked.connect(self.pic2word)
self.translate_google_button_small.clicked.connect(self.translate_google_button)
self.translate_google_button_big.clicked.connect(self.translte_google_before)
self.translate_youdao_small.clicked.connect(self.translate_youdao_button)
self.translate_youdao_big.clicked.connect(self.translate_youdao_brfore)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
app.exit(app.exec_())
辅助工具的第一个功能是去掉换行符,这是最简单也是唯一一个不需要联网就能用的功能:只是从剪切板读取文字,把原始文字中的换行符(“\r\n”)换成空(“”)即可。代码如下:
def on_click(self):
try:
write_text_to_clipboard(read_text_from_clipboard().replace("\r\n"," "))
self.statusBar().showMessage(str(self.time)+"K成功!!")
self.time=self.time+1
except:
self.statusBar().showMessage(str(self.time)+"K失败!!")
图片转文字用到了百度图片转文字API,具体代码我是参考前边提到的ID为风吴痕的大哥/大姐的博客的。具体代码如下:
主线程:
def pic2word(self):
t=threading.Thread(target=pic2wordsss,args=(self.My_statusBar,self.time2),name="function")
t.start()
self.time2+=1
t线程:
def pic2wordss(pic):
# 定义常量
APP_ID = '14966447'
API_KEY = 'Gaz1QIGG0XFUzHA1cfwGlvRA'
SECRET_KEY = 'bZXqpXb82E2AGvKBzHlfgZrIYYGuIXF2 '
# 初始化文字识别分类器
aipOcr = AipOcr(APP_ID, API_KEY, SECRET_KEY)
options = {'detect_direction': 'true', 'language_type': 'CHN_ENG', }
result = aipOcr.webImage(pic, options)#得到结果
words = result.get("words_result")
pp = ""
for word in words:
pp = pp + " " + word.get("words")
print(str(pp))
return str(pp)
def pic2wordsss(status_bar,time2):
try:
pic = read_pic_from_clipboard()
words = pic2wordss(pic)
print(type(words))
write_text_to_clipboard(words)
status_bar(str(time2) + "C成功!!")
time2 = time2 + 1
except:
status_bar(str(time2) + "C成功!!")
翻译工具是本文中最复杂的部分。
翻译工具包括谷歌翻译和有道翻译,主要的处理流程为:
标签管理的主要作用是将浏览器界面切换到对应的网页,是正常翻译的保证。例如,若选择了谷歌翻译而浏览器界面是有道翻译,就会因为找不到对应的目标而报错。标签管理的代码如下:
def tag_manage(browser,target):#标签管理函数
Google='window.open("https://translate.google.cn/");'
Youdao='window.open("http://fanyi.youdao.com/");'
statu=0
try:
handles = browser.window_handles
except:
browser=webdriver.Firefox()
handles=browser.window_handles
if browser.title==target:
pass
else:
for handle in handles:
browser.switch_to.window(handle)
if browser.title == target:
statu = 1
break
if statu == 0 and target=="在线翻译_有道":
browser.execute_script(Youdao)
if statu==0 and target == "Google 翻译":
browser.execute_script(Google)
return browser
前处理要解决的问题是在翻译之前去掉文字中不需要的东西,把一整段话以句为单位进行分解,最后输出分解结果
代码如下:
def before_translate():
words=read_text_from_clipboard()
p=words.replace("\r\n"," ")
pp=p.replace("et al. ","et al ")
ppp=pp.replace("e.g.","***********")
pppp=ppp.replace("i.e.","&&&&&&&&&&&")
ppppp=pppp.replace("\x00",'')
wordss=ppppp.split(". ")
for i in range(len(wordss)):
wordss[i]=wordss[i].replace("***********","e.g.")
wordss[i]=wordss[i].replace("&&&&&&&&&&&", "i.e.")
for word in wordss:
if word=='':
wordss.pop(wordss.index(word))
return wordss
谷歌翻译的主要流程是:
1.清楚翻译栏原有文字
2.放进新文字
3.点击翻译
4.点急复制按钮
5.将结果存储了,进行下一句翻译
代码如下:
def translate_google(browser,words):
WebDriverWait(browser,20,0.01).until(lambda browser:browser.find_element_by_class_name("clear")).click()
WebDriverWait(browser, 20, 0.01).until(lambda browser: browser.find_element_by_id("source")).send_keys(words.replace("al.[","al ["))
WebDriverWait(browser, 20, 0.01).until(lambda browser: browser.find_element_by_class_name("go-button")).click()
WebDriverWait(browser, 20, 0.01).until(lambda browser: browser.find_element_by_class_name("translation"))
time.sleep(0.5)
WebDriverWait(browser, 20, 0.01).until(lambda browser: browser.find_element_by_class_name("copybutton")).click()
有道翻译的基本过程同谷歌翻译,代码如下:
def translate_youdao(browser,words):
try:
WebDriverWait(browser, 20, 0.01).until(lambda browser: browser.find_element_by_id("inputDelete")).click()
#点击清除
except:
pass
WebDriverWait(browser, 20, 0.01).until(lambda browser: browser.find_element_by_id("inputOriginal")).send_keys(
words.replace("al.[", "al ["))
#输入内容
WebDriverWait(browser, 20, 0.01).until(lambda browser: browser.find_element_by_id("transMachine")).click()
#点击翻译
WebDriverWait(browser, 20, 0.01).until(lambda browser: browser.find_element_by_id("transTarget"))
time.sleep(0.5)
#等待结果
WebDriverWait(browser, 20, 0.01).until(lambda browser: browser.find_element_by_id("targetCopy")).click()
#复制
两种翻译方式的共有部分为共有翻译函数,代码如下:
def translate_with_google_and_youdao(browser,status_bar,time3,tranlate):
i = 1
sucess_num = 0
fail_num = 0
out = ""
status_bar(str(time3) + "T开始!!")
time.sleep(0.2)
words = before_translate() # 预处理
word_num=len(words)
for word in words:
try:
tranlate(browser,word)
out=out+read_text_from_clipboard()+"。"
sucess_num+=1
status_bar(str(i) + "/" + str(word_num) + "/" + str(time3) + "T成功")
except:
status_bar(str(i) + "/" + str(word_num) + "/" + str(time3) + "T失败")
time.sleep(1)
fail_num+=1
i+=1
if fail_num:
status_bar(str(time3)+"-"+str(fail_num)+"T失败")
else:
status_bar(str(time3) + "T成功")
write_text_to_clipboard(out)
所有程序都正常运行之后需要将工具打包成exe,方便以后直接调用。用到的工具是pyinstaller,打包命令为:
Pyinsaller -F -w xxxxx.py
打包好了就可以正常使用了!
本文涉及的源代码和最后的exe程序连接如下:
链接:https://pan.baidu.com/s/1FAP18elUegRsAM4WysU6GQ
提取码:pf1a
有需要的朋友可以自己下载