好几年前在网上找到一部喜剧片《塔科马消防队》,可能是比较冷门,看到第二季第六集往后第十三集就没字幕了,一直等到前几天还是没有,于是我打算自己去用机翻去解决。
流程很简单,但具体实现对没使用过云API的我还是比较烦的:
- 使用python先把srt文件后缀改成txt。
- 再把所有两行英文的并成一行英文(我是按行读取文件,两行会自动翻译成破坏语义的两句中文)。
- 将每行英文归纳进python的一个列表,用这个列表分割成多个最大长度为100长度的列表分别调用网易有道翻译的API(因为单次传输最高5000字符),再把翻译后的中文重组成和原列表等长的列表。
- 再将原列表插入到确定位置,重新写一个双语字母txt。
一开始翻译用的是translate库,一会就超出限制了,所以我才用的网易有道,新用户送了50块,我翻译了7集大概每集600到1000行句子,还包括了测试也翻译了几千行句子,才用了十块多点。因为是机翻,所以是需要点英文基础的,看看喜剧完全够用了。
调用有道翻译
我略微改了一下官网demo代码,使得connect函数输入输出都是内容一一对应的列表,如果出现问题可以打印response.content.decode('utf-8')可以看到报错码,再根据官网提示去修改就好了。
youdao.py:
# -*- coding: utf-8 -*-
import sys
import uuid
import requests
import hashlib
import time
from importlib import reload
import json
reload(sys)
YOUDAO_URL = 'https://openapi.youdao.com/v2/api'
APP_KEY = ''#填自己的
APP_SECRET = ''#填自己的
def connect(a):
# qArray = ["- Why aren't you treating him?", "- We're just actors!"]
data = {}
data['from'] = 'en'
data['to'] = 'zh-CHS'
data['signType'] = 'v3'
curtime = str(int(time.time()))
data['curtime'] = curtime
salt = str(uuid.uuid1())
signStr = APP_KEY + truncate(''.join(a)) + salt + curtime + APP_SECRET
sign = encrypt(signStr)
data['appKey'] = APP_KEY
data['q'] = a
data['salt'] = salt
data['sign'] = sign
data['vocabId'] = "您的用户词表ID"#不用填
response = do_request(data)
contentType = response.headers['Content-Type']
# print(contentType)
# print(response.content.decode('utf-8'))
json_str = response.content.decode('utf-8')
data = json.loads(json_str)
translations = [item["translation"] for item in data["translateResults"]]
# print(translations)
return translations
def encrypt(signStr):
hash_algorithm = hashlib.sha256()
hash_algorithm.update(signStr.encode('utf-8'))
return hash_algorithm.hexdigest()
def truncate(q):
if q is None:
return None
size = len(q)
return q if size <= 20 else q[0:10] + str(size) + q[size - 10:size]
def do_request(data):
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
return requests.post(YOUDAO_URL, data=data, headers=headers)
if __name__ == '__main__':
# connect(a)
批量修改srt为txt后缀名
clean.py
import os
folder_path = ''#文件路径
os.chdir(folder_path)
for filename in os.listdir(folder_path):
# 将文件后缀改为txt
if filename.endswith(".srt") :
newfile=f'{filename}.txt'
os.rename(filename, newfile)
print(filename)
if filename.endswith(".txt"):
print(filename)
合并英文行
这是原字幕文件,英文有一行的也有两行的,遇到两行的需要合并一下,换行符为'\n'。
clean.py
file = open("Tacoma.FD.S02E13.WEBRip.x264-ION10.srt.txt", "r", encoding="UTF-8")
frlist = file.readlines()
i=0
while i < len(frlist):
# print(i,frlist[i])
if frlist[i].strip().isdigit():
if i + 4 < len(frlist) and frlist[i+4]=='\n':
frlist[i + 2] = ' '.join([frlist[i + 2].replace('\n',''),frlist[i + 3]])
# print(i,frlist[i + 2])
frlist.pop(i+3)
i=i+4
continue
i=i+1
file.close()
将合并好的内容写入新的文件。
file2 = open("13.txt", "w", encoding="UTF-8")
for i in range(0,(len(frlist))):
file2.write(frlist[i])
file2.close()
翻译并添加进新文件
trans.py
import time
import numpy as np
import youdao
import os
folder_path = 'D:\BaiduNetdiskDownload'
os.chdir(folder_path)
betranslted = []
#读取合并好的英文行
file = open("13.txt", "r", encoding="UTF-8")
frlist = file.readlines()
for m in range(0, len(frlist)):
if not frlist[m].strip().isdigit() and not frlist[m].strip().startswith(tuple(str(num) for num in range(10))) and \
frlist[m] != '\n':
# print(m, frlist[m])
betranslted.append(frlist[m])
file.close()
#去除列表中的换行符
def remove_newline(qArray):
for i in range(len(qArray)):
qArray[i] = qArray[i].replace('\n', '')
# 添加列表中的换行符
def add_newline(qArray):
for i in range(len(qArray)):
qArray[i] += '\n'
remove_newline(betranslted)
# print(betranslted)
# 分割成多个小列表和余下的小列表
print(len(betranslted))
chunk_size = 100
chunks = [betranslted[i:i + chunk_size] for i in range(0, len(betranslted), chunk_size)]
# print(chunks)
for i in range(len(chunks)):
#翻译
chunks[i] = youdao.connect(chunks[i])
time.sleep(1)
# print(chunk)
# 将操作后的小列表重新合并成一个新的等长列表
new_list = np.concatenate(chunks).tolist()
add_newline(new_list)
m = 0
while m < len(frlist) and new_list:
if not frlist[m].strip().isdigit() and not frlist[m].strip().startswith(tuple(str(num) for num in range(10))) and \
frlist[m] != '\n':
# print(m, frlist[m])
result = new_list[0]
# print(result)
frlist.insert(m, result)
new_list.pop(0)
# print(m, result)
m = m + 2
else:
m = m + 1
file2 = open("E13.txt", "w", encoding="UTF-8")
for i in range(0, (len(frlist))):
file2.write(frlist[i])
file2.close()
最后就是手动把txt改为srt导入就好了。由于都是单句文本翻译,机翻总是会存在一些小问题,如下,不过总算是把硬盘吃灰的剧集给看完了。