java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

Wesley13
• 阅读 995

本文章为原创文章,转载请注明,欢迎评论和改正。

一,分析

  之前所用的直接通过HTML中的元素值来爬取一些网页上的数据,但是一些比较敏感的数据,很多正规网站都是通过json数据存储,这些数据通过HTML元素是爬取不到的,所以只能通过json数据的api接口来爬取数据。

二,网站处理

  1,打开去哪儿网的网站https://train.qunar.com/,找到火车票查询,输入起点终点和日期,查询。

  java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

  2,右击打开审查元素,点击network

java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

  3,刷新网页,找到XHR,点击链接

java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

  4,找到s2sBeanList这一属性,打开即为所需要的数据

java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

 header里有所需的地址java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

三,项目结构

  1,所需jar包,基本是分析json数据的时候用到

  java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

  2,项目目录结构

 java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

四,代码分析

  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));为循环遍历所有车次

 java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

五,完整代码

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,刷新网页点击一个车次,展开查看经停

  java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

   3,先点击XHR,然后点击js,查看到改车次的信息

java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

  java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

 根据URL道理同上,对json数据进行分析,然后爬取下来。

本文章为原创文章,转载请注明,欢迎评论和改正。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Irene181 Irene181
3年前
3000字 “婴儿级” 爬虫图文教学 | 手把手教你用Python爬取 “实习网”!
1\.为"你"而写这篇文章,是专门为那些"刚学习"Python爬虫的朋友,而专门准备的文章。希望你看过这篇文章后,能够清晰的知道整个"爬虫流程"。从而能够"独立自主"的去完成,某个简单网站的数据爬取。好了,咱们就开始整个“爬虫教学”之旅吧!2\.页面分析①你要爬取的网站是什么?首先,我们应该清楚你要爬去的网站是什么?由于这里我们想要
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
把帆帆喂饱 把帆帆喂饱
3年前
爬虫
爬虫什么是爬虫使用编程语言所编写的一个用于爬取web或app数据的应用程序怎么爬取数据1.找到要爬取的目标网站、发起请求2.分析URL是如何变化的和提取有用的URL3.提取有用的数据爬虫数据能随便爬取吗?遵守robots.txt协议爬虫的分类通用网络爬虫百度,Google等搜索引擎,从一些初识的URL扩展到整个网站,主要为门户站点搜索引擎和大型网站服务采
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
如何应对亚马逊反爬机制
大家都知道亚马逊是全球最大的购物平台很多商品信息、用户评价等等都是最丰富的。但是对于爬虫来说,亚马逊的反爬机制应该也是数一数二的,想要获取亚马逊数据的人很多,但是真的能成功的确是少数,所以今天小编就手把手带大家,越过亚马逊的各种反爬机制爬取你想要的商品、评论等等有用信息。这里我们可以通过以下一些步骤去实现亚马逊数据的获取。一、使用requests的get请求