Java获取12306余票信息(二)

接上

前面我们说到如何用Firefox浏览器抓取数据,并 对json进行了分析,下面就是用Java代码来进行操作。以下代码都没有导入包,有需要自行导入
Java获取12306余票信息(一)
Java获取12306余票信息(二)
Java获取12306余票信息(三)


首先创建JavaBean,用于存放数据
public class TicketingBean {
    private String station_train_code;//车次
    private String from_station_name;//始发站名字
    private String to_station_name;//到达站名字
    private String start_time;//出发时间
    private String arrive_time;//到达时间
    private String lishi;//历时
    private String gjrw;//高级软卧
    private String rw;//软卧
    private String wz;//无座
    private String yw;//硬卧
    private String yz;//硬座
    private String ed;//二等座
    private String yd;//一等座
    private String td;//商务座,特等座
    }
    //getter() , setter() , toString() 方法自行实现
创建ReturnJson类,用于获取json
public class ReturnJson {

    public static String returnJson(String urlString) throws Exception {
        ignoreSSL();//忽略证书   调用自 class IgnoreSSL{}
        URL url = new URL(urlString);
        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();

        InputStreamReader input = new InputStreamReader(con.getInputStream(),
                "utf-8");
        BufferedReader bufferedReader = new BufferedReader(input);

        StringBuffer stringBuffer = new StringBuffer();
        String tempStr = "";

        while ((tempStr = bufferedReader.readLine()) != null) {
            stringBuffer.append(tempStr);
        }
        return stringBuffer.toString();
    }
}
IngoreSSL类,用于忽略证书问题

12306存在安全证书问题,可以在本地安装证书,也可以用这个来忽略证书

public class IgnoreSSL {
        /*
         *Ignore the 12306 certificate.
         *
         * */
    public static void ignoreSSL() throws Exception {
        javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
        javax.net.ssl.TrustManager ignoreSSL = new miTM();
        trustAllCerts[0] = ignoreSSL;
        javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
                .getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc
                .getSocketFactory());
    }

    static class miTM implements javax.net.ssl.TrustManager,
            javax.net.ssl.X509TrustManager {

        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
                                       String authType) throws java.security.cert.CertificateException {
            return;
        }

        public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
                                       String authType) throws java.security.cert.CertificateException {
            return;
        }
    }
}
创建一个GetJsonAndDeal类,用于对获得json进行处理

思路就是把json字符串通过正则表达式处理,取出我们需要的,然后放进一个List,并返回

public class GetJsonAndDeal {
	/*
	 *分析返回的json得到以下信息
	 * info.get(3);// 车次信息
	 *  info.get(6); // 出发地代号
	 *  info.get(7);// 目的地代号
	 *  info.get(8);// 出发时间 
	 *  info.get(9); // 到达时间 
	 *  info.get(10);// 历时 
	 *  info.get(11); // Y
	 * info.get(21); // 高级软卧 
	 * info.get(23); // 软卧 
	 * info.get(26); // 无座
	 * info.get(28); // 硬卧 
	 * info.get(29); // 硬座 
	 * info.get(30); // 二等座
	 * info.get(31);// 一等座
	 *  info.get(32); // 商务,特等座
	 */

	// 获得余票信息的json字符串,并进行处理
	// https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=2018-01-22&leftTicketDTO.from_station=NJH&leftTicketDTO.to_station=HZH&purpose_codes=ADULT
	
	public static List<String> getTicketsInfo(String train_date, String from_station, String to_station, String purpose_codes) throws Exception {
		List<String> ticketsInfo_list = new ArrayList<>();
		List<String> jsonLists = new ArrayList<>();
		String urlStr = "https://kyfw.12306.cn/otn/leftTicket/queryO?"
				+ "leftTicketDTO.train_date="
				+ train_date
				+ "&leftTicketDTO.from_station="
				+ from_station
				+ "&leftTicketDTO.to_station="
				+ to_station
				+ "&purpose_codes="
				+ purpose_codes;
		String ticketsInfo_json = returnJson(urlStr);  //调用class ReturnJson.returnJson(String);获取json
		JSONObject jsonObject = JSONObject.fromObject(ticketsInfo_json);//将获取的json字符串转换为json对象
		JSONArray jsonArray_result = jsonObject.getJSONObject("data").getJSONArray("result");//取出result
		JSONObject jsonObject_map = jsonObject.getJSONObject("data").getJSONObject("map");//取map
		Pattern p = Pattern.compile("(^[^\\|]).*");//正则表达式,不匹配 分割符 `|`
		for (Object object : jsonArray_result) {
			Matcher m = p.matcher(object.toString());
			if (m.find()) {
				jsonLists.add(m.group(0));  //匹配后放到jsonList,每一条数据就是一组
			}
		}
		for (int i = 0; i < jsonLists.size(); i++) {     //遍历list
			String tempStr = jsonLists.get(i).toString();  //将每一条list转换为String 
			String tempArr[] = tempStr.split("\\|");  //进行分割
			List<String> info = new ArrayList<>();
			for (String str : tempArr) { 
				info.add(str);              //遍历,放入list
			}
			List<String> ticketsInfo_list_temp = new ArrayList<>(); //临时的list,将info里的数据分别存到list中,组成一条我们需要的数据
			ticketsInfo_list_temp.add(info.get(3));
			ticketsInfo_list_temp.add((String) jsonObject_map.get(info.get(6)));
			ticketsInfo_list_temp.add((String) jsonObject_map.get(info.get(7)));//得到车站名字
			ticketsInfo_list_temp.add(info.get(8));
			ticketsInfo_list_temp.add(info.get(9));
			ticketsInfo_list_temp.add(info.get(10));
			ticketsInfo_list_temp.add(info.get(21));
			ticketsInfo_list_temp.add(info.get(23));
			ticketsInfo_list_temp.add(info.get(26));
			ticketsInfo_list_temp.add(info.get(28));
			ticketsInfo_list_temp.add(info.get(29));
			ticketsInfo_list_temp.add(info.get(30));
			ticketsInfo_list_temp.add(info.get(31));
			ticketsInfo_list_temp.add(info.get(32));
			ticketsInfo_list.add(ticketsInfo_list_temp.toString()); //最后放到list
		}
		return ticketsInfo_list;
	}

创建QueryTickets类

public class QueryTickets {
	
	// 从处理好的list中查找,存入javabean
    public static List<TicketingBean> queryTickets(String train_date,String from_station,String to_station, String purpose_codes) throws Exception {
		List<String> list = getTicketsInfo(train_date, from_station,to_station, purpose_codes);
        Pattern p = Pattern.compile("[^\\[].*[^\\]]");
		Matcher m ;
		TicketingBean bean;
		List<TicketingBean> beanList = new ArrayList<>();
		for(int i =0 ; i<list.size();i++){
			m = p.matcher(list.get(i));
			if(m.find())
				m.group(0);
			JSONArray jsonArray = JSONArray.fromObject(m.group(0).split(","));
			bean = new TicketingBean();
			BeanUtils.setProperty(bean, "station_train_code",jsonArray.get(0).toString());
			BeanUtils.setProperty(bean, "from_station_name",jsonArray.get(1).toString());
			BeanUtils.setProperty(bean, "to_station_name",jsonArray.get(2).toString());
			BeanUtils.setProperty(bean, "start_time",jsonArray.get(3).toString());
			BeanUtils.setProperty(bean, "arrive_time",jsonArray.get(4).toString());
			BeanUtils.setProperty(bean, "lishi",jsonArray.get(5).toString());
			BeanUtils.setProperty(bean, "gjrw",jsonArray.get(6).toString());
			BeanUtils.setProperty(bean, "rw",jsonArray.get(7).toString());
			BeanUtils.setProperty(bean, "wz",jsonArray.get(8).toString());
			BeanUtils.setProperty(bean, "yw",jsonArray.get(9).toString());
			BeanUtils.setProperty(bean, "yz",jsonArray.get(10).toString());
			BeanUtils.setProperty(bean, "ed",jsonArray.get(11).toString());
			BeanUtils.setProperty(bean, "yd",jsonArray.get(12).toString());
			BeanUtils.setProperty(bean, "td",jsonArray.get(13).toString());
			beanList.add(bean);
		}
		return beanList;
	}
}
前面说到过,车站名字代号,写一个getCodeByName方法,放到GetJsonAndDeal类中
public static String getCodeByName(String stationName) throws Exception {
		Map<String,String> map = new HashMap<>();
		//获取json写入字符串
		String urlStr = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9030";
		String nameString = returnJson(urlStr);
		//第一次处理json字符串
		String[] nameArr = nameString.split("\\@");//获得json由@分割开
		Pattern p = Pattern.compile("[^\\@].*\\|.*");
		List<String> jsonLists = new ArrayList<String>();
		for (Object object : nameArr) {
			Matcher m = p.matcher(object.toString());
			if (m.find()) {
				jsonLists.add(m.group(0));
			}
		}
		//第二次处理json字符互串
		for (int i = 0; i < jsonLists.size(); i++) {
			String temp = jsonLists.get(i).toString();
			String jsonArr[] = temp.split("\\|");
			List<String> mapLists = new ArrayList<String>();
			for (Object object : jsonArr) {
				mapLists.add(object.toString());
			}
			map.put(mapLists.get(1), mapLists.get(2));
		}
		return map.get(stationName);
	}
测试
@Test
    public void test() throws Exception {
        System.out.println(queryTickets("2018-03-23",getCodeByName("北京"),getCodeByName("上海"),"ADULT"));
    } 

写在最后

以上就是整个思路,获得天气啊什么的都是差不多的。源码我已经贴到了GitHub上
wufeiwua.github
当然还用到了一些工具包,JDK不自带的,GitHub 下 lib 文件夹下面都有,有需要的可以下载
主要是:

  • commons-beanutils-1.7.0.jar(commons一类)
  • json-lib-2.4-jdk15.jar(json处理一类的)
  • json-simple-1.1.1,jar

完结

我也是新手一个,可能说的有误,希望指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值