最近手头在做一些东西,需要一个全国各地的地域数据,从省市区到县镇乡街道的。各种度娘,各种谷歌,都没找到一个完整的数据。最后功夫不负有心人,总算找到一份相对来说比较完整的数据,但是这里的数据也只是精确到镇级别,没有村一级的数据(后来通过分析数据源我知道了为什么,呵呵),在加上博主提供的有些数据存在冗余,对于有强迫症和追求完美的我,心想着我一定要自己动手去把这部分数据给爬取出来。

上述博文中的内容还算丰富,博主是用的是php来实现的,作为2015年度编程语言排行榜的第一位,我们也不能示弱啊,下面我就带着大家一起来看看用java怎么从网页当中爬取我们想要的数据...

第一步、准备工作(数据源+工具):

数据源(截止目前最全面权威的官方数据):http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2013/

爬取数据的工具(爬虫工具):http://jsoup.org/

第二步、数据源分析:

首先jsoup工具的使用我在这里就不做讲解了,感兴趣的可以自己动手去查阅。

做开发就应该多去了解一些软件工具的使用,在平常开发过程中遇到了才知道从何下手,鼓励大家多平时留意一些身边的软件工具,以备不时之需。在做 这个东西以前,我也不知道jsoup要怎么用,但我知道jsoup可以用来干嘛,在我需要的用到的时候,再去查阅资料,自己学习。

上述的数据源是2013年中华人民共和国国家统计局发布的,其准确性和权威性不言而喻。

接下来我们分析一下数据源的结构,先从首页说起:

通过分析首页源码我们可以得到如下3点:

页面的整个布局是用的table标签来控制的,也就是说我们如果要通过jsoup来选择超链接,那么一定要注意,上图中不是只要标注了省市地区的地方采用的才是表格,整个页面中存在多个表格,因此是不可以直接通过表格

Document connect = connect("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2013/");

Elements rowProvince = connect.select("table");

来解析数据的。

页面中有超链接的部分有多少地方。可能是官方考虑到了你们这种程序员需要获取这样的数据的原因吧,页面很干净,除开下方的备案号是多余的超链接,其他的链接可以直接爬取。

省份城市的数据规律。包含有效信息的表格的每一行都有一个class属性provincetr,这个属性很重要,至于为什么重要,请接着往下看; 每一行数据中存在多个td标签,每一个td标签中包含一个a超链接,而这个超链接正是我们想要的超链接,超链接的文本即使省份(直辖市等)的名称。

再次我们再看一下一般的数据页面(一般的数据页面包括市级、县级、镇级这三级数据展示页面):

之所以要把上述三个页面放在一起,是因为通过分析我们可以发现,这三级数据的数据页面完全一致,唯一不同的就是在html源码数据表格中的数据 行tr的class属性不一致,分别对应为:citytr,countrytrhe towntr。其他均一致。这样我们就可以用一个通用的方法解决这三个页面的数据爬取。

最后看看村一级的数据页面:

在村一级的数据中,和上述市县镇的数据格式不一致,这一级所表示的数据是最低一级的,所以不存在a链接,因此不能采用上面市县镇数据的爬取方 式去爬取;这里展示数据的表格行的class为villagetr,除开这两点以外,在每一行数据中包含三列数据,第一列是citycode,第二列是城 乡分类(市县镇的数据格式不存在这一项),第三列是城市名称。

把握了以上各个要点之外,我们就可以开始编码了。

第三步、编码实现:

1 importjava.io.BufferedWriter;

2 importjava.io.File;

3 importjava.io.FileWriter;

4 importjava.io.IOException;

5 importjava.util.HashMap;

6 importjava.util.Map;

7

8 importorg.jsoup.Jsoup;

9 importorg.jsoup.nodes.Document;

10 importorg.jsoup.nodes.Element;

11 importorg.jsoup.select.Elements;

12

13 /**

14 * 全国省市县镇村数据爬取

15 * @authorliushaofeng

16 * @date 2015-10-11 上午12:19:39

17 * @version1.0.0

18 */

19 public classJsoupTest

20 {

21 private static Map cssMap = new HashMap();

22 private static BufferedWriter bufferedWriter = null;

23

24 static

25 {

26 cssMap.put(1, "provincetr");//省

27 cssMap.put(2, "citytr");//市

28 cssMap.put(3, "countytr");//县

29 cssMap.put(4, "towntr");//镇

30 cssMap.put(5, "villagetr");//村

31 }

32

33 public static void main(String[] args) throwsIOException

34 {

35 int level = 1;

36

37 initFile();

38

39 //获取全国各个省级信息

40 Document connect = connect("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2013/");

41 Elements rowProvince = connect.select("tr." +cssMap.get(level));

42 for (Element provinceElement : rowProvince)//遍历每一行的省份城市

43 {

44 Elements select = provinceElement.select("a");

45 for (Element province : select)//每一个省份(四川省)

46 {

47 parseNextLevel(province, level + 1);

48 }

49 }

50

51 closeStream();

52 }

53

54 private static voidinitFile()

55 {

56 try

57 {

58 bufferedWriter = new BufferedWriter(new FileWriter(new File("d:\\CityInfo.txt"), true));

59 } catch(IOException e)

60 {

61 e.printStackTrace();

62 }

63 }

64

65 private static voidcloseStream()

66 {

67 if (bufferedWriter != null)

68 {

69 try

70 {

71 bufferedWriter.close();

72 } catch(IOException e)

73 {

74 e.printStackTrace();

75 }

76 bufferedWriter = null;

77 }

78 }

79

80 private static void parseNextLevel(Element parentElement, int level) throws IOException

81 {

82 try

83 {

84 Thread.sleep(500);//睡眠一下,否则可能出现各种错误状态码

85 } catch (InterruptedException e)

86 {

87 e.printStackTrace();

88 }

89

90 Document doc = connect(parentElement.attr("abs:href"));

91 if (doc != null)

92 {

93 Elements newsHeadlines = doc.select("tr." + cssMap.get(level));//

94 // 获取表格的一行数据

95 for (Element element : newsHeadlines)

96 {

97 printInfo(element, level + 1);

98 Elements select = element.select("a");// 在递归调用的时候,这里是判断是否是村一级的数据,村一级的数据没有a标签

99 if (select.size() != 0)

100 {

101 parseNextLevel(select.last(), level + 1);

102 }

103 }

104 }

105 }

106

107 /**

108 * 写一行数据到数据文件中去

109 * @param element 爬取到的数据元素

110 * @param level 城市级别

111 */

112 private static void printInfo(Element element, int level)

113 {

114 try

115 {

116 bufferedWriter.write(element.select("td").last().text() + "{" + level + "}["

117 + element.select("td").first().text() + "]");

118 bufferedWriter.newLine();

119 bufferedWriter.flush();

120 } catch (IOException e)

121 {

122 e.printStackTrace();

123 }

124 }

125

126 private static Document connect(String url)

127 {

128 if (url == null || url.isEmpty())

129 {

130 throw new IllegalArgumentException("The input url('" + url + "') is invalid!");

131 }

132 try

133 {

134 return Jsoup.connect(url).timeout(100 * 1000).get();

135 } catch (IOException e)

136 {

137 e.printStackTrace();

138 return null;

139 }

140 }

141 }

数据爬取过程便是一个漫长的过程,只需要慢慢等待吧,呵呵,由于程序运行时间较长,请不要在控制台打印输出,否则可能会影响程序运行....

最终获取到数据的格式如下("{}"中表示城市级别,"[]"中内容表示城市编码):

拿到以上数据以后,自己想干什么都可以自我去实现了,以上的代码可以直接运行,从数据源爬取后,可以直接转换成自己所要的格式。

全国省市区java_Jsoup获取全国地区数据(省市县镇村)相关推荐

  1. Jsoup获取全国地区数据(省市县镇村)

    为什么80%的码农都做不了架构师?>>>    `package com.soft.di.jsoup; import java.io.BufferedWriter; import j ...

  2. java 省市县数据_使用Jsoup抓取全国地区数据(省市县镇村)

    最近手头在做一些东西,需要一个全国各地的地域数据,从省市区到县镇乡街道的.各种度娘,各种谷歌,都没找到一个完整的数据.最后功夫不负有心人,总算找到一份相对来说比较完整的数据,但是这里的数据也只是精确到 ...

  3. 用于ECharts的全国省市区县乡镇街道级的行政区划边界数据(GeoJSON格式)

    https://map.vanbyte.com 提供了免费的省市县3级行政边界数据(GeoJSON格式).省市县乡4级联动数据. 至于行政区划边界数据的来源,网络上有各种教程.授人以鱼不如授人以渔,下 ...

  4. 分析界面,在全国公共资源交易平台使用java获取全国的招投标数据接口

    任务:获取全国的建筑招投标数据信息,并打开界面获取详情页抓取html保存至本地. 打开网址地址,进行网页分析. 2.获取省市区联动,在控制台并没有发现任何往后台获取省市区联动的信息,怀疑是在js里写死 ...

  5. 在线获取全国省市区信息

    省 http://datavmap-public.oss-cn-hangzhou.aliyuncs.com/areas/csv/100000_province.json 市(130000 河北省) h ...

  6. 全国省市区JSON数据-转

    版权声明:本文为CSDN博主「PJ-ZH」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/zhouhaisun ...

  7. 爬取百度地图全国省市区地铁线路等数据

    从百度地图和高德地图中提炼出了对应的接口,方便iOS直接调用. 1.获取全国地铁城市: http://map.baidu.com/?qt=subwayscity&t=123457788 2.根 ...

  8. 获取全国地铁线站口数据(Python+百度API)

    使用场景 工作中需要及时更新全量线站口数据  ~~~ 研究城市地铁分布和数据 ~~~ 整体方案 地铁线站:高德地铁页面获取全国地铁线.站数据.百度也有地铁页面,但是百度的比较难抓取. 高德地图 | 地 ...

  9. Ajax怎么获取天气,Ajax获取全国天气预报的API数据

    这次给大家带来Ajax获取全国天气预报的API数据,Ajax获取全国天气预报API数据的注意事项有哪些,下面就是实战案例,一起来看一下. 预览图(比较简单粗糙) 聚合数据全国天气预报接口:https: ...

  10. 全国三级地区数据表设计

    全国三级地区数据表设计 最近因为工作需要,需要设计全国地区的三级联动,我也查了不少前端实现方式 不过都有些过时,一些地区的更新和变动后,这些实现方式并没跟着变动,所以我就上全国行政区划信息查询平台照着 ...

最新文章

  1. IT人的八大修炼神器
  2. Excel随机选取指定数据
  3. pandas fillna_6个提升效率的pandas小技巧
  4. 图论算法》关于tarjan算法两三事
  5. 关于python的线程安全的一些理解.
  6. 10个舍不得删的高质量公号
  7. Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用
  8. 2017年高考改革地区:浙江、上海
  9. 盘点 4 个开源小游戏
  10. 当地图与绘画结合,竟然能迸发出这样的精彩
  11. Linux 内核编程风格
  12. 5.14——教你把ssh抄成ssm
  13. Python小白的进阶之路---Day5
  14. 2018-2-13-win10-uwp-音频
  15. PTA 寻找250 (10分)
  16. hsv 与 hsi 颜色空间
  17. Oracle Primavera P6软件建立项目工序权重
  18. c++学习笔记:记在类前
  19. 开发必备 之 为你的谷歌浏览器润色一波~
  20. 字典树01字典树专题对字典树的理解

热门文章

  1. 利用函数求字符串长度
  2. LimeWire Basic 4.8.1 for Linux(转)
  3. lisp princ详解_晓东CAD家园-论坛-A/VLISP-正则表达式lisp实例讲解-通过代码,完整的展示了正则表达式在lisp中使用 - Powered by Discuz!...
  4. 后端速成JavaScript
  5. win7计算机系统减肥,怎样给win7瘦身 win7瘦身攻略
  6. Ttest(T检验)
  7. win10查看桌面壁纸路径
  8. 南航计算机学院考博难么,考研专硕真的不能考博吗?看看过来人是咋说的
  9. 数据分析案例-航空公司客户价值分析(聚类)
  10. 【DVB】【ATSC】ATSC和DVB数字电视系统的比较