原因:有很多单词要背,然后一开始一个一个查单词意思,令人智熄,于是心想批量翻译。
准备工作
- 一台装有pythonista的iPad (当然用电脑肯定是可以的,只不过我弄的时候也是想看看iPad写python体验怎么样。)
- 注册一个有道智云账户,创建一个自然语言翻译示例和应用,并两者进行绑定,需要利用应用ID和应用密钥进行有道翻译API的调用
- 当然还得有待翻译单词文件,一行存储一个单词
参考资料
写的时候百度了一下利用有道API的示例,找到这个博客,但是是老版本的API调用,也是可以实现翻译的,但是我修改成读取文件进行批量翻译的时候,发现到后面会报错,原因是因为有访问频率限制,好像是一个小时只允许进行1000次翻译操作,然后我就自己注册了一个有道智云的账号,官方给了调用API的资料。
API的调用主要是需要如下几个字段
- appKey:就是在有道智云里面创建的应用的应用ID;
- secretKey:创建的应用的应用密钥;
- fromLang:源语言,此处是’EN’;
- toLang:目标语言,此处是’zh-CHS’;
- salt:随机数,利用
random.randint()
产生; - sign:签名,通过
md5(appKey+q+salt+应用密钥)
生成 - q:待翻译源语言单词
组合成如下的URL形式进行API调用:
http://openapi.youdao.com/api?q=”待翻译单词“&from=EN&to=zh_CHS&appKey=”应用ID“&salt=”随机数“&sign=签名
如对单词good进行翻译,API调用URL如下(官网给的例子,应用ID、应用密钥和签名是无效的):
http://openapi.youdao.com/api?q=good&from=EN&to=zh_CHS&appKey=ff889495-4b45-46d9-8f48-946554334f2a&salt=2&sign=1995882C5064805BC30A39829B779D7B
返回的API调用结果为json格式,如下所示为翻译good的结果(官网给的例子):
{
"errorCode":"0",
"query":"good", //查询正确时,一定存在
"translation": [ //查询正确时一定存在
"好"
],
"basic":{ // 有道词典-基本词典,查词时才有
"phonetic":"gʊd"
"uk-phonetic":"gʊd" //英式音标
"us-phonetic":"ɡʊd" //美式音标
"uk-speech": "XXXX",//英式发音
"us-speech": "XXXX",//美式发音
"explains":[
"好处",
"好的"
"好"
]
},
"web":[ // 有道词典-网络释义,该结果不一定存在
{
"key":"good",
"value":["良好","善","美好"]
},
{...}
]
],
"dict":{
"url":"yddict://m.youdao.com/dict?le=eng&q=good"
},
"webdict":{
"url":"http://m.youdao.com/dict?le=eng&q=good"
},
"l":"EN2zh-CHS",
"tSpeakUrl":"XXX",//翻译后的发音地址
"speakUrl": "XXX" //查询文本的发音地址
}
我的目的就是从返回的json数据中提取basic->explains
的翻译结果;如果不存在,则提取translation
结果;如果都不存在,则返回‘没有翻译结果’。并将源单词和翻译结果组合存储到文件中。
代码
import urllib.request
import urllib.parse
import json
import hashlib
import random
class YoudaoFanyi():
"""
有道智云API
"""
appKey = '有道智云应用ID'
secretKey = '有道智云应用密钥'
fromLang = 'EN'
toLang = 'zh-CHS'
URL = "http://openapi.youdao.com/api?"
def translate(self, text):
"""
翻译方法,传入要翻译的文本,返回结果字典
"""
# 参数
salt = random.randint(1, 65536)
sign = self.appKey+text+str(salt)+self.secretKey
m1 = hashlib.md5()
m1.update(sign.encode("utf-8"))
sign = m1.hexdigest()
params = {'appKey': self.appKey, 'from': self.fromLang, 'to': self.toLang, 'salt': salt, 'sign': sign ,'q': text}
#params = {'keyfrom': self.KEY_FROM, 'key': self.KEY, 'type': self.TYPE, 'doctype': self.DOC_TYPE, 'version': self.VERSION ,'q': text}
resp = urllib.request.urlopen(self.URL, urllib.parse.urlencode(params).encode(encoding='utf_8'))
data = resp.read().decode("utf_8")
# print('有道API翻译内容:%s'%data)
return json.loads(data)
def format_for_command(self, text):
"""
为命令行格式化翻译结果
"""
data = main(text)
# TODO:格式化字符串
if data:
# print('有道翻译:')
# print('\t原文本:', data.get('query', text))
explains = data.get("basic")
translation = data.get('translation',None)
if explains:
explains = explains.get("explains")
s = data.get('query', text) + ':\t' + ','.join(explains)
print("explains:"+s)
return s
elif translation:
s = data.get('query', text) + ':\t' + ','.join(translation)
print("trans:"+s)
return s
else:
print('未找到该词')
return 'no explanation'
def main(text):
if text and text.strip() != '':
return YoudaoFanyi().translate(text)
if __name__ == '__main__':
print("------------Word translation-----------")
file_in = "./word.txt"
file_out = "./word_fanyi.txt"
fout = open(file_out, 'w', encoding='utf-8')
with open(file_in, 'r') as f:
line = f.readline().strip()
while line:
if line:
s = YoudaoFanyi().format_for_command(line)
fout.write(s+"\n")
line = f.readline().strip()
fout.close()
结果
利用pythonista代码运行结果