实现省市区镇四级联动选择器(地址选择)

实现省市区镇四级联动选择器(地址选择)

1.简介

由于学习要求,每次做注册,地址选择时,都需要省市区镇四级联动选择器 ,到网上下载很难找到合适的资源,即使有,但资源都是往年的,没有实时更新。

所以,我们将利用Java Jsoup爬虫技术和jQuery,html实现一个自己的现省市区镇四级联动选择器

效果图

截图


2.省市区镇数据的来源

使用Jsoup Java爬虫技术

jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

资源来自:http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/

导入jar包

<!--        Java爬虫包-->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.10.2</version>
        </dependency>

<!--        实体类包-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.3</version>
        </dependency>

主要代码

/**
 * @author xieyongfeng
 */
public class CityAll {
    private List<City> cityList = new ArrayList<>();
    private List<City> cityList1 = new ArrayList<>();
    private List<City> cityList2 = new ArrayList<>();

    /**
     * @return 地区表
     */
    public List<Area> getCity(){
        List<Area> areaList = new ArrayList<>();
        try {
            //构建请求头
            Connection.Response execute = getHtml("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/index.html");
            assert execute != null;
            Document document = execute.parse();
            //遍历省份
            Elements provincetrs = document.getElementsByClass("provincetr");
            int index=0;
            for (Element provincetr : provincetrs) {
                for (Element a : provincetr.getElementsByTag("a")) {
                    String[] split = a.getElementsByTag("a").eq(0).attr("href").split("\\.");
                    String cityId=split[0];
                    String url = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/"+a.getElementsByTag("a").eq(0).attr("href");
                    String cityName = a.getElementsByTag("a").eq(0).text();
                    //"网址:"+url+"  地区名:"+cityName;

                    //遍历citytr
                    List<Area> areaList1 = getArea(new City(url, cityName), "citytr","http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/");
                    areaList.add(new Area(cityId,cityName,areaList1));

                    System.out.print("------------------------------------省份:"+cityName+"   id:"+cityId);

                    //遍历countytr
                    //cityList1.removeAll(cityList1);
                    cityList1.addAll(cityList);
                    cityList.removeAll(cityList);
                    for (int i = 0; i < cityList1.size(); i++) {
                        List<Area> areaList2 = getArea(cityList1.get(i), "countytr", "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/" + cityId + "/");
                        areaList.get(index).getAreaList().get(i).setAreaList(areaList2);

                        System.out.println("    --------------城市:"+cityList1.get(i).getCityName());

                    //遍历towntr
                    cityList2.removeAll(cityList2);
                    cityList2.addAll(cityList);
                    cityList.removeAll(cityList);
                    for (int j = 0; j < cityList2.size(); j++) {
                        if(cityList2.get(j).getUrl()==null||cityList2.get(j).getUrl().equals("")){

                        }else {
                            List<Area> areaList3 = getArea(cityList2.get(j), "towntr", "");
                            areaList.get(index).getAreaList().get(i).getAreaList().get(j).setAreaList(areaList3);
                        }

                        System.out.print("  地区:"+cityList2.get(j).getCityName());
                        System.out.println();

                    }

                }
                    index++;
                    cityList.removeAll(cityList);
                    cityList1.removeAll(cityList1);
                    cityList2.removeAll(cityList2);
            }
        }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return areaList;
    }


    /**
     * @param city
     * @param className
     * @param sufferUrl
     * @return
     */
    private List<Area> getArea(City city,String className,String sufferUrl){
        List<Area> areaList = new ArrayList<>();
        cityList.removeAll(cityList);
        //遍历省份
            try{
                Connection.Response response = getHtml(city.getUrl());
                Document document = response.parse();
                //遍历city
                String cityId=null;
                String cityName=null;
                String url=null;
                Elements citytr = document.getElementsByClass(className);
                for (Element element : citytr) {
                    //解析city
                    Elements td = element.getElementsByTag("td");
                    for (int i = 0; i < td.size(); i++) {
                        //获取用区划代码,city名
                        //判断是否有<a>标签
                        if(td.get(i).getElementsByTag("a").text().equals("")){
                            //否
                            //分别获取用区划代码与city名
                            if(i==0){
                                //获取用区划代码
                                cityId = td.get(0).text();
                            }else if (i==1){
                                //获取city名
                                cityName = td.get(1).text();
                            }
                        }else{
                            //是
                            //分别获取用区划代码与city名
                            if(i==0){
                                //获取用区划代码
                                cityId = td.get(0).getElementsByTag("a").text();
                            }else if (i==1){
                                //获取city名
                                cityName = td.get(1).getElementsByTag("a").text();
                                //获取url
                                url = sufferUrl+td.get(1).getElementsByTag("a").attr("href");
                            }
                        }
                    }

                    //cityId
                    //cityName
                    // url

                    //打包AreaList
                    areaList.add(new Area(cityId,cityName,new ArrayList<>()));

                    //打包cityList
                    cityList.add(new City(url,cityName));
                }
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
            return areaList;
    }
    
    /**
     * @param url 
     * @return Connection
     */
    private Connection.Response getHtml(String url){
        //构建请求头
        try {
            return Jsoup.connect(url)
                     .header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9")
                     .header("Accept-Encoding", "gzip, deflate")
                     .header("Accept-Language", "zh-CN,zh;q=0.9")
                     .header("Cookie", "SF_cookie_1=37059734; _trs_uv=l0g4jh8f_6_eeaf; _trs_ua_s_1=l0g4jh8f_6_ky27")
                     .header("Referer", "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/")
                     .header("User-Agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Mobile Safari/537.36")
                     .method(Connection.Method.GET)
                     .execute();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        return null;
    }
    
}

需要的实体类

/**
 * @date 省份实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class City {
    private String url;
    private String cityName;
}

/**
 * @date 地区实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Area {
    private String areaId;
    private String areaName;
    private List<Area> areaList;
}

打包

//调用方法
        List<Area> city = new CityAll().getCity();
        //转为Json
        String str= JSON.toJSON(city).toString();
        System.out.println(str);
        FileOutputStream fileOutputStream = null;
        //保存至本地
        try {
            //地址
            fileOutputStream = new FileOutputStream("D:\\图片\\city.json");
            fileOutputStream.write(str.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

执行打包后,将会生成一个city.json文件。在主页搜索省市区镇四级联动选择器可下载资源包

接下来就是html的数据处理,渲染。


html的数据处理,渲染

使用Jquery库,导入jquery.js文件

<script src="http://www.kaylee.cool:8080/xieyongfeng/jquery.js"></script>

使用jquery.ajax获取city.json文件

$.get({
        url:"city.json",  //文件地址
        success: function (data) {
            province=data;
            provinceList();
        }
    });

html代码

<select id="province">
    <option value="0">请选择省份..</option>
</select>

<span id="city-span"></span>
<span id="country-span"></span>
<span id="town-span"></span>
<br>
<hr>
<span id="outAddress"></span>

js代码

let province;
    let city;
    let country;
    let town;

    let provinceName;
    let cityName;
    let countryName;
    let townName;

    let address;
    $.get({
        url:"city.json",  //文件地址
        success: function (data) {
            province=data;
            provinceList();
        }
    });

//遍历省份
    function provinceList() {
        for(let i=0;i<province.length;i++){
            //Dom操作 添加省份
            $("#province").append("<option id='"+province[i].areaId+"'>"+province[i].areaName+"</option>");
        }

        //初始化
        $("#city-span").html("");
        $("#country-span").html("");
        $("#town-span").html("");
    }

//省份选择处理
    $("#province:first").change(function(){
        //初始化地址
        address="";
        $("#outAddress").html("");
        //获取以选择的省份
        provinceName=$("#province:first").val();

        //遍历省份
        for(let i=0;i<province.length;i++){
            //判断对应省份
            if(province[i].areaName===provinceName){
                city = province[i].areaList;
                break;
            }
        }
        //遍历城市
        $("#city-span").html("<select id='city'><option>请选择城市..</option></select>");
        for (let i = 0; i < city.length; i++) {
            //Dom操作 添加城市
            $("#city").append("<option id='"+city[i].areaId+"'>"+city[i].areaName+"</option>");
        }
        reload_country();

        //初始化
        $("#country-span").html("");
        $("#town-span").html("");
    });


//重新加载js //城市选择处理
    function reload_country() {
        //城市选择处理
        $("#city:first").change(function() {
            //初始化地址
            address="";
            $("#outAddress").html("");
            //获取以选择的城市
            cityName=$("#city:first").val();

            //遍历城市
            for(let i=0;i<city.length;i++){
                //判断对应城市
                if(city[i].areaName===cityName){
                    country = city[i].areaList;
                    break;
                }
            }

            //遍历地区
            $("#country-span").html("<select id='country'><option>请选择地区..</option></select>");
            for (let i = 0; i < country.length; i++) {
                //Dom操作 添加城市
                $("#country").append("<option id='"+country[i].areaId+"'>"+country[i].areaName+"</option>");
            }
            reload_town();

            //初始化
            $("#town-span").html("");
        });
    }


//重新加载js //地区选择处理
    function reload_town() {
        //地区选择处理
        $("#country:first").change(function() {
            //初始化地址
            address="";
            $("#outAddress").html("");
            //获取以选择的地区
            countryName=$("#country:first").val();

            //遍历地区
            for(let i=0;i<country.length;i++){
                //判断对应地区
                if(country[i].areaName===countryName){
                    town = country[i].areaList;
                    break;
                }
            }

            //无城镇信息
            if(town.length===0){
                address=provinceName+"  "+cityName+"    "+countryName;
                $("#outAddress").html(address);
                return;
            }

            //遍历城镇
            $("#town-span").html("<select id='town'><option>请选择城镇..</option></select>");
            for (let i = 0; i < town.length; i++) {
                //Dom操作 添加城镇
                $("#town").append("<option id='"+town[i].areaId+"'>"+town[i].areaName+"</option>");
            }

            outAddress();
        });
    }


//输出地址
    function outAddress() {
        //获取城镇
        $("#town:first").change(function() {
            townName=$("#town:first").val();
            //打印地址
            address=provinceName+"  "+cityName+"    "+countryName+" "+townName;
            $("#outAddress").html(address);
        });
    }

编写完成后,打开浏览器,测试


最终效果图

截图

这样我们就拥有自己的省市区镇四级联动选择器了,当想更新数据时,将网址的2021更改就行了,

http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/


在主页搜索省市区镇四级联动选择器可下载资源包

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,那么这里提供一种基于Vue实现省市区三级联动的方法。 首先,我们需要准备好三个下拉框,分别是省、市、区,同时需要一个存放省市区数据的数组。我们可以在Vue实例中定义一个data属性来存储这些数据。 然后,我们需要在页面加载时,通过Ajax请求获取省市区数据,并将数据存储到Vue实例的data属性中。 最后,我们需要监听省、市的选择事件,根据选择的省、市来筛选出对应的区数据,并将其展示在区的下拉框中。 下面是一个简单的示例代码: ``` <template> <div> <select v-model="selectedProvince" @change="provinceChange"> <option v-for="province in provinces" :value="province.id">{{province.name}}</option> </select> <select v-model="selectedCity" @change="cityChange"> <option v-for="city in cities" :value="city.id">{{city.name}}</option> </select> <select v-model="selectedDistrict"> <option v-for="district in districts" :value="district.id">{{district.name}}</option> </select> </div> </template> <script> export default { data() { return { provinces: [], // 省份数据 cities: [], // 城市数据 districts: [], // 区域数据 selectedProvince: '', // 当前选中的省份id selectedCity: '', // 当前选中的城市id selectedDistrict: '', // 当前选中的区域id } }, mounted() { // 页面加载时请求省市区数据 this.loadProvinces(); }, methods: { // 加载省份数据 loadProvinces() { // 发送Ajax请求获取省份数据 axios.get('/api/provinces').then(response => { this.provinces = response.data; }).catch(error => { console.log(error); }); }, // 加载城市数据 loadCities(provinceId) { // 发送Ajax请求获取城市数据 axios.get('/api/cities?provinceId=' + provinceId).then(response => { this.cities = response.data; }).catch(error => { console.log(error); }); }, // 加载区域数据 loadDistricts(cityId) { // 发送Ajax请求获取区域数据 axios.get('/api/districts?cityId=' + cityId).then(response => { this.districts = response.data; }).catch(error => { console.log(error); }); }, // 省份选择事件 provinceChange() { // 重置城市和区域的选择 this.selectedCity = ''; this.selectedDistrict = ''; // 加载选中省份的城市数据 this.loadCities(this.selectedProvince); }, // 城市选择事件 cityChange() { // 重置区域的选择 this.selectedDistrict = ''; // 加载选中城市的区域数据 this.loadDistricts(this.selectedCity); } } } </script> ``` 在这个示例中,我们使用了axios库来发送Ajax请求获取省市区数据。对于省份选择事件和城市选择事件,我们都需要重置下一级选择框的值,并根据当前选择的省、市来加载对应的城市、区域数据。 当然,具体的数据结构和请求方式需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值