java 请求 google translate
Table of Contents
1 使用Java获取Google Translate结果
1.1 开发环境设置 Eclipse + Maven 插件
- 各种jar仓库 http://mvnrepository.com/
- 创建一个 maven 项目,在 pom.xml 里面添加依赖的包,
让 maven 顺便下载源码: Eclipse Preference->Maven->Download Artiface Sources 打勾
<dependencies> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20160212</version> </dependency> </dependencies>
1.2 使用 commons-httpclient-3.1 进行 https 请求
- commons-httpclient-3.1 文档: http://hc.apache.org/httpclient-3.x/sslguide.html
- 根据上面的文档中的 Customizing SSL in HttpClient ,创建一个 MySSLSocketFactory.java
package com.zc.myhttps; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.SocketFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.params.HttpConnectionParams; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; public class MySSLSocketFactory implements ProtocolSocketFactory { private SSLContext sslcontext = null; private SSLContext createSSLContext() { SSLContext sslcontext = null; try { sslcontext = SSLContext.getInstance("SSL"); sslcontext.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } return sslcontext; } private SSLContext getSSLContext() { if (this.sslcontext == null) { this.sslcontext = createSSLContext(); } return this.sslcontext; } public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose); } public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port); } public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); } public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { if (params == null) { throw new IllegalArgumentException("Parameters may not be null"); } int timeout = params.getConnectionTimeout(); SocketFactory socketfactory = getSSLContext().getSocketFactory(); if (timeout == 0) { return socketfactory.createSocket(host, port, localAddress, localPort); } else { Socket socket = socketfactory.createSocket(); SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); SocketAddress remoteaddr = new InetSocketAddress(host, port); socket.bind(localaddr); socket.connect(remoteaddr, timeout); return socket; } } // 自定义私有类 private static class TrustAnyTrustManager implements X509TrustManager { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] {}; } } }
- 再注册
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443); Protocol.registerProtocol("https", myhttps);
- 最后就可以根据 httpclient 进行正常的 发送请求了:如 TestHttps.java
package com.zc.myhttps; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Iterator; import java.util.Map; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.protocol.Protocol; public class TestHttps { public static String sendByGet(String url) { HttpClient httpclient = null; GetMethod method = null; String result = ""; try { httpclient = new HttpClient(); method = new GetMethod(url); httpclient.executeMethod(method); BufferedReader bs = new BufferedReader(new InputStreamReader( method.getResponseBodyAsStream(), "utf-8")); String line = ""; while ((line = bs.readLine()) != null) { result += line; } System.out.println("==========================获取到的结果"); System.out.println(result); // System.out.println(); // System.out.println("HttpsUtil-sendByGet-url=" + url + "-result=" // + result); } catch (Exception ex) { ex.printStackTrace(); result = "error crm error " + ex.toString(); System.out.println("HttpsUtil-sendByGet-url=" + url + "-result=" + ex.toString()); } finally { if (method != null) { method.releaseConnection(); } } return result; } public static String sendByPost(String url, Map param) { HttpClient httpclient = null; PostMethod method = null; String result = ""; try { httpclient = new HttpClient(); method = new PostMethod(url); if (param != null && !param.isEmpty()) { int len = param.size(); method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); NameValuePair[] np = new NameValuePair[len]; Iterator iter = param.keySet().iterator(); int i = 0; while (iter.hasNext()) { String k = (String) iter.next(); String v = (String) param.get(k); np[i].setName(k); np[i].setValue(v); } method.setRequestBody(np); } httpclient.executeMethod(method); // result = method.getResponseBodyAsString(); BufferedReader bs = new BufferedReader(new InputStreamReader( method.getResponseBodyAsStream(), "utf-8")); String line = ""; while ((line = bs.readLine()) != null) { result += line; } System.out.println("HttpsUtil-sendByPost-url=" + url + "-result=" + result); } catch (Exception ex) { ex.printStackTrace(); result = "error crm error " + ex.toString(); System.out.println("HttpsUtil-sendByPost-url=" + url + "-result=" + ex.toString()); } finally { if (method != null) { method.releaseConnection(); } } return result; } public static void main(String[] args) { Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443); Protocol.registerProtocol("https", myhttps); sendByGet("https://translate.google.com/#en/zh-CN/word"); } }
1.3 进行处理具体的翻译请求
- chrome 下通过调试工具找到具体的请求头,比如查询 "word",会发现如何请求 头:
https://translate.google.com/translate_a/single?client=t&sl=en&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&source=bh&ssel=0&tsel=0&kc=1&tk=253493.388741&q=word
并且可以查看到响应的Response.
- 分析Request,发现主要tk参数比如蛋疼,通过google搜索到一 个:https://github.com/cocoa520/Google_TK 感谢作者把这个tk参数搞出来.
- 有了这个 tk 参数 ,然后加上上面的 Request,就可以很快的构造需要的 url.最后按照上面的httpclient就可以随意处理了.
1.4 使用命令行执行 xxx.class
- 假如依赖 log4j json.jar
java -cp /Users/mac/work/eclipse_luna/com.zc.myhttps/target/classes:/Users/mac/.m2/repository/org/json/json/20160212/json-20160212.jar:/Users/mac/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar com.zc.myhttps.TestHttps
注意:
- -cp 相当于 -classpath
- /Users/mac/work/eclipseluna/com.zc.myhttps/target/classes 这个路径加上 com.zc.myhttps.TestHttps 就可以找到 main 函数所在的文件.
- -cp 后面依赖的jar包的分割符号是":"