本文章为原创文章,转载请注明,欢迎评论和改正。
一,分析
之前所用的直接通过HTML中的元素值来爬取一些网页上的数据,但是一些比较敏感的数据,很多正规网站都是通过json数据存储,这些数据通过HTML元素是爬取不到的,所以只能通过json数据的api接口来爬取数据。
二,网站处理
1,打开去哪儿网的网站https://train.qunar.com/,找到火车票查询,输入起点终点和日期,查询。
2,右击打开审查元素,点击network
3,刷新网页,找到XHR,点击链接
4,找到s2sBeanList这一属性,打开即为所需要的数据
header里有所需的地址
三,项目结构
1,所需jar包,基本是分析json数据的时候用到
2,项目目录结构
四,代码分析
1,解析URL地址,并以将json数据转化为String类型返回
public static String geturl(String url){ StringBuffer json = new StringBuffer(); try { URL u = new URL(url); URLConnection yc = u.openConnection(); //读取返回的数据 BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream(),"UTF-8")); String inputline = null; while((inputline=in.readLine())!=null){ json.append(inputline); } in.close(); } catch (Exception e) { e.printStackTrace(); } //将StringBuffer转化为json格式的字符串 String jsonStr=json.toString();
//将不规范的字符串形式的json数据规范化 jsonStr=jsonStr.substring(jsonStr.indexOf("{"),jsonStr.length()-1); return jsonStr; }
2,将地址转化为经纬度的方法(用到即可取)
public static String getLngLat(String address) { StringBuffer json = new StringBuffer(); try { URL u = new URL("http://restapi.amap.com/v3/geocode/geo?address="+address+"&output=JSON&key=7f4ffae4074e8b8e4d147190527a4b72"); URLConnection yc = u.openConnection(); //读取返回的数据 BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream(),"UTF-8")); String inputline = null; while((inputline=in.readLine())!=null){ json.append(inputline); } in.close(); } catch (Exception e) { e.printStackTrace(); } String jsonStr=json.toString(); JSONObject jsonObject = JSONObject.fromObject(jsonStr);
//判断是否有这个点 if(jsonObject.getJSONArray("geocodes").size()>0) return jsonObject.getJSONArray("geocodes").getJSONObject(0).get("location").toString(); else return null; }
3,查询火车票的代码
public static List<TrainMess> loadTrainRoute(String startPoint,String endPoint,String date) { String strUrl="https://train.qunar.com/dict/open/s2s.do?callback=jQuery17203917861486539813_1558231852669" + "&dptStation="+startPoint+"&arrStation="+endPoint+"&date="+date //日期格式2019-05-20 + "&type=normal&user=neibu&source=site&start=1&num=500&sort=3&_=1558231852892"; //调用方法将url转为json格式的字符串 String jsonStr=geturl(strUrl); JSONObject jsonObject = JSONObject.fromObject(jsonStr); JSONArray jArray=jsonObject.getJSONObject("data").getJSONArray("s2sBeanList"); for(int i=0;i<jArray.size();i++) { //循环遍历所有车次 jsonObject=(jArray.getJSONObject(i)); System.out.println("起点:"+startPoint); System.out.println("起点经纬度:"+getLngLat(startPoint)); //getLngLat 调用将地址转化为经纬度的方法 System.out.println("车次"+jsonObject.get("trainNo").toString()); System.out.println("车站:"+jsonObject.get("dptStationName")+"-"+jsonObject.get("arrStationName")); System.out.println("时间段:"+jsonObject.get("dptTime")+"-"+jsonObject.get("arrTime")); System.out.println("一等座的价格:"+jsonObject.getJSONObject("seats").getJSONObject("一等座").get("price")); System.out.println("一等座的剩余票数:"+jsonObject.getJSONObject("seats").getJSONObject("一等座").get("count")); } return null; }
jsonObject=(jArray.getJSONObject(i));为循环遍历所有车次
五,完整代码
package test; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.List; import com.travel.bean.TrainMess; import com.travel.util.AddressLngLatExchange; import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class GetTrainTest { //解析URL public static String geturl(String url){ StringBuffer json = new StringBuffer(); try { URL u = new URL(url); URLConnection yc = u.openConnection(); //读取返回的数据 BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream(),"UTF-8")); String inputline = null; while((inputline=in.readLine())!=null){ json.append(inputline); } in.close(); } catch (Exception e) { e.printStackTrace(); } //将StringBuffer转化为json格式的字符串 String jsonStr=json.toString(); jsonStr=jsonStr.substring(jsonStr.indexOf("{"),jsonStr.length()-1); return jsonStr; } //调用将地址转化为经纬度的方法 public static String getLngLat(String address) { StringBuffer json = new StringBuffer(); try { URL u = new URL("http://restapi.amap.com/v3/geocode/geo?address="+address+"&output=JSON&key=7f4ffae4074e8b8e4d147190527a4b72"); URLConnection yc = u.openConnection(); //读取返回的数据 BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream(),"UTF-8")); String inputline = null; while((inputline=in.readLine())!=null){ json.append(inputline); } // System.out.println(json); in.close(); } catch (Exception e) { e.printStackTrace(); } String jsonStr=json.toString(); JSONObject jsonObject = JSONObject.fromObject(jsonStr); // System.out.println(jsonObject.getJSONArray("geocodes")); if(jsonObject.getJSONArray("geocodes").size()>0) return jsonObject.getJSONArray("geocodes").getJSONObject(0).get("location").toString(); else return null; } @SuppressWarnings("null") public static List<TrainMess> loadTrainRoute(String startPoint,String endPoint,String date) { String strUrl="https://train.qunar.com/dict/open/s2s.do?callback=jQuery17203917861486539813_1558231852669" + "&dptStation="+startPoint+"&arrStation="+endPoint+"&date="+date //日期格式2019-05-20 + "&type=normal&user=neibu&source=site&start=1&num=500&sort=3&_=1558231852892"; //调用方法将url转为json格式的字符串 String jsonStr=geturl(strUrl); JSONObject jsonObject = JSONObject.fromObject(jsonStr); JSONArray jArray=jsonObject.getJSONObject("data").getJSONArray("s2sBeanList"); for(int i=0;i<jArray.size();i++) { jsonObject=(jArray.getJSONObject(i)); System.out.println("起点:"+startPoint); System.out.println("起点经纬度:"+getLngLat(startPoint)); //getLngLat 调用将地址转化为经纬度的方法 System.out.println("车次"+jsonObject.get("trainNo").toString()); System.out.println("车站:"+jsonObject.get("dptStationName")+"-"+jsonObject.get("arrStationName")); System.out.println("时间段:"+jsonObject.get("dptTime")+"-"+jsonObject.get("arrTime")); System.out.println("一等座的价格:"+jsonObject.getJSONObject("seats").getJSONObject("一等座").get("price")); System.out.println("一等座的剩余票数:"+jsonObject.getJSONObject("seats").getJSONObject("一等座").get("count")); } return null; } public static void main(String[] args) { loadTrainRoute("北京", "上海", "2019-06-10"); } }
六,火车车次的站点信息查询
1,分析:因为火车车次和改车次的站点数据存储的位置不同,所以车站站点信息要更改URL
2,刷新网页点击一个车次,展开查看经停
3,先点击XHR,然后点击js,查看到改车次的信息
根据URL道理同上,对json数据进行分析,然后爬取下来。
本文章为原创文章,转载请注明,欢迎评论和改正。