google翻译 中文文本大量翻译成英文

本文分享如何应对大量中文文本翻译需求,尤其是在google翻译API收费后,利用开源项目进行批量翻译,同时解决字符串长度限制和防止IP被禁的问题。

如题,我遇到了一下情况,需要将大量wiki百科的中文文本翻译成英文

面对这个问题,有以下几点困难

  • google 翻译的API 已经开始收费了。不在提供免费的API服务。
  • 纯手工在google翻译的网页上翻译,对程序猿来说,你是认真的吗?
  • 在使用github上的开源项目时,发现即使通过web脚本调用google网页翻译的免费服务时,依然存在着字符串长度限制,已经会发生长度超出,翻译失败。

在我解决了这个问题之后,我想还是在这里和大家分享一下吧。

首先,先介绍下使用的开源项目:googletrans
具体如下下载就请参考项目的介绍文档。

假如你就是简单翻译几句短文本,
查看 样例 就完全可以了。

>>> from googletrans import Translator
>>> translator = Translator()
>>> translator.translate('안녕하세요.')
# <Translated src=ko dest=en text=Good evening. pronunciation=Good evening.>
>>> translator.translate('안녕하세요.', dest='ja')
# <Translated src=ko dest=ja text=こんにちは。 pronunciation=Kon'nichiwa.>
>>> translator.translate('veritas lux mea', src='la')
# <Translated src=la dest=en text=The truth is my light pronunciation=The truth is my light>

如果你和我一样需要翻译大量的文本,那么请看下面?

(以下代码处理几百个文件依然没有被禁IP,请自己酌情改小sleep时间,以加快翻译速度)

#首先导入需要的包
from googletrans import Translator
from tqdm import tqdm
import os
import random
import time
import re

#声明源文件目录 和 生成文件的放置目录
home = os.environ['HOME']
path = home + "/study/project/chineseSegment/artifical/test"
dest = home + "/study/project/chineseSegment/artifical/en"
files = os.listdir(path)
s = []

# 把长文本切分成短文本,当时google担心会检查文本长度,所以随机了长度,应该没这么严格,想写成固定的也可以
def getText(string):
    list = []
    randline = random.random() * 500 
    while len(string) > 1500:
        index = string.find("\n",int(randline)+1000)
        if index is not None:
            list.append(string[0:index])
            string = string[index:]
    list.append(string)
    return list
#保存翻译完后的文件
def save2file(title,result):
    with open(dest+"/"+title,'w') as d:
        for en in result:
            d.write(en)
        d.close
# 在文本中无法识别的表情包会使得翻译产生错误,对文本过滤
emoji_pattern = re.compile(
    u"(\ud83d[\ude00-\ude4f])|"  # emoticons
    u"(\ud83c[\udf00-\uffff])|"  # symbols & pictographs (1 of 2)
    u"(\ud83d[\u0000-\uddff])|"  # symbols & pictographs (2 of 2)
    u"(\ud83d[\ude80-\udeff])|"  # transport & map symbols
    u"(\ud83c[\udde0-\uddff])|"  # flags (iOS)
    u"((-{0,1}[{}]-{0,1}))|"     # 我的项目逻辑需要,可删除
    u"([R efn]|)"				 # 我的项目逻辑需要,可删除
    "+", flags=re.UNICODE)

def remove_emoji(text):
    return emoji_pattern.sub(r'', text)

# 打印单个文本分段后的翻译进度
def printProcess(cnt,txt_len,tatal_size,error):
    content = "file completed "+str(cnt)+"/"+str(txt_len)
    print(content,end="\r")

# 在短文本翻译出错后,用二分法找到错误地方,并舍去无法翻译的句子
def binarySearch(text):
    mid = (int) (len(text) *1.0/2)
    result = []
    splitIndex = text.find("。",mid)
    if splitIndex == -1 or splitIndex == 0:
        return result
    
    pre = text[0:splitIndex]
    after = text[splitIndex+1:]
    try:
        result = result+append(pre)
    except:
        result = result+binarySearch(pre)
    
    try:
        result = result+append(after)
    except:
        result = result+binarySearch(after)
        
    return result 

# 翻译文本
def getTranslateTextList(txt):
    result = []
    time.sleep(1)
    cnt = 0
    txtsize = 0
  
    for text in txt:
        try:
            cnt += 1
            text = remove_emoji(text)
            txtsize += len(text)
            translate = Translator()
            en = translate.translate(text=text, dest='en').text 
            result.append(en)
            printProcess(cnt,len(txt),txtsize,error)
            slptimes = random.random()  #我可能想太多,怕固定的sleep还是会被google检查出来,所以随机了一个时间
            time.sleep(1.2 + slptimes) 
        except Exception as e:
            result = result + binarySearch(text)
    return result

## 正式开始 mian()
for file in tqdm(files):
    if not os.path.isdir(file):
        title = Translator().translate(text=file, dest='en').text 
        try:
            with open(path+"/"+file,'r') as f:
                string = f.read()
                f.close()
            txt = getText(string)
            print("analysis:"+title)
            result = getTranslateTextList(txt)
            save2file(title,result)
        except Exception as e:
                print(str(e))
                continue
    time.sleep(30) #为了保证不被google屏蔽IP,不得已设置了一个超长时间的sleep,可以按情况改小

如果 在这过程中遇到问题,可以去github的项目issue中找一下,我记得我当时运行这个项目的时候遇到了问题,通过issue的方法解决了,但是这会儿想不起来当时的问题是什么了。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值