前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手把手教你用Python脚本调用 DeepL API Pro 进电子书的行进行中英文自动翻译

手把手教你用Python脚本调用 DeepL API Pro 进电子书的行进行中英文自动翻译

作者头像
Python进阶者
发布2021-12-13 14:39:51
2.3K0
发布2021-12-13 14:39:51
举报

大家好,我是我是Python进阶者。

一、前言

前几天有个叫【张茜】的粉丝找我看了一个代码,关于电子书中英文自动翻译的,感觉挺有意思,这里拿出来给大家分享下。

二、简介

这个小项目是git上一个叫【xiaolai】的大佬分享的,看上去还是挺新的,发布不太久,14天前发布的。

一本书中文译文大约 39 万字的书,差不多用 1.5 小时就可以处理完毕(包括基本的格式编辑),这速度恐怖如斯!下面一起来看看这款神器的使用方法吧!

三、电子书格式转换路径

首先,需要将电子书从 Kindle 中导出来,并用 ePubor 进行 deDRM,而后将电子书转换成 epub 文件。

我都是在 Amazon 上直接买,而后在电脑上安装一个老版本的 Kindle App,用鼠标右键点击书名,下载,并不打开该电子书,而后退出 Kindle。

ePubor Ultimate 也是个收费软件,能把旧版 Kindle 下载的电子书的 DRM 去掉;将 awz 文件转换成 epub 文件。(可参考这个网页)

然后,再用免费软件 Calibre 将 epub 转换成 htmlz 文件(一个压缩包)。(我尝试过使用命令行工具包 pandoc,但,比较之后,发现 Calibre 在保留样式方面可能更好一点……)

在 Terminal 里用 unzip 命令解开 htmlz 压缩包。

四、选择 html 格式作为翻译格式的原因

可以保留书中大量的脚注、尾注及其链接;DeepL 有专门的 API 参数处理 xml tag,tag_handling="xml";

可以通过 css 文件随意设置显示样式,比较灵活;

可以通过插入 javascript 函数指定某种特定语言的显示(比如,只显示中文);

可以用来作为源文件转换成任意格式的电子书……

另外,在调用 tag_handling="xml" 之后,DeepL API 返回的译文非常规整,能够保留所有 html tag;并且,“返回字符串” 与 “原字符串” 相同,可以作为一个判断依据 —— 该行有没有被翻译,如果没有,在生成的译文 html 文件中,该行没必要重复出现……

五、清理 html

html 文件整理起来比较麻烦,一个比较方便的手段是使用 BeautifulSoup 模块。BeautifulSoup 本来是爬虫工具,但,它又很方便的手段可以清理 html 文件。

以下脚本主要完成以下工作:

首先将 html 文件里的所有 \n 去掉;将所有

单独放在一行;将所有

也单独放在一行;将

内部的所有 \n 全都去掉;并在之前加上一个空行;…… 当然,你可以在这里做更多你自己喜欢做的格式清理。为了方便起见,pathsource_filename 以及 target_filename 都单独指定。代码如下:

代码语言:javascript
复制
import bs4
import re

path = "John Law/" # 文件夹名称末尾得有 /
source_filename = "index.html"
target_filename = "index2.html"

html = open(path+source_filename)
htmltext = html.read()

soup = bs4.BeautifulSoup(htmltext)

# 将所有的 \n 去掉……
htmltext = str(bs4.BeautifulSoup(htmltext)).replace("\n", "")

# <h... 之前添加空行
pttn = r'<h'
rpl = r'\n\n<h'
re.findall(pttn, htmltext)
htmltext = re.sub(pttn, rpl, htmltext)

# <div... 之前添加空行
pttn = r'<div'
rpl = r'\n\n<div'
re.findall(pttn, htmltext)
htmltext = re.sub(pttn, rpl, htmltext)

# </div> 之前添加空行
pttn = r'</div>'
rpl = r'\n\n</div>'
re.findall(pttn, htmltext)
htmltext = re.sub(pttn, rpl, htmltext)

# <p... 之前添加空行
pttn = r'<p'
rpl = r'\n\n<p'
re.findall(pttn, htmltext)
htmltext = re.sub(pttn, rpl, htmltext)

fileSave = open(path+target_filename, "w")
fileSave.write(htmltext)
print(htmltext)

六、逐行提交 DeepL API Pro 进行翻译

将清理过的 html 交给以下脚本,逐行提交给 DeepL 翻译,并返回。

为了方便起见,path 和 source_filename 以及 target_filename 都单独指定。

lines 是 source_filename 的内容 new_lines 是将要放到 target_filename 中的内容 startline 是 “从哪一行开始提交 DeepL 翻译” endline 是 “到哪一行开始结束提交 DeepL 翻译”。代码如下:

代码语言:javascript
复制
import re
import requests

auth_key = "<your DeepL API Pro authentication key>" # 注意,要订阅的是 DeepL API Pro
target_language = "ZH"  ## 当然,你可以将目标语言设置成任何 DeepL 支持的语言

path = "John Law/" # 文件夹名称末尾得有 /
source_filename = "index2.html" # 上一步生成的文件,成为这一步的 “源文件”
target_filename = "index3.html"

def translate(text):
    result = requests.get( 
       "https://api.deepl.com/v2/translate",
       params={ 
         "auth_key": auth_key,
         "target_lang": target_language,
         "text": text,
         "tag_handling": "xml", # 这个参数确保 DeepL 正确处理 html tags
       },
    ) 
    return result.json()["translations"][0]["text"]

def add_language_tag_en(html):
    pttn = re.compile(r'^<(.*?) class="(.*?)">', re.M)
    rpl = r'<\1 class="\2 en">'
    re.findall(pttn, html)
    html = re.sub(pttn, rpl, html)
    return html

def add_language_tag_cn(html):
    pttn = re.compile(r'^<(.*?) class="(.*?)">', re.M)
    rpl = r'<\1 class="\2 cn">'
    re.findall(pttn, html)
    html = re.sub(pttn, rpl, html)
    return html

lines = open(path+source_filename, "r").readlines()


new_lines = []
line_count = 0
startline = 16
endline = 4032

for line in lines:
    line_count += 1
    if line_count < startline or line_count > endline or line.strip() == '':
        new_lines.append(line)
        print(line)
        continue        
    
    succeeded = False
    while not succeeded:
        # 以下比较粗暴的 try... except,用来防止执行过程中出现 DeepL 连接错误而导致翻译任务中断……
        try:
            line_translated = translate(line)
            # 以下一行确保将返回的字符串转换成一整行,而非含有 \n 的多行文本
            line_translated = line_translated.replace("\n", "")
            
            succeeded = True
        except:
            succeeded = False
    
    if line.strip() == line_translated.strip(): 
        #返回的字符串与原字符串相同,说明 html tag 之间的内容无需翻译
        new_lines.append(line)
        print(line)
    else:
        line = add_language_tag_en(line)
        line_translated = add_language_tag_cn(line_translated)
        new_lines.append(line)
        print(line)
        new_lines.append(line_translated)
        print(line_translated)

with open(path+target_filename, 'w') as f:
    f.write("\n".join(new_lines))

七、结果展示

1、运行代码之后,会自动读取待翻译的文件,然后进行翻译,如下图所示:

2、运行完程序之后,可以得到想要的结果,如下图所示:

八、总结

大家好,我是Python进阶者。这篇文章主要给大家介绍了使用Python脚本调用DeepL API Pro进电子书的行中英文自动翻译的方法,代码亲测可行,欢迎大家积极尝试,下次再遇到需要自动翻译的时候,不妨调用下这个API,兴许事半功倍呢!

------------------- End -------------------

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-12-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python爬虫与数据挖掘 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、简介
  • 三、电子书格式转换路径
  • 四、选择 html 格式作为翻译格式的原因
  • 五、清理 html
  • 六、逐行提交 DeepL API Pro 进行翻译
  • 七、结果展示
  • 八、总结
相关产品与服务
机器翻译
机器翻译(Tencent Machine Translation,TMT)结合了神经机器翻译和统计机器翻译的优点,从大规模双语语料库自动学习翻译知识,实现从源语言文本到目标语言文本的自动翻译,目前可支持十余种语言的互译。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档