前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >武汉疫情系列(2)|java爬取【新型冠状病毒肺炎确诊患者同行程查询工具】数据

武汉疫情系列(2)|java爬取【新型冠状病毒肺炎确诊患者同行程查询工具】数据

作者头像
小小鱼儿小小林
发布2020-06-24 12:12:51
7302
发布2020-06-24 12:12:51
举报

一、要爬取的内容

了解到已经有大佬们整理和制作了同行程的查询网站,能够帮助到更多人解决问题,这里感谢一下这些无私奉献的大佬们。我这里的爬取并没有恶意的意思,正如我提到的,我是希望能够将多个平台的功能整理出API,然后能够让更多人整合这么多个平台的功能,然后再次整合成网站甚至制作成小程序,虽然我也会做小程序。

爬取的地址:http://2019ncov.nosugartech.com/search.html 或者 http://2019ncov.nosugartech.com

二、抓包数据

抓包可以利用抓包工具或者直接浏览器F12看请求数据 ,这里我就直接省略跳过去了,想了解的可以自己搜索教程,我用的抓包工具是fiddler。

请求地址:http://2019ncov.nosugartech.com/search.html

1、分析

这里发现当我请求这个页面的抓包数据如图所示,我们可以清楚的看到请求的url有这些,我们可以猜测到这个网站的前端是用了Layui框架,然后所有的数据在一个data.json里面,然后我试着输入日期和车次搜索了一下,发现没有新的请求,所以可以猜测到数据应该没有和数据库交互,数据都是放在data.json文件里面,然后页面的展示表格和搜索展示是用了layui的表格组件,这样可以保证搜索的人即使再多,也不会出现崩溃,关于网站的架构模式这篇文章不是重点,我也就不继续分析和猜测了。

这样也降低了我们的爬取难度,我们只要直接请求这个http://2019ncov.nosugartech.com/data.json?439072文件就可以拿到所有的数据了,然后不管你是每次都请求这个data.json,还是将数据入库或redis缓存里,然后每隔一定时间请求一次data.json都可以,看你想怎么弄。(这次感谢这些大佬们默默的整理这些数据,整理数据是繁琐的,但也是重中之重)

很多人会问这个问号后面的439072是什么东东,我们直接查看源代码,可以看到这个只是一个防止浏览器有缓存的一个版本号,

2、代码demo

/**
     * 新型冠状病毒肺炎确诊患者同行程查询工具
     * @return
     */
    public static String getSameTripData(){
        String url="http://2019ncov.nosugartech.com/data.json?"+Math.floor(new Date().getTime()/1000/3600);
        //模拟请求
        HttpPojo httpPojo = new HttpPojo();
        httpPojo.setHttpHost("2019ncov.nosugartech.com");
        httpPojo.setHttpAccept("application/json, text/javascript, */*; q=0.01");
        httpPojo.setHttpConnection("keep-alive");
        httpPojo.setHttpUserAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
        httpPojo.setHttpReferer("http://2019ncov.nosugartech.com/search.html");
        httpPojo.setHttpOrigin("http://2019ncov.nosugartech.com/search.html");
        Map paramObj = new HashMap();
        String htmlResult = httpSendGet(url, paramObj, httpPojo); //整个html页面
        System.out.println(htmlResult);

        //遍历入库或者存redis等操作
        /*JSONObject dataJo = JSONObject.parseObject(htmlResult);
        String data = dataJo.getString("data");//拿到所有数据
        JSONArray array = JSONArray.parseArray(data);
        for (int i = 0; i < array.size(); i++) {
            JSONObject tripJo = JSONObject.parseObject(array.getString(i));
            String t_no = tripJo.getString("t_no");
            System.out.println("t_no:"+t_no);
            
            //入库操作
        }*/

        return htmlResult;
    }

运行效果:可以自行复制打印出来的结果在 在线json格式化网站解析一下看看:http://www.bejson.com/count.html

数据就不复制出来了,因为数据实在是太多,csdn博客会提示字数太多,发布不了,所以大家自己运行获取结果哈

3、各个字段的含义

 {
		"id": 946,
		"t_date": "2020-01-28",
		"t_start": "2020/01/28 13:30:00",
		"t_end": "2020/01/28 23:59:59",
		"t_type": 5,
		"t_no": "淮北市1路公交车",
		"t_memo": "1月31日确诊",
		"t_no_sub": "",
		"t_pos_start": "淮北淮海路",
		"t_pos_end": "淮北市人民医院",
		"source": "http://wjw.huaibei.gov.cn/xxfb/tzgg/55971291.html",
		"who": "淮北市卫生健康委员会",
		"verified": 1,
		"created_at": "2020/02/02 21:19:11",
		"updated_at": "2020/02/02 21:35:21"
	}, {
		"id": 855,
		"t_date": "2020-01-27",
		"t_start": "2020/01/27 00:00:00",
		"t_end": "2020/01/27 23:59:59",
		"t_type": 1,
		"t_no": "JD5859",
		"t_memo": "",
		"t_no_sub": "",
		"t_pos_start": "北京",
		"t_pos_end": "南昌",
		"source": "https://mp.weixin.qq.com/s/HYcnAc-G5GpgEGFJSPsZBg",
		"who": "人民日报",
		"verified": 1,
		"created_at": "2020/02/01 20:30:19",
		"updated_at": "2020/02/01 21:41:15"
	}

t_type 表示交通工具、交通类型

t_type == 1 飞机
t_type == 2 火车
t_type == 3 地铁
t_type == 4 长途客车/大巴
t_type == 5 公交车
t_type == 6 出租车
t_type == 7 轮船
t_type == 8 其它公共场所
't_type': '交通类型'
't_date': '日期'
't_no': '车次/车牌/航班号/场所名称'
't_no_sub': '车厢'
't_pos_start': '出发站'
't_pos_end': '到达站'
't_memo': '车次附加描述'
't_start': '开始时间'
't_end': '结束时间'
'source': '线索来源'
'created_at': '提交时间'
'remark': '事件备注'

至此,同行程查询工具的数据已经爬取完毕了,如何搜索,一定要将数据存库或者放redis缓存中,然后写一个查询接口,就可以进行搜索时间+车次+地区的功能了,

下面放一下爬取要用到的工具类和完整代码

三、工具类

用到的工具类,请戳链接:https://blog.csdn.net/qq_27471405/article/details/104140618

四、完整代码

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.common.apiV2.beans.HttpPojo;

import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



/**
 * Created by yjl on 2020-02-01.
 */
@Service("WuhanService")
public class WuhanService {
    public static void main(String[] args) {
        getSameTripData();
    }


   


    /**
     * 新型冠状病毒肺炎确诊患者同行程查询工具
     * @return
     */
    public static String getSameTripData(){
        String url="http://2019ncov.nosugartech.com/data.json?"+Math.floor(new Date().getTime()/1000/3600);
        //模拟请求
        HttpPojo httpPojo = new HttpPojo();
        httpPojo.setHttpHost("2019ncov.nosugartech.com");
        httpPojo.setHttpAccept("application/json, text/javascript, */*; q=0.01");
        httpPojo.setHttpConnection("keep-alive");
        httpPojo.setHttpUserAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
        httpPojo.setHttpReferer("http://2019ncov.nosugartech.com/search.html");
        httpPojo.setHttpOrigin("http://2019ncov.nosugartech.com/search.html");
        Map paramObj = new HashMap();
        String htmlResult = httpSendGet(url, paramObj, httpPojo); //整个html页面
        System.out.println(htmlResult);

        //遍历入库或者存redis等操作
        /*JSONObject dataJo = JSONObject.parseObject(htmlResult);
        String data = dataJo.getString("data");//拿到所有数据
        JSONArray array = JSONArray.parseArray(data);
        for (int i = 0; i < array.size(); i++) {
            JSONObject tripJo = JSONObject.parseObject(array.getString(i));
            String t_no = tripJo.getString("t_no");
            System.out.println("t_no:"+t_no);

            //入库操作
        }*/

        return htmlResult;
    }



    /**
     * http请求
     * @param url
     * @param paramObj
     * @param httpPojo
     * @return
     */
    private static String httpSendGet(String url, Map paramObj, HttpPojo httpPojo){
        String result = "";
        String urlName = url + "?" + parseParam(paramObj);

        BufferedReader in=null;
        try {

            URL realURL = new URL(urlName);
            URLConnection conn = realURL.openConnection();
            //伪造ip访问
            String ip = randIP();
            System.out.println("目前伪造的ip:"+ip);
            conn.setRequestProperty("X-Forwarded-For", ip);
            conn.setRequestProperty("HTTP_X_FORWARDED_FOR", ip);
            conn.setRequestProperty("HTTP_CLIENT_IP", ip);
            conn.setRequestProperty("REMOTE_ADDR", ip);
            conn.setRequestProperty("Host", httpPojo.getHttpHost());
            conn.setRequestProperty("accept", httpPojo.getHttpAccept());
            conn.setRequestProperty("connection", httpPojo.getHttpConnection());
            conn.setRequestProperty("user-agent", httpPojo.getHttpUserAgent());
            conn.setRequestProperty("Referer",httpPojo.getHttpReferer()); //伪造访问来源
            conn.setRequestProperty("Origin", httpPojo.getHttpOrigin()); //伪造访问域名
            conn.connect();
            Map<String, List<String>> map = conn.getHeaderFields();
            for (String s : map.keySet()) {
                //System.out.println(s + "-->" + map.get(s));
            }
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += "\n" + line;
            }


        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (in!=null){
                try {
                    in.close();
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        }
        return result;
    }


    /**
     * 解析map
     * @param paramObj
     * @return
     */
    public static String parseParam(Map paramObj){
        String param="";
        if (paramObj!=null&&!paramObj.isEmpty()){
            for (Object key:paramObj.keySet()){
                String value = paramObj.get(key).toString();
                param+=(key+"="+value+"&");

            }
        }
        return param;
    }

    /**
     * 伪造ip地址
     * @return
     */
    public static String randIP() {
        Random random = new Random(System.currentTimeMillis());
        return (random.nextInt(255) + 1) + "." + (random.nextInt(255) + 1)
                + "." + (random.nextInt(255) + 1) + "."
                + (random.nextInt(255) + 1);
    }

}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、要爬取的内容
  • 二、抓包数据
    • 1、分析
      • 2、代码demo
        • 3、各个字段的含义
        • 三、工具类
        • 四、完整代码
        相关产品与服务
        云开发 CloudBase
        云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档