首先我是自己学习的,使用httpclient的jar的版本为4.3.1。
json的版本为json-lib-2.4-jdk15
以上为开发需要的版本
首先呢,我通过网站https://kyfw.12306.cn/otn/login/init
看了半天。。。。嗯,他是https的。为了不每次验证,我首先下载安全证书
然后将证书交给SSLConnectionSocketFactory管理,代码如下:
public static SSLConnectionSocketFactory initssl(){
FileInputStream instream = null;
KeyStore trustStore = null;
SSLContext sslcontext = null;
SSLConnectionSocketFactory sslsf = null;
try {
trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
instream = new FileInputStream(new File("steven/steven.keystore"));
trustStore.load(instream, "1234567".toCharArray());
sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore).build();
sslsf = new SSLConnectionSocketFactory(sslcontext,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
instream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return sslsf;
}
然后呢,我来创建一个httpclient的实力,因为本人懒,所以没写称多线程的。
package com.zz.httpClient;
import java.io.Serializable;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
public class MyhttpClient implements Serializable{
/**
*
*/
private static final long serialVersionUID = -7005306187784613564L;
private static CloseableHttpClient httpclient = null;
private BasicCookieStore cookieStore =null;
public MyhttpClient(){
}
public BasicCookieStore getCookieStore() {
return cookieStore;
}
public void setCookieStore(BasicCookieStore cookieStore) {
this.cookieStore = cookieStore;
}
public CloseableHttpClient getHttpclient(SSLConnectionSocketFactory sslsf) {
if(httpclient == null){
cookieStore = new BasicCookieStore();
httpclient = HttpClients.custom().setDefaultCookieStore(cookieStore).setSSLSocketFactory(sslsf).build();
}
return httpclient;
}
public void setHttpclient(CloseableHttpClient httpclient) {
this.httpclient = httpclient;
}
}
然后呢。我找到了验证码的获取的url:https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand
public static void creatImage() throws ClientProtocolException, IOException{
System.out.println("GetRegist creatImage start");
MyHttpGet myHttpGet = new MyHttpGet();
String url = "https://kyfw.12306.cn/otn/passcodeNew/getPassCodeNew?module=login&rand=sjrand";
HttpEntity entity = myHttpGet.get(url);
File file = new File("image/regist.jpg");
OutputStream outStream = new FileOutputStream(file);
if (entity != null) {
entity.writeTo(outStream);
}
outStream.close();
EntityUtils.consume(entity);
System.out.println("GetRegist creatImage end");
}
好了,我们将验证码下载下来以后,我就可以研究研究登录的事情了。
我写了个通用的post的方法
public static HttpEntity post(String url , List keys,List value) throws ClientProtocolException, IOException{
System.out.println("MyHttpPost logIn is star");
MyhttpClient client = new MyhttpClient();
CloseableHttpClient myhttpclient = client.getHttpclient(sslAndCookie.initssl());
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(20000).build();
CloseableHttpResponse response = null;
HttpPost httpost = new HttpPost(url);
httpost.setConfig(requestConfig);
if(keys.size() != 0){
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
for(int i = 0 ; i < keys.size() ; i++){
nvps.add(new BasicNameValuePair(keys.get(i).toString(),value.get(i).toString() ));
}
httpost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
}
response = myhttpclient.execute(httpost);
HttpEntity entity = response.getEntity();
//EntityUtils.consume(entity);
//response.close();
//httpost.releaseConnection();
System.out.println("MyHttpPost logIn is end");
return entity;
}
以及一个通用的get方法
public HttpEntity get(String url) throws ClientProtocolException, IOException{
System.out.println("MyHttpGet get start");
MyhttpClient client = new MyhttpClient();
CloseableHttpResponse response = null;
CloseableHttpClient myhttpclient = client.getHttpclient(sslAndCookie.initssl());
HttpGet httpget = new HttpGet(url);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(20000).build();
httpget.setConfig(requestConfig);
response = myhttpclient.execute(httpget);
HttpEntity entity = response.getEntity();
//EntityUtils.consume(entity);
//response.close();
//httpget.releaseConnection();
System.out.println("GetRegist get end");
return entity;
}
这2个方法一定要注意,一定要设置过期的时间,要不你就等吧,等到海枯石烂也是你。
通过post方法看到了登录成功,嗯,很不错了,下面获得车次。
通过url:https://kyfw.12306.cn/otn/resources/js/framework/station_name.js
我们可以获得到所有的车次,很舒服。使用json解析下就可以了,json如何解析我就不说了,很简单
通过:https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2014-01-30&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=CET&purpose_codes=0X00这个url我们可以看到。2014年1月30日,应该是北京到上海的所有车次。
其中有一部分是能买的。所以。
public String getTicket(String from_station,String to_station,String train_date,String purpose_codes) throws ClientProtocolException, IOException{
MyHttpGet myHttpGet = new MyHttpGet();
String jsonData = "";
String url = "https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2014-01-30&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=CET&purpose_codes=0X00";
HttpEntity entity = myHttpGet.get(url);
if(entity != null){
InputStream is = entity.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String line = "";
while ((line = br.readLine()) != null) {
jsonData += line;
}
}else{
jsonData = "没有";
}
return jsonData;
}
我们获得所有的能买的车票,嗯。我就做到这一步,他们那个转换我没看明白,我也就写到这,其实我们要的只是安全的回家。
http://download.csdn.net/detail/zilang625/6843243
这个呢,是我的源码下载地址,配合我的说明我相信大部分的人都能看明白。