背景

打算做一个省级联动的功能,由于网上没有找到符合自己要求的数据。便着手尝试写一个简单爬虫进行数据抓取。由于时间仓促,简单粗糙的写了份代码。(嵌套循环过多)可自行优化。复制代码,能直接运行;

大概花费一个多小时能运行完成

如果不想自己重新抓取,文章的最后有2份不同数据结构格式的sql,可直接使用;

部分城市没有5级的,例如广东省东莞市下一级是镇。

数据来源:中国统计局标准 http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/

运行环境:jdk8;

代码

<!-- 依赖包 -->
<dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.11.3</version>
</dependency>

import cn.hutool.core.date.DateUtil;import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;public class Test {private static final Logger log = LoggerFactory.getLogger(Test.class);private static AtomicInteger atomicInteger = new AtomicInteger(0);private static AtomicInteger atomicIntegerErrorNum = new AtomicInteger(0);public static void main(String[] args) {//获取所有的数据
//        test(null, null);//获取指定的城市test("广东省", "中山市");}private static String getHtml(String url) throws Exception {atomicInteger.incrementAndGet();log.info("调用接口次数 :" + atomicInteger.get());log.info("请求开始时间 ==>" + DateUtil.formatDateTime(new Date()));log.info(url);String html = null;try {html = getHtml2(url);} catch (Exception e) {e.printStackTrace();log.info(Thread.currentThread().getName() + " = 超时。。睡5秒再重试");Thread.sleep(1000 * 5);log.info(Thread.currentThread().getName() + " = 超时重试");atomicIntegerErrorNum.incrementAndGet();log.info("error num = " + atomicIntegerErrorNum.get());try {//重试1次html = getHtml2(url);} catch (Exception e2) {e2.printStackTrace();log.info("error num = " + atomicIntegerErrorNum.get());log.info(Thread.currentThread().getName() + " 第二次超时重试");log.info(Thread.currentThread().getName() + " = 第二次超时。。睡12分钟再重试");log.info("error num = " + atomicIntegerErrorNum.get());Thread.sleep(1000 * 60 * 12);//重试2次html = getHtml2(url);}}log.info("请求结束时间 ==>" + DateUtil.formatDateTime(new Date()));System.out.println("");System.out.println("");return html;
//        }}private static String getHtml2(String url) throws Exception {//链式构建请求return HttpRequest.get(url).header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36")//头信息,多个头信息多次调用此方法即可.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("Cookie", "_trs_uv=" + IdUtil.simpleUUID() + "; SF_cookie_1=" + IdUtil.fastUUID()).header("If-None-Match", "f32-5d4bccaa05a80-gzip")
//                    .header("If-Modified-Since",new Date())
//                    .form(paramMap)//表单内容.timeout(15000)//超时,毫秒.execute().body();}public static String baseUrl = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/";public static void test(String appendProvide, String appendCity) {System.out.println("===============开始抓取数据==================");var url = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/index.html";String html = HttpUtil.get(url);var htmlDoc = Jsoup.parse(html);var selectClasses = htmlDoc.getElementsByClass("provincetr");var startDateStr = DateUtil.formatDateTime(new Date());long startDate = System.currentTimeMillis();//        ExecutorService executorService = new ThreadPoolExecutor(4, 5, 1L, TimeUnit.SECONDS, new ArrayBlockingQueue(4), Executors.defaultThreadFactory());for (int i = 0; i < selectClasses.size(); i++) {int finalI = i;
//            executorService.execute(() -> {
//                System.out.println(Thread.currentThread().getName() + " " + "--->开始爬数据");try {//一个线程跑就行startProvide(selectClasses, finalI, baseUrl, appendProvide, appendCity);} catch (Exception e) {e.printStackTrace();}}System.out.println("耗时 =》");System.out.println((System.currentTimeMillis() - startDate) / 1000);System.out.println("开始时间 ==> " + startDateStr);System.out.println("结束时间 ==>" + DateUtil.formatDateTime(new Date()));}/*** @param selectClasses* @param i* @param baseUrl* @param appendProvide 需要查询的省  ,null表示查询所有* @throws Exception*/private static void startProvide(Elements selectClasses, Integer i, String baseUrl, String appendProvide, String appendCity) throws Exception {var provideCodes = selectClasses.get(i).children();//1.省份 provincetrfor (int provideCodeIndex = 0; provideCodeIndex < provideCodes.size(); provideCodeIndex++) {var provideCodeUrl = provideCodes.get(provideCodeIndex).select("a").attr("href");var provideName = provideCodes.get(provideCodeIndex).select("a").text();//            System.out.println("省份 = " + provideName);if (!StringUtils.isBlank(provideCodeUrl)) {if (StringUtils.isBlank(appendProvide)) {provide(provideCodeUrl, provideName, null);} else {if (appendProvide.equals(provideName)) {provide(provideCodeUrl, provideName, appendCity);}}}}}/*** 通过省,市获取下面的数据** @param provideCodeUrl*/public static void provide(String provideCodeUrl, String provideName, String appendCity) throws Exception {var provideCode = provideCodeUrl.split("\\.")[0];//                    String gotoCityHtml = HttpUtil.get(baseUrl + provideCodeUrl);String gotoCityHtml = getHtml(baseUrl + provideCodeUrl);var cityHtmlDoc = Jsoup.parse(gotoCityHtml);Elements selectCityClass = cityHtmlDoc.select(".citytr");//        var len = provideCode.length();
//        var provideCode2 = provideCode;
//        if (len < 6) {
//            len = 6 - len;
//            for (int l = 0; l < len; l++) {
//                provideCode2 += "0";
//            }
//        }if (StringUtils.isBlank(appendCity)) {//todo 保存到数据库  保存省city(selectCityClass, provideName, provideCode, null);} else {city(selectCityClass, provideName, provideCode, appendCity);}}/*** 城市** @param selectCityClass* @param provideName* @param provideCode* @throws Exception*/private static void city(Elements selectCityClass, String provideName, String provideCode, String appendCity) throws Exception {//2.城市  citytrfor (int cityIndex = 0; cityIndex < selectCityClass.size(); cityIndex++) {var gotoCountyUrl = selectCityClass.get(cityIndex).select("td").get(1).select("a").attr("href");var cityName = selectCityClass.get(cityIndex).select("td").get(1).select("a").text();System.out.println("城市 = " + cityName);if (StringUtils.isBlank(gotoCountyUrl)) {continue;}if (StringUtils.isBlank(appendCity)) {appendCity(gotoCountyUrl, provideName, provideCode, cityName);} else {if (appendCity.equals(cityName)) {appendCity(gotoCountyUrl, provideName, provideCode, cityName);}}}}private static void appendCity(String gotoCountyUrl, String provideName, String provideCode, String cityName) throws Exception {//                        String countytr = HttpUtil.get(baseUrl + gotoCountyUrl);boolean flag = true;String countytr = getHtml(baseUrl + gotoCountyUrl);var countytrDoc = Jsoup.parse(countytr);Elements countyClass = countytrDoc.select(".countytr");if (countyClass.size() == 0) {flag = false;countyClass = countytrDoc.select(".towntr");}var strCityUrl = gotoCountyUrl.split("/");var cityCode = strCityUrl[strCityUrl.length - 1].split("\\.")[0];var cityCodeLen = cityCode.length();var cityCode2 = cityCode;if (cityCodeLen < 6) {cityCodeLen = 6 - cityCodeLen;for (int l = 0; l < cityCodeLen; l++) {cityCode2 += "0";}}if (cityName.equals("市辖区")) {cityName = provideName;}cityCode = cityCode2;if (!flag) {town(countyClass,provideName,provideCode,cityCode, flag);} else {//todo 保存到数据库   保存城市county(countyClass,provideName,provideCode);}}/*** 街道** @param countyClass* @param provideCode*/private static void county(Elements countyClass, String provideName, String provideCode) throws Exception {//3.县区  countytrfor (int county = 0; county < countyClass.size(); county++) {var gotoTownUrl = countyClass.get(county).select("td").get(1).select("a").attr("href");var countyName = countyClass.get(county).select("td").get(1).select("a").text();System.out.println("县区 = " + countyName);if (StringUtils.isBlank(gotoTownUrl)) {continue;}//todo 保存到数据库String towntr = getHtml(baseUrl + provideCode + "/" + gotoTownUrl);var townDoc = Jsoup.parse(towntr);Elements townClass = townDoc.select(".towntr");var gotoTownCode = gotoTownUrl.split("/")[0];
//                            Thread.sleep(3000);town(townClass,provideName,provideCode,gotoTownCode, true);}}/*** @param townClass* @param provideName* @param provideCode* @param gotoTownCode* @param flag         是否地级市。true是,false否* @throws Exception*/private static void town(Elements townClass, String provideName, String provideCode, String gotoTownCode, boolean flag) throws Exception {//4.街道。镇 towntrfor (int town = 0; town < townClass.size(); town++) {//towntrvar gotoVillageHref = townClass.get(town).select("td").get(1).select("a").attr("href");var townName = townClass.get(town).select("td").get(1).select("a").text();System.out.println("街道。镇 = " + townName);if (StringUtils.isBlank(gotoVillageHref)) {continue;}//todo 保存到数据库//居委会
//                                String villageStr = HttpUtil.get(baseUrl + provideCode + "/" + gotoTownCode + "/" + gotoVillageHref);String villageStr = null;if(flag){villageStr = getHtml(baseUrl + provideCode + "/" + gotoTownCode + "/" + gotoVillageHref);}else{villageStr = getHtml(baseUrl + provideCode + "/"+ gotoVillageHref);}var villageDoc = Jsoup.parse(villageStr);Elements villagetr = villageDoc.select(".villagetr");for (int villageIndex = 0; villageIndex < villagetr.size(); villageIndex++) {var tds = villagetr.get(villageIndex).select("td");//[0].text();var villageCode = tds.get(0).text();var villageType = tds.get(1).text();var villageName = tds.get(2).text();System.out.println(villageCode + " " + villageType + " " + villageName);//todo 保存到数据库}}}}

附录

2021全国行政区域4级,5级(不含港澳台)-MySQL文档类资源-CSDN下载

免责声明:本文章仅用于学习参考

java获取行政区划编码(省市区县居委5级)相关推荐

  1. 爬虫模式-JAVA获取省市区编码

    起因 准备做一个省级联动的功能,从网页上查找了很多资源符合要求的很少(缺失港澳台数据,不好实现直辖市.特别行政区判断).复制代码,能直接运行. 数据来源:中国统计局标准 http://www.stat ...

  2. java获取文件编码

    目录 1. 概述 2. 编码基本知识 2.1. iso8859-1 2.2. GB2312/GBK 2.3. unicode 2.4. UTF 3.JAVA中移位运算>> , <&l ...

  3. 百度地图--展示行政区划(省市区县)和添加多个标注点案例

    百度地图JavaScript API支持HTTP和HTTPS,免费对外开放,可直接使用.接口使用无次数限制.在使用前,您需先申请密钥(ak)才可使用. 申请密钥链接: http://lbsyun.ba ...

  4. java获取文件编码_java如何获取文件编码格式

    1:简单判断是UTF-8或不是UTF-8,因为一般除了UTF-8之外就是GBK,所以就设置默认为GBK. 按照给定的字符集存储文件时,在文件的最开头的三个字节中就有可能存储着编码信息,所以,基本的原理 ...

  5. java 获取网页编码_spider JAVA如何判断网页编码

    前言 最近做一个搜索项目,需要爬取很多网站获取需要的信息.在爬取网页的时候,需要获得该网页的编码,不然的话会发现爬取下来的网页有很多都是乱码. 分析 一般情况下,网页头信息会指定编码,可以解析head ...

  6. java获取参数编码_java获取接口数据编码问题

    需求比较简单,就是获取接口数据并返回.但是在用的过程中发现编码问题.接口返回的数据编码为UTF-8,希望显示的数据也是UTF-8,问题出在从输入流中读取数据的过程中.下面是几个实例程序. 1.不管编码 ...

  7. java获取网页编码_java根据URL获取网页编码

    由于很多原因,我们要获取网页的编码(多半是写批量抓取的脚本吧...嘻嘻嘻) 注意: 如果你的目的是获取不乱码的网页内容(而不是根据网址发送post请求获取返回值),切记切记,移步这里 先说思路: 有三 ...

  8. python高德 查询县_Python获取高德地图省市区县列表

    项目中需要用省市区来进行检索,原想高德地图肯定会有API来获得这些数据,结果没有找到,有一个接口好像可以用,但是会附带大量的边界坐标点. 所以就不如自己把高德的省市区列表扒下来,自己写接口来完成这个功 ...

  9. python高德 查询县_【python】获取高德地图省市区县列表

    项目中需要用省市区来进行检索,原想高德地图肯定会有API来获得这些数据,结果没有找到,有一个接口好像可以用,但是会附带大量的边界坐标点. 所以就不如自己把高德的省市区列表扒下来,自己写接口来完成这个功 ...

  10. 实时最新中国省市区县geoJSON格式地图行政边界数据Echarts地图数据(可精确到街道级)

    geojson 数据下载地址:https://hxkj.vip/demo/echartsMap/ 可下载的数据包含省级geojson行政边界数据.市级geojson行政边界数据.区/县级geojson ...

最新文章

  1. 微机原理—定时计数控制接口
  2. 植树节特别活动:合种樟子松/华山松/云杉/胡杨
  3. 带 sin, cos 的线段树 - 牛客
  4. linux安装redis 完整步骤
  5. 【ijkplayer】编译 Android 版本的 ijkplayer ⑥ ( 进入 ijkplayer-android/android 目录 | 执行 compile-ijk.sh 脚本完成编译 )
  6. mac电脑开机出现客人用户,没有输入密码框,其他键都点不动,重启也不好使
  7. Linux shell if [ -n ] 正确使用方法
  8. 数学--数论--快速乘法+快速幂
  9. mysql日期为00_MySQL 8.0.13 设置日期为0000-00-00 00:00:00时出现的问题
  10. 多线程socket 端口扫描程序,实现了,但是速度不行,求指点。
  11. 无限法则无法连接服务器内容,无限法则链接不了服务器
  12. 二分法01:查找一个数
  13. 在线选课网站用什么服务器,高校网上选课系统 PC服务器替代小型机
  14. 猿创征文 | 2022 我的开发者工具
  15. Centos8创建pem文件进行远程连接
  16. jmeter性能测试实战——基础篇
  17. hive 中创建表的三种方式
  18. 计算摄影:相机成像流程 —— ISP
  19. clear:both在HTML页面中的用法
  20. 三菱L系列PLC 注释完成 程序完整 有威纶通触摸屏程序

热门文章

  1. 会议室预约系统(小程序+web端管理系统)2020.11.11-2021.02.11
  2. centos 计算器_Linux下的计算器
  3. 什么是EJB?EJB到底是什么?
  4. 七牛 html 上传,在七牛上传之后如何自己自定义上传完成处理并在页面显示。_html/css_WEB-ITnose...
  5. 【资料】舵机控制原理
  6. matlab lu分解 源代码,矩阵LU分解程序实现(Matlab)
  7. 信息收集--wmic命令
  8. golang html转成pdf,使用_go-wkhtmltopdf_将html转pdf
  9. Java后台给PDF加水印并且合并多个PDF文件
  10. VS2010编程助手