龙空技术网

恭喜中国获得东京奥运会首金!看看Java如何爬虫奥运奖牌榜数据

无处不在2020 585

前言:

而今同学们对“javalist转json”大体比较注意,看官们都想要分析一些“javalist转json”的相关内容。那么小编在网络上网罗了一些关于“javalist转json””的相关内容,希望小伙伴们能喜欢,咱们快快来学习一下吧!

2020年的东京奥运会在2021年7月23日开幕了。

2021年7月24日上午,中国的00后选手杨倩,获得了女子10米气步枪的金牌,未来可期,恭喜!

看到如此激动人心的消息,你是否想要获取奥运会的奖牌榜数据呢?

本文带你使用Java来进行爬虫获取2020年东京奥运奖牌榜的数据。

本文的数据源来源于新浪体育,首先我们访问新浪体育的奥运专题页面:

然后切换到完全奖牌榜的页签,可以看到相关的奖牌数据,如下图所示:

首金

然后我们可以打开浏览器的调试工具,查看网络请求并分析源代码,然后找到如下相关的代码:

页面配置

通过对变量的分析与判断,可以知道了4个URL信息,即国家的信息、比赛项目的信息、比赛日期的信息、奖牌榜数据的信息。

对于截图中的medalPage.js文件,通过分析可以知道是负责处理奖牌榜相关请求与页面渲染的主要文件,感兴趣的深入学习研究。

我们可以通过浏览器单独访问这几个接口,获得相关返回的JSON数据,各个请求如下:

国家请求:

比赛项目请求:

比赛日期请求:

奖牌榜数据请求:

通过对返回结果的分析,可以看到都是返回的JSON结构的数据。其中奖牌榜的数据如下:

{    	"result": {        "status": {            "code": 0,            "msg": "all succ"        },        "timestamp": "Sat Jul 24 10:18:10 +0800 2021",        "data": {            "total": [{                "gold": "1",                "silver": "0",                "bronze": "0",                "total": "1",                "goldMan": "0",                "silverMan": "0",                "bronzeMan": "0",                "totalMan": "0",                "goldWoman": "1",                "silverWoman": "0",                "bronzeWoman": "0",                "totalWoman": "1",                "goldMixed": "0",                "silverMixed": "0",                "bronzeMixed": "0",                "totalMixed": "0",                "country": "CHN",                "countryNameSSY": "\u4e2d\u56fd",                "countryFlagSSY": "https:\/\/\/ty\/2020\/Olympic\/flag\/CHN.png",                "olympicEventId": "540",                "ischn": "1",                "rank": "1"            }, {                "gold": "0",                "silver": "1",                "bronze": "0",                "total": "1",                "goldMan": "0",                "silverMan": "0",                "bronzeMan": "0",                "totalMan": "0",                "goldWoman": "0",                "silverWoman": "1",                "bronzeWoman": "0",                "totalWoman": "1",                "goldMixed": "0",                "silverMixed": "0",                "bronzeMixed": "0",                "totalMixed": "0",                "country": "ROC",                "countryNameSSY": "ROC",                "countryFlagSSY": "https:\/\/\/ty\/2020\/Olympic\/flag\/ROC.png",                "olympicEventId": "540",                "ischn": "0",                "rank": "2"            }, {                "gold": "0",                "silver": "0",                "bronze": "1",                "total": "1",                "goldMan": "0",                "silverMan": "0",                "bronzeMan": "0",                "totalMan": "0",                "goldWoman": "0",                "silverWoman": "0",                "bronzeWoman": "1",                "totalWoman": "1",                "goldMixed": "0",                "silverMixed": "0",                "bronzeMixed": "0",                "totalMixed": "0",                "country": "SUI",                "countryNameSSY": "\u745e\u58eb",                "countryFlagSSY": "https:\/\/\/ty\/2020\/Olympic\/flag\/SUI.png",                "olympicEventId": "540",                "ischn": "0",                "rank": "3"            }],            "sum": {                "gold": "1",                "silver": "1",                "bronze": "1",                "total": "3",                "goldMan": "0",                "silverMan": "0",                "bronzeMan": "0",                "totalMan": "0",                "goldWoman": "1",                "silverWoman": "1",                "bronzeWoman": "1",                "totalWoman": "3",                "goldMixed": "0",                "silverMixed": "0",                "bronzeMixed": "0",                "totalMixed": "0"            }        }    }}

这个JSON中根据英文含义,可以明确知道每个字段的含义。

接下来,我们采用SpringBoot+Jsoup+FastJSON来进行相关操作。

首先新建个Java实体类:

/** * 新浪奥运奖牌实体 * @date 2021-07-24 */public class MedalEntity implements Serializable {    private static final long serialVersionUID = 1L;    /**     * 国家编码     */    private String country;    /**     * 国家名称     */    private String countryNameSSY;    /**     * 奥运ID     */    private String olympicEventId;    /**     * 当前排名     */    private String rank;    /**     * 金牌     */    private String gold;    /**     * 银牌     */    private String silver;    /**     * 铜牌     */    private String bronze;    /**     * 奖牌总数     */    private String total;    /**     * 男子金牌     */    private String goldMan;    /**     * 男子银牌     */    private String silverMan;    /**     * 男子铜牌     */    private String bronzeMan;    /**     * 男子奖牌总数     */    private String totalMan;    /**     * 女子金牌     */    private String goldWoman;    /**     * 女子银牌     */    private String silverWoman;    /**     * 女子铜牌     */    private String bronzeWoman;    /**     * 女子奖牌总数     */    private String totalWoman;    /**     * 混合金牌     */    private String goldMixed;    /**     * 混合银牌     */    private String silverMixed;    /**     * 混合铜牌     */    private String bronzeMixed;    /**     * 混合奖牌总数     */    private String totalMixed;        //此处省略setter/getter    

然后写一个新浪奥运网络爬虫工具类:

package com.wxbz.olympic.util;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import com.alibaba.fastjson.parser.Feature;import com.wxbz.olympic.entity.MedalEntity;import org.jsoup.Jsoup;import java.io.IOException;import java.security.SecureRandom;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Random;/** * 新浪2020东京奥运请求处理类 * @date 2021-07-24 */public class SinaRequestUtil {    /**     * 获得国家的列表,返回的国家JSON具有顺序性     */    public static final String COUNTRY_URL = ";;    /**     * 奥运比赛项目大类     */    public static final String ITEM_URL = ";;    /**     * 奥运比赛日期列表     */    public static final String DATE_URL = ";;    /**     * 奥运所有奖牌榜数据     */    public static final String MEDAL_URL = ";;    /**     * user-agent模拟数据     */    protected static final String[] USER_AGENT = new String[] {            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36",            "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0",            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/73.0.3683.103"};    /**     * 随机获得一个User-Agent     * @return     */    public static String getRandomUserAgent() {        Random r = new SecureRandom();        return USER_AGENT[r.nextInt(5)];    }    /**     * 创建基础的Map数据     * @param key     * @param dataMap     * @return     */    public static Map<String,Object> createCodeMap(String key,JSONObject dataMap){        Map<String,Object> tempMap = new HashMap<String,Object>();        tempMap.put("code",key);        tempMap.put("name",dataMap.getString(key));        return tempMap;    }    /**     * 查询基础的数据     * @param url     * @return     * @throws Exception     */    public static List<Map<String,Object>> getCodeDataList(String url)throws Exception{        List<Map<String,Object>> countryList = new ArrayList<Map<String,Object>>();        String countryData = Jsoup.connect(url).ignoreContentType(true).userAgent(getRandomUserAgent()).execute().body();        JSONObject countryDataObj = JSONObject.parseObject(countryData, Feature.OrderedField);        int successCode = countryDataObj.getJSONObject("result").getJSONObject("status").getInteger("code");        if(successCode == 0){            JSONObject countryMap =  countryDataObj.getJSONObject("result").getJSONObject("data");            for(String key : countryMap.keySet()){                countryList.add(createCodeMap(key,countryMap));            }        }        return countryList;    }    /**     * 获得国家的配置数据     * @return     * @throws Exception     */    public static List<Map<String,Object>> getCountryList()throws Exception{        return getCodeDataList(COUNTRY_URL);    }    /**     * 获得比赛项目的配置数据     * @return     * @throws Exception     */    public static List<Map<String,Object>> getItemList()throws Exception{        return getCodeDataList(ITEM_URL);    }    /**     * 获得奖牌榜数据     * @return     * @throws Exception     */    public static List<MedalEntity> getMedalDataList()throws Exception{        List<MedalEntity> medalList = new ArrayList<MedalEntity>();        String medalData = Jsoup.connect(MEDAL_URL).ignoreContentType(true).userAgent(getRandomUserAgent()).execute().body();        JSONObject medalDataObj = JSONObject.parseObject(medalData, Feature.OrderedField);        int successCode = medalDataObj.getJSONObject("result").getJSONObject("status").getInteger("code");        if(successCode == 0){            JSONObject dataObj =  medalDataObj.getJSONObject("result").getJSONObject("data");            JSONArray totalArray =  dataObj.getJSONArray("total");//每个国家的数据            medalList = totalArray.toJavaList(MedalEntity.class);        }        return medalList;    }    public static void main(String[] args) throws Exception {        //查询国家数据        System.out.println(JSON.toJSONString(getCountryList()));        //查询比赛项目数据        System.out.println(JSON.toJSONString(getItemList()));        //查询奖牌榜数据        System.out.println(JSON.toJSONString(getMedalDataList()));    }}

执行程序后,即可以在控制台打印出我们需要的数据:

本篇文件简单介绍了如何获取奥运会奖牌的数据,后续会继续更新此系列内容,目前大概的想法有:

1、将爬虫的奖牌榜数据存储到数据库中。

2、集成Vue前端页面,展示数据并进行可视化。

3、集成定时任务进行实时数据获取处理。

感兴趣和喜欢的点个赞吧,你们的关注就是我持续的动力,期待中国获得更多金牌!

本文在我的微信公众平台【无处不在的技术】同步发布!

标签: #javalist转json #javalist的add