程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

Java初始化省市区三级数据

发布于2021-08-28 19:58     阅读(1292)     评论(0)     点赞(13)     收藏(4)


使用Jsoup爬虫工具获取全国地区数据(省市县镇村)

最近新做一个项目,要在数据库初始化省市区三级数据,所以在网上找了个爬虫工具,从国家统计局区划代码网站爬取了相关数据。具体原理不解释了,只要能实现功能就OK。

  • 首先需要导入Jsoup相关依赖,数据库和spring的依赖就不用我再说了吧!!
<!--爬虫工具-->
<dependency>
     <groupId>org.jsoup</groupId>
     <artifactId>jsoup</artifactId>
     <version>1.14.2</version>
</dependency>
  • 然后创建地区实体类
/**
 * @作者 yangs
 * @日期 2021/8/25
 * @描述 中国省市区
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "area")
public class Area implements Serializable {

    //主键,区划代码
    @TableId(value = "id")
    private String id;

    //上级区划代码
    @TableField(value = "parentId")
    private String parentId;

    //区域名称,如山东省
    @TableField(value = "areaName")
    private String areaName;

    //区域等级,1代表省,2代表市,3代表区
    @TableField(value = "level")
    private Integer level;
}
  • 接着编写代码,从http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/这个网站爬取数据并存入数据库,这个网站包含了全国省市县镇乡所有数据,但是根据业务需要,本人业务只需要省市县数据即可,各位可以根据自己的业务需求,修改相应代码。
package com.yckj.appauth.service.impl;

import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yckj.appauth.mapper.InitAreaMapper;
import com.yckj.appauth.service.InitAreaService;
import com.yckj.common.entity.Area;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @作者 yangs
 * @日期 2021/8/26
 * @描述 初始化省市区数据
 */
@Service
public class InitAreaServiceImpl extends ServiceImpl<InitAreaMapper, Area> implements InitAreaService {

	//这是DAO层
    @Autowired
    private InitAreaMapper initAreaMapper;

    private static Map<Integer, String> cssMap = new HashMap<>();

    static {
        cssMap.put(1, "provincetr");// 省
        cssMap.put(2, "citytr");// 市
        cssMap.put(3, "countytr");// 县
        //数据只需要统计省市区,所以把镇和村注释掉了。如果你需要镇和村,直接打开注释就行
        /*cssMap.put(4, "towntr");// 镇
        cssMap.put(5, "villagetr");// 村*/
    }

    /**
     * @作者 yangs
     * @日期 2021/8/26
     * @描述 爬取数据直接存入数据库,这是方法入口,使用controller调用即可
     */
    public void initArea() {
        int level = 1;
        // 获取全国各个省级信息
        Document connect = connect("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/");
        Elements rowProvince = connect.select("tr." + cssMap.get(level));
        System.out.println("区划代码****上级代码****区域名称****区域等级");
        // 遍历每一行的省份城市
        for (Element provinceElement : rowProvince) {
            Elements select = provinceElement.select("a");
            // 每一个省份(如:山东省)
            for (Element province : select) {
                String strprovince = province.toString();
                String areaName = strprovince.substring(strprovince.indexOf(".html\">") + 7, strprovince.indexOf("<br></a>"));
                String areaCode = "";
                switch (areaName) {
                    case "北京市":
                        areaCode = "110000";
                        break;
                    case "天津市":
                        areaCode = "120000";
                        break;
                    case "河北省":
                        areaCode = "130000";
                        break;
                    case "山西省":
                        areaCode = "140000";
                        break;
                    case "内蒙古自治区":
                        areaCode = "150000";
                        break;
                    case "辽宁省":
                        areaCode = "210000";
                        break;
                    case "吉林省":
                        areaCode = "220000";
                        break;
                    case "黑龙江省":
                        areaCode = "230000";
                        break;
                    case "上海市":
                        areaCode = "310000";
                        break;
                    case "江苏省":
                        areaCode = "320000";
                        break;
                    case "浙江省":
                        areaCode = "330000";
                        break;
                    case "安徽省":
                        areaCode = "340000";
                        break;
                    case "福建省":
                        areaCode = "350000";
                        break;
                    case "江西省":
                        areaCode = "360000";
                        break;
                    case "山东省":
                        areaCode = "370000";
                        break;
                    case "河南省":
                        areaCode = "410000";
                        break;
                    case "湖北省":
                        areaCode = "420000";
                        break;
                    case "湖南省":
                        areaCode = "430000";
                        break;
                    case "广东省":
                        areaCode = "440000";
                        break;
                    case "广西壮族自治区":
                        areaCode = "450000";
                        break;
                    case "海南省":
                        areaCode = "460000";
                        break;
                    case "重庆市":
                        areaCode = "500000";
                        break;
                    case "四川省":
                        areaCode = "510000";
                        break;
                    case "贵州省":
                        areaCode = "520000";
                        break;
                    case "云南省":
                        areaCode = "530000";
                        break;
                    case "西藏自治区":
                        areaCode = "540000";
                        break;
                    case "陕西省":
                        areaCode = "610000";
                        break;
                    case "甘肃省":
                        areaCode = "620000";
                        break;
                    case "青海省":
                        areaCode = "630000";
                        break;
                    case "宁夏回族自治区":
                        areaCode = "640000";
                        break;
                    case "新疆维吾尔自治区":
                        areaCode = "650000";
                        break;
                }
                //Area只有4个字段,ID代表区划代码,parentId代表上级区划代码,areaName代表区域名称,level代表区域等级
                Area area = new Area();
                area.setId(areaCode);
                area.setParentId("root");
                area.setAreaName(areaName);
                area.setLevel(1);
                //把省级数据入库
                initAreaMapper.insert(area);
                System.out.println(areaCode + "****root****" + areaName + "****" + 1);
                parseNextLevel(areaCode, province, level + 1);
            }
        }
        System.out.println("执行完毕");
    }

    /**
     * @作者 yangs
     * @日期 2021/8/26
     * @描述 递归读取数据(根据业务需求,这里只读取到区级)
     */
    private void parseNextLevel(String parentId, Element parentElement, int level) {
        try {
            Thread.sleep(500);//睡眠一下,否则可能出现各种错误状态码
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Document doc = connect(parentElement.attr("abs:href"));
        if (doc != null) {
            Elements newsHeadlines = doc.select("tr." + cssMap.get(level));
            // 获取表格的一行数据
            for (Element element : newsHeadlines) {
                printInfo(parentId, element, level + 1);
                String code = element.select("td").first().text();
                Elements select = element.select("a");// 在递归调用的时候,这里是判断是否是村一级的数据,村一级的数据没有a标签
                if (select.size() != 0) {
                    parseNextLevel(code.substring(0, 6), select.last(), level + 1);
                }
            }
        }
    }

    /**
     * @作者 yangs
     * @日期 2021/8/26
     * @描述 打印市区并入库
     */
    private void printInfo(String parentId, Element element, int level) {
        String code = element.select("td").first().text();
        Area area = new Area();
        area.setId(code.substring(0, 6));
        area.setParentId(parentId);
        area.setAreaName(element.select("td").last().text());
        area.setLevel(level - 1);
        //把市和区数据入库
        initAreaMapper.insert(area);
        System.out.println(area.getId() + "****" + area.getParentId() + "****" + area.getAreaName() + "****" + (level - 1));
    }

    private static Document connect(String url) {
        if (url == null || url.isEmpty()) {
            throw new IllegalArgumentException("The input url('" + url + "') is invalid!");
        }
        try {
            return Jsoup.connect(url).timeout(100 * 1000).get();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

感谢:本人是根据前辈的代码改写形成的,下面附上前辈博客链接:Jsoup获取全国地区数据(省市县镇村)

原文链接:https://blog.csdn.net/YoungShuai1995/article/details/119924563



所属网站分类: 技术文章 > 博客

作者:哦哦好吧

链接:http://www.javaheidong.com/blog/article/276268/99a0a5b9adc6049dc6c0/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

13 0
收藏该文
已收藏

评论内容:(最多支持255个字符)