1.利用python自動翻譯

對于程序員來說經(jīng)常遇到英文手冊芙贫,本文就是作者在工作過程中遇到英文的.chm格式的英文手冊界面如圖1所示些己,為了方便查詢手冊,利用python編程血久,網(wǎng)絡(luò)在線翻譯文檔突照。具體的實現(xiàn)如下:


圖1.原英文手冊截圖

1.利用windows系統(tǒng)自帶的hh.exe文件還原.chm文件
進入cmd 使用語句 hh -decompile 目標文件夾 源CHM文件名
我使用的實例如圖2所示


圖2.還原.chm文件

還原后的文件如圖3所示


圖3.還原后的圖片

2.還原后的文件包括各種文件類型,而我們需要翻譯的是.htm文件類型氧吐。所以我們需要獲取還原后的文件夾中的所有.html文件,這里就會用到編程語言中的遞歸末盔,具體代碼如下:
#獲取所有的html 文件
def getHtmlFiles(dir):

    global htmlFiles
    fileNames = os.listdir(dir)
    for i in range(len(fileNames)):
        if fileNames[i].__contains__(".htm"):
            htmlFiles.append(dir+"\\"+fileNames[i])
            print(dir+"\\"+fileNames[i])

    for i in range(len(fileNames)):
        if os.path.isdir(dir + "\\" + fileNames[i]):
            getHtmlFiles(dir + "\\" + fileNames[i])

打印出的文件路徑如圖4所示


圖4.打印的所有.htm文件路徑

3.以上獲取到htm文件路徑后筑舅,我們就可以根據(jù)路徑讀取htm的文件內(nèi)容,實際操作過程中陨舱,我將翻譯的結(jié)果替代htm的英文后翠拣,用瀏覽器打開會出現(xiàn)亂碼,因此先要刪除htm文件中關(guān)于語言的設(shè)置頭文件游盲。具體代碼如下:

#刪除頭文件解決中文亂碼
def deleteHtmlHead(index,path):
    print('==1_刪除頭文件中的屬性解決中文亂碼Start==')
    print('****'+str(index)+'****'+str(path))

    filedata = ""
    with open(path, "r") as html:
        encoding = 'UTF-8'
        # print("hhhhhhhhhhhhhhhhhhhhhhhh")
        for line in html:
            # print(line)
            if line.__contains__('<meta http-equiv="Content-Language" content="en-us">'):
                line = ''
            if line.__contains__('<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">'):
                line = ''
            if line.__contains__('charset=windows-1252'):
                line = ''
            if line.__contains__('doctype HTML'):
                line = ''
            filedata += line

    with open(path, "w") as html:
        html.write(filedata)
    print('==1_刪除頭文件中的屬性解決中文亂碼END==')

4.原始的.htm文件打開后如圖5所示误墓。


圖5.原始的htm內(nèi)容

提取內(nèi)容的文本可使用BeautifulSoup或者htmlparser 使用過程中沒有得到理想的效果蛮粮,因此我使用代碼獲取'>'與'<'之間的值來獲取。其實翻譯的準確性與否就在于能否準確的提取出.htm文件中的英文文本谜慌。在實際的編程過程中有許多特殊字符串情況需要處理然想,而本人做的不夠完美。
5.將獲取到的英文文本調(diào)用有道的翻譯接口進行翻譯
6.用翻譯的中文結(jié)果替換原文件中的英文完成翻譯
4-6過程的具體代碼如下:

#獲取翻譯結(jié)果
def translator(str):
    """
    input : str 需要翻譯的字符串
    output:translation 翻譯后的字符串
    """
    # API
    url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null'
    # 傳輸?shù)膮?shù)欣范, i為要翻譯的內(nèi)容
    key = {
        'type': "AUTO",
        'i': str,
        "doctype": "json",
        "version": "2.1",
        "keyfrom": "fanyi.web",
        "ue": "UTF-8",
        "action": "FY_BY_CLICKBUTTON",
        "typoResult": "true"
    }
    # key 這個字典為發(fā)送給有道詞典服務(wù)器的內(nèi)容
    response = requests.post(url, data=key)
    # 判斷服務(wù)器是否相應(yīng)成功
    if response.status_code == 200:
        # 通過 json.loads 把返回的結(jié)果加載成 json 格式
        if response.text==None:
            print("有道詞典None")
            return None
        else:
            if (response.text.__contains__('非常抱歉变泄,來自您ip的請求異常頻繁,為了保護其他用戶的正常訪問恼琼,只能暫時禁止您目前的訪問妨蛹。')):
                print("非常抱歉,來自您ip的請求異常頻繁")
                return None
            else:
                result = json.loads(response.text)
        #         print ("輸入的詞為:%s" % result['translateResult'][0][0]['src'])
        #         print ("翻譯結(jié)果為:%s" % result['translateResult'][0][0]['tgt'])
              #  translation = result['translateResult'][0][0]['tgt']
                translation = result['translateResult']
                return translation
    else:
        print("有道詞典調(diào)用失敗")
        # 相應(yīng)失敗就返回空
        return None

def getEnContentAndTrans(index,path):
    print('==2_處理文本分割Start==')
    print('****'+str(index)+'****'+str(path))
    html = open(path,"r")
    orgContent = html.read()
    list=[]
    if orgContent.__contains__('Example (C)'):
        list = orgContent.split('Example (C)')
    elif orgContent.__contains__('Example</span> (C)'):
        list = orgContent.split('Example</span> (C)')
    else:
        list = orgContent.split('Example (C)')
    html.close()
    print('==2_處理文本分割 END==')
    print('==3_截取英文字段并翻譯Start==')
    print('****'+str(index)+'****'+str(path))
    dealText = list[0]
    chTransText = dealText

    totalSize = len(dealText)

    beginPosition = 0
    findLeft = True
    leftPosition = 0
    rightPosition = 0
    enTextList=[]

    for i in range(beginPosition,totalSize):
        if dealText[i]==">" and findLeft:
            beginPosition=i
            leftPosition = i;
            findLeft = False
        if dealText[i]=="<" and not findLeft:
            beginPosition = i
            rightPosition = i
            findLeft = True

            enText = dealText[leftPosition+1:rightPosition]
            checkText = re.sub("\s", "", enText)
            #屏蔽&nbsp;
            checkNbspText = checkText
            checkNbspText = checkNbspText.replace('&nbsp;', '')
            checkNbspText = checkNbspText.replace('\n', '')
            checkNbspText = checkNbspText.replace(' ', '')
            checkNbspText = checkNbspText.replace('\t', '')
            #屏蔽大寫字母和數(shù)字
            checkNum = checkNbspText
            checkNum = checkNum.replace('.','')

            isDigit = checkNum.isdigit()
            isUpcase = checkNum.isupper()

            if (len(checkText))>0 and len(checkNbspText)>0 and isDigit==False and isUpcase==False:
                transResult = translator(enText)
                # if enText.__contains__('With J1939, the Rx buffer is reserved for this CAN channel'):
                #     print('ssssssssssssssssssss')
                ch=""
                if transResult==None:
                    print("NONENONENONENONENONENONE")
                    sys.exit(0)
                else:
                    for i in range(len(transResult)):
                        for j in range(len(transResult[i])):
                            item = transResult[i][j]
                            chx = item['tgt']
                            ch+=chx
                    print(enText+'___'+ch)
                    #dealText = dealText.replace(enText,ch,1)
                    if enText.__contains__('CAN') or enText.__contains__('Can') or enText.__contains__('can'):
                        chTransText = chTransText.replace(enText, 'CAN'+ch, 1)
                    elif ch.__contains__('手動RC系列30'):
                        ch=ch.replace('手動RC系列30','RC30系列手冊',1)
                        chTransText = chTransText.replace(enText, ch, 1)
                    else:
                        chTransText = chTransText.replace(enText, ch, 1)
            else:
                if len(checkText)>0:
                    print('%%%%%%'+enText)

                    #enTextList.append(enText)
    print('==3_截取英文字段并翻譯 END==')
    print('==4_將翻譯后的文件保存Start==')
    print('****'+str(index)+'****'+str(path))
    with open(path,"w") as html:
        chTransText=chTransText.replace('晴竞。','.')
        html.write(chTransText)

        if len(list)>1:
            # html.write('Example')
            # if orgContent.__contains__('Example (C)'):
            #     html.write('Example (C)')
            # elif orgContent.__contains__('Example</span> (C)'):
            #     html.write('Example</span> (C)')

            for i in range(1,len(list)):
                if orgContent.__contains__('Example (C)'):
                    html.write('Example (C)')
                elif orgContent.__contains__('Example</span> (C)'):
                    html.write('Example</span> (C)')
                html.write(list[i])
    print('==4_將翻譯后的文件保存 END==')

翻譯后的結(jié)果如圖6所示


圖6.翻譯結(jié)果

7.利用.chm生成器將所有翻譯后的文件打包成.chm文件
8.一些問題蛙卤。有道接口一小時只能調(diào)用1000次,我的解決方案是電腦連接手機熱點噩死,當ip被有道封鎖后颤难,插拔sim卡,ip地址就不同了甜滨。整體的代碼(包括調(diào)試過程中的所有有用或無用的方法)如下:



import json
import requests
import os
from bs4 import BeautifulSoup
import re
import sys



isFirst = True
htmlFiles=[]

#獲取所有的html 文件
def getHtmlFiles(dir):

    global htmlFiles
    fileNames = os.listdir(dir)
    for i in range(len(fileNames)):
        if fileNames[i].__contains__(".htm"):
            htmlFiles.append(dir+"\\"+fileNames[i])
            print(dir+"\\"+fileNames[i])

    for i in range(len(fileNames)):
        if os.path.isdir(dir + "\\" + fileNames[i]):
            getHtmlFiles(dir + "\\" + fileNames[i])


#刪除頭文件解決中文亂碼
def deleteHtmlHead(index,path):
    print('==1_刪除頭文件中的屬性解決中文亂碼Start==')
    print('****'+str(index)+'****'+str(path))

    filedata = ""
    with open(path, "r") as html:
        encoding = 'UTF-8'
        # print("hhhhhhhhhhhhhhhhhhhhhhhh")
        for line in html:
            # print(line)
            if line.__contains__('<meta http-equiv="Content-Language" content="en-us">'):
                line = ''
            if line.__contains__('<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">'):
                line = ''
            if line.__contains__('charset=windows-1252'):
                line = ''
            if line.__contains__('doctype HTML'):
                line = ''
            filedata += line

    with open(path, "w") as html:
        html.write(filedata)
    print('==1_刪除頭文件中的屬性解決中文亂碼END==')

#處理html中的文本
def handHtmlContent(index,path):
    print('========================')
    print('==2_處理HTML中的文本Start==')
    print('========================')
    print(str(index)+'___'+str(path))
    org=''
    with open(path,"r") as html:
        content = html.read()
        soup = BeautifulSoup(content, "lxml")
        org = str(soup.text)
        # org = org.replace("\t", "\n")
        # org = re.sub("\s\n", "\n", org)
        # org=re.sub("\n\s\n","",org)
        # org = re.sub("\n\s\s\n", "", org)
        # org = re.sub("\s\s\s", "", org)
        # org = re.sub("\s\s\s\s", "", org)
        # org = re.sub("\s\s\s\s\s", "", org)
        # org = re.sub("\s\s\s\s\s\s", "", org)
        # org = re.sub("\s\s\s\s\s\s\s", "", org)
        # org = re.sub("\s\s\s\s\s\s\s\s", "", org)
        # org = re.sub("\s\s\s\s\s\s\s\s\s", "", org)
        # org = re.sub("\s\s\s\s\s\s\s\s\s\s", "", org)
        #
        # while org.__contains__("\n\n"):
        #     org = org.replace("\n\n","\n")
    print('========================')
    print('==2_處理HTML中的文本 End==')
    print('========================')
    return org


#獲取翻譯結(jié)果
def translator(str):
    """
    input : str 需要翻譯的字符串
    output:translation 翻譯后的字符串
    """
    # API
    url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null'
    # 傳輸?shù)膮?shù)乐严, i為要翻譯的內(nèi)容
    key = {
        'type': "AUTO",
        'i': str,
        "doctype": "json",
        "version": "2.1",
        "keyfrom": "fanyi.web",
        "ue": "UTF-8",
        "action": "FY_BY_CLICKBUTTON",
        "typoResult": "true"
    }
    # key 這個字典為發(fā)送給有道詞典服務(wù)器的內(nèi)容
    response = requests.post(url, data=key)
    # 判斷服務(wù)器是否相應(yīng)成功
    if response.status_code == 200:
        # 通過 json.loads 把返回的結(jié)果加載成 json 格式
        if response.text==None:
            print("有道詞典None")
            return None
        else:
            if (response.text.__contains__('非常抱歉,來自您ip的請求異常頻繁衣摩,為了保護其他用戶的正常訪問昂验,只能暫時禁止您目前的訪問。')):
                print("非常抱歉艾扮,來自您ip的請求異常頻繁")
                return None
            else:
                result = json.loads(response.text)
        #         print ("輸入的詞為:%s" % result['translateResult'][0][0]['src'])
        #         print ("翻譯結(jié)果為:%s" % result['translateResult'][0][0]['tgt'])
              #  translation = result['translateResult'][0][0]['tgt']
                translation = result['translateResult']
                return translation
    else:
        print("有道詞典調(diào)用失敗")
        # 相應(yīng)失敗就返回空
        return None

"""有道翻譯函數(shù)  DONE!"""

#將翻譯的文本結(jié)果替換到源文件
def updateHtmlContent(index,path,transResult):
    print('=========================')
    print('==4_將中文替換文本內(nèi)容Start==')
    print('=========================')
    print(str(index) + '___' + str(path))

    html = open(path, "r")
    #lines = html.readlines()
    maxContent = html.read()
    updateContent = maxContent
    for i in range(len(transResult)):
        item = transResult[i][0]
        en = item['src']
        ch = item['tgt']
        if ch==None or len(en)<=0 or en.__contains__('\xa0'):
            continue
        if updateContent.__contains__(en):
            #print('==============='+ch)
            updateContent = updateContent.replace(en,ch,1)

    html.close()
    with open(path, "w") as html:
        html.write(updateContent)
    print('=========================')
    print('==4_將中文替換文本內(nèi)容 END==')
    print('=========================')

#def checkOnlyNBSP(text):

def getEnContentAndTrans(index,path):
    print('==2_處理文本分割Start==')
    print('****'+str(index)+'****'+str(path))
    html = open(path,"r")
    orgContent = html.read()
    list=[]
    if orgContent.__contains__('Example (C)'):
        list = orgContent.split('Example (C)')
    elif orgContent.__contains__('Example</span> (C)'):
        list = orgContent.split('Example</span> (C)')
    else:
        list = orgContent.split('Example (C)')
    html.close()
    print('==2_處理文本分割 END==')
    print('==3_截取英文字段并翻譯Start==')
    print('****'+str(index)+'****'+str(path))
    dealText = list[0]
    chTransText = dealText

    totalSize = len(dealText)

    beginPosition = 0
    findLeft = True
    leftPosition = 0
    rightPosition = 0
    enTextList=[]

    for i in range(beginPosition,totalSize):
        if dealText[i]==">" and findLeft:
            beginPosition=i
            leftPosition = i;
            findLeft = False
        if dealText[i]=="<" and not findLeft:
            beginPosition = i
            rightPosition = i
            findLeft = True

            enText = dealText[leftPosition+1:rightPosition]
            checkText = re.sub("\s", "", enText)
            #屏蔽&nbsp;
            checkNbspText = checkText
            checkNbspText = checkNbspText.replace('&nbsp;', '')
            checkNbspText = checkNbspText.replace('\n', '')
            checkNbspText = checkNbspText.replace(' ', '')
            checkNbspText = checkNbspText.replace('\t', '')
            #屏蔽大寫字母和數(shù)字
            checkNum = checkNbspText
            checkNum = checkNum.replace('.','')

            isDigit = checkNum.isdigit()
            isUpcase = checkNum.isupper()

            if (len(checkText))>0 and len(checkNbspText)>0 and isDigit==False and isUpcase==False:
                transResult = translator(enText)
                # if enText.__contains__('With J1939, the Rx buffer is reserved for this CAN channel'):
                #     print('ssssssssssssssssssss')
                ch=""
                if transResult==None:
                    print("NONENONENONENONENONENONE")
                    sys.exit(0)
                else:
                    for i in range(len(transResult)):
                        for j in range(len(transResult[i])):
                            item = transResult[i][j]
                            chx = item['tgt']
                            ch+=chx
                    print(enText+'___'+ch)
                    #dealText = dealText.replace(enText,ch,1)
                    if enText.__contains__('CAN') or enText.__contains__('Can') or enText.__contains__('can'):
                        chTransText = chTransText.replace(enText, 'CAN'+ch, 1)
                    elif ch.__contains__('手動RC系列30'):
                        ch=ch.replace('手動RC系列30','RC30系列手冊',1)
                        chTransText = chTransText.replace(enText, ch, 1)
                    else:
                        chTransText = chTransText.replace(enText, ch, 1)
            else:
                if len(checkText)>0:
                    print('%%%%%%'+enText)

                    #enTextList.append(enText)
    print('==3_截取英文字段并翻譯 END==')
    print('==4_將翻譯后的文件保存Start==')
    print('****'+str(index)+'****'+str(path))
    with open(path,"w") as html:
        chTransText=chTransText.replace('既琴。','.')
        html.write(chTransText)

        if len(list)>1:
            # html.write('Example')
            # if orgContent.__contains__('Example (C)'):
            #     html.write('Example (C)')
            # elif orgContent.__contains__('Example</span> (C)'):
            #     html.write('Example</span> (C)')

            for i in range(1,len(list)):
                if orgContent.__contains__('Example (C)'):
                    html.write('Example (C)')
                elif orgContent.__contains__('Example</span> (C)'):
                    html.write('Example</span> (C)')
                html.write(list[i])
    print('==4_將翻譯后的文件保存 END==')

def main():
    # rootDir = 'D:\用戶手冊\RC30_Manual'+'\\'+'3_controllers'+'\\'+'HWID00D3'+'\\'+'functions'
    rootDir = 'D:\用戶手冊\RC30_Manual'
    print('==0_獲取所有的Html文件Start==')
    global isFirst
    if isFirst:
        getHtmlFiles(rootDir)
        isFirst=False
    print('==0_獲取所有的Html文件 END===')

    # ** ** 118 ** ** D:\用戶手冊\RC30_Manual\5
    # _API\CAN\can_sendDatabox.htm
    '''
    for i in range(len(htmlFiles)):
        print(str(i)+'******'+htmlFiles[i])
        if (str(htmlFiles[i])).__contains__('can_sendDatabox.htm'):
            print('=============='+str(i))
    '''
    ''''''
    for i in range(207,len(htmlFiles)):
    # for i in range(175, 176):
        #print(str(i+1)+'__'+str(htmlFiles[i]))
        # if i==0:
        deleteHtmlHead(i,str(htmlFiles[i]))
        getEnContentAndTrans(i,str(htmlFiles[i]))

        '''
        content = handHtmlContent(i,htmlFiles[i])
        #print(content)
        print('================================')
        print('========3_調(diào)用有道翻譯Start========')
        print('================================')

        transResult = translator(content)
        print(transResult)
        # print(transResult[0])
        # print(transResult[0][0])
        # print(transResult[1][0])
        #
        # print(len(transResult))
        print('===============================')
        print('========3_調(diào)用有道翻譯 End========')
        print('===============================')
        updateHtmlContent(i,htmlFiles[i],transResult)
        '''



if __name__=='__main__':
    main()

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市泡嘴,隨后出現(xiàn)的幾起案子甫恩,更是在濱河造成了極大的恐慌,老刑警劉巖酌予,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件磺箕,死亡現(xiàn)場離奇詭異,居然都是意外死亡抛虫,警方通過查閱死者的電腦和手機松靡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來建椰,“玉大人雕欺,你說我怎么就攤上這事。” “怎么了屠列?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵啦逆,是天一觀的道長。 經(jīng)常有香客問我笛洛,道長夏志,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任撞蜂,我火速辦了婚禮盲镶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蝌诡。我一直安慰自己溉贿,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布浦旱。 她就那樣靜靜地躺著宇色,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颁湖。 梳的紋絲不亂的頭發(fā)上宣蠕,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音甥捺,去河邊找鬼抢蚀。 笑死,一個胖子當著我的面吹牛镰禾,可吹牛的內(nèi)容都是我干的皿曲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼吴侦,長吁一口氣:“原來是場噩夢啊……” “哼屋休!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起备韧,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤劫樟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后织堂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叠艳,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年易阳,在試婚紗的時候發(fā)現(xiàn)自己被綠了虑绵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡闽烙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情黑竞,我是刑警寧澤捕发,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站很魂,受9級特大地震影響扎酷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜遏匆,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一法挨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧幅聘,春花似錦凡纳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至葛超,卻和暖如春暴氏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绣张。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工答渔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侥涵。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓沼撕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親独令。 傳聞我的和親對象是個殘疾皇子端朵,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354