由于学习要求,每次做注册,地址选择时,都需要省市区镇四级联动选择器 ,到网上下载很难找到合适的资源,即使有,但资源都是往年的,没有实时更新。
所以,我们将利用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包
org.jsoup
jsoup
1.10.2
org.projectlombok
lombok
1.18.22
com.alibaba
fastjson
1.2.3
主要代码
public class CityAll {
private List cityList = new ArrayList<>();
private List cityList1 = new ArrayList<>();
private List cityList2 = new ArrayList<>();
public List getCity(){
List 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 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 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 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;
}
private List getArea(City city,String className,String sufferUrl){
List 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名
//判断是否有标签
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;
}
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,*
@Data
@AllArgsConstructor
@NoArgsConstructor
public class City {
private String url;
private String cityName;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Area {
private String areaId;
private String areaName;
private List areaList;
}
打包
//调用方法
List 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文件
使用jquery.ajax获取city.json文件
$.get({
url:"city.json", //文件地址
success: function (data) {
province=data;
provinceList();
}
});
html代码
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[i].areaName+"");
}
//初始化
$("#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");
for (let i = 0; i < city.length; i++) {
//Dom操作 添加城市
$("#city").append("");
}
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");
for (let i = 0; i < country.length; i++) {
//Dom操作 添加城市
$("#country").append("");
}
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");
for (let i = 0; i < town.length; i++) {
//Dom操作 添加城镇
$("#town").append("");
}
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/
在主页搜索省市区镇四级联动选择器可下载资源包



