众所周知,Google Translate API在几年前就停止服务了,并提供了收费的版本GOOGLE TRANSLATE API。
之前尝试用http请求来翻译(如此链接),再解析返回的字符串([[["xxx",….),xxx即为所需的内容。
这种方式对于非频繁的请求还是ok的,但是实时翻译就经常会遇到返回403的情况,即使添加User-Agent、设置延时也无济于事。
最近更是变本加厉,非频繁的请求偶尔也会收到403的结果。
网上搜了一大圈,也没有看到很好的解决办法,屌丝又不想花钱买服务(毕竟使用量不大),只能换工具了。
那么换哪个翻译工具好呢?Alternative to Google Translate API?介绍了多种翻译API,参考了下面的评论,最终选择的微软的翻译API。
微软的翻译API支持的语言没有Google的多,比如不支持缅甸语(my)、老挝语(lo)、尼泊尔语(ne)、孟加拉语(bn)、格鲁吉亚语(ka)等,不过只能退而求其次了。
废话说了太多,现在进入正题,介绍下Microsoft Translator API的使用方法(参考此博客)。
注册微软账号
(如果已经有微软账号,可以跳过此步)
进入注册页,填入需要的信息,进行注册。
注意填写一个可以收到邮件的User name,注册成功后,需要到邮箱进行验证才能正常使用后面的功能。
登陆
进入Microsoft Translator页面,点击右上角的登陆,输入用户名(邮箱)和密码登陆。
如果是首次使用Microsoft Azure Marketplace,会提示先注册,如下图
填上信息点继续就ok了。
这里有个要注意的地方,这个“继续”按钮,是用了js的,而这个js地址是ajax.aspnetcdn.com,国内有可能获取不到,如果你发现点了半天“继续”没反应,按下F12,看看是不是js没获取到,Console那里有一堆错误提示。
选择合适的翻译服务
登陆/注册后会回到之前的页面,右侧有一列服务,根据需求选择对应的服务:
咱就选第一项啦
查看余量
进入我的数据可以查看剩余的使用量
注册应用
进入应用注册页,填写必要的信息
其中,重定向URI填写一个有效的URL即可,如https://code.google.com/。
注册成功后,可以看到客户端ID(Client ID)和客户端密钥(Client Secret),这两项是后面需要用到的。
开发程序
这些都搞定后,就可以来开发程序了。
对于Java程序员来说,有位大神已经对API进行了封装,直接使用就可以了。
首先引入依赖:
<dependency><groupId>com.memetix</groupId><artifactId>microsoft-translator-java-api</artifactId><version>0.6.2</version><type>jar</type>
</dependency>
接着coding:
import com.memetix.mst.language.Language;
import com.memetix.mst.translate.Translate;public class Main {public static void main(String[] args) throws Exception {// Set your Windows Azure Marketplace client info - See http://msdn.microsoft.com/en-us/library/hh454950.aspxTranslate.setClientId(/* Enter your Windows Azure Client Id here */);Translate.setClientSecret(/* Enter your Windows Azure Client Secret here */);String translatedText = Translate.execute("Bonjour le monde", Language.FRENCH, Language.ENGLISH);System.out.println(translatedText);}
还不快尝试下
注意事项
1.访问Microsoft Translator API需要使用Access Token,获取后的有效时间是10分钟,为了避免访问失败,官方建议在超时时间之前重新请求一个。
这个封装的API也是这么做的,如下面代码:
/*** Forms an HTTP request, sends it using GET method and returns the result of the request as a String.* * @param url The URL to query for a String response.* @return The translated String.* @throws Exception on error.*/private static String retrieveResponse(final URL url) throws Exception {if(clientId!=null&&clientSecret!=null&&System.currentTimeMillis()>tokenExpiration) {String tokenJson = getToken(clientId,clientSecret);Integer expiresIn = Integer.parseInt((String)((JSONObject)JSONValue.parse(tokenJson)).get("expires_in"));tokenExpiration = System.currentTimeMillis()+((expiresIn*1000)-1);token = "Bearer " + (String)((JSONObject)JSONValue.parse(tokenJson)).get("access_token");}//如下省略}
但是它只提前了1毫秒,就是说,如果到这个逻辑的时候,并未超时,而下面到实际请求之间消耗的时间超过1毫秒,就超时了。
超时后,微软的API仍然会返回200,但是内容是“ArgumentException: The incoming token has expired. Get a new access token from the Authorization Server. : ID=xxx”,如果没注意,错把它当翻译结果,就悲剧了。
2.根据官方说明,当余量用尽时,返回的翻译内容是“Quota Exceeded”,因此这个也需要判断下。
(还没有用尽过余量,这个待确认)