使用java爬取国家统计局的12位行政区划代码
前言:
本文基于j2ee的原始url进行都写,解析指定内容时也是使用很傻的形式去查找指定格式的字符串来实现的。
更优雅的方式是可以使用apache的HttpClient和某些文档模型将HTML字符串构建成doc来进行解析。
目前已经修改代码适配最新的2015年的抓取。
爬取的原因:统计局网站提供的页面并按照:省-市-县-镇-村 这样的层次关系来组织页面,人工去获取所有的代码工作量大而繁琐,遂有了下面很粗糙的代码
代码如下:
1 import java.io.BufferedReader; 2 import java.io.BufferedWriter; 3 import java.io.File; 4 import java.io.FileWriter; 5 import java.io.InputStreamReader; 6 import java.net.URL; 7 import java.nio.charset.Charset; 8 9 /** 10 * 从国家统计局网站爬取2013年12位到村级别的行政区划代码 11 * @author 杨志龙 12 * blog:http://www.cnblogs.com/yangzhilong 13 * 14 */ 15 public class ReadCodeFromWeb { 16 public static final String baseUrl = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2015/"; 17 //设置utf-8发现有部分字符有乱码 18 public static final String CHARSET = "GBK"; 19 20 public static StringBuffer result = new StringBuffer(); 21 22 /** 23 * 读省的信息 24 * @param args 25 * @throws Exception 26 */ 27 public static void main(String[] args) throws Exception { 28 String url = baseUrl + "index.html"; 29 //如果需要设置代理 30 //initProxy("10.10.13.200", "80"); 31 String str = getContent(url).toUpperCase(); 32 String[] arrs = str.split("<A"); 33 34 for (String s : arrs) { 35 if (s.indexOf("HREF") != -1 && s.indexOf(".HTML") != -1) { 36 37 String a = s.substring(7, s.indexOf("'>")); 38 String name = s.substring(s.indexOf("'>")+2, s.indexOf("<BR/>")); 39 System.out.println(name); 40 if(!"云南省".equals(name)){//这行代码代表只抓取云南省 41 continue; 42 } 43 44 FileWriter fw = new FileWriter(new File("c:/"+name+".html")); 45 BufferedWriter bw = new BufferedWriter(fw); 46 47 bw.write("<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /></head><body><table border='1' bordercolor='#000000' style='border-collapse:collapse'><tr><td>代码</td><td>省</td><td>市</td><td>县</td><td>镇</td><td>城乡分类</td><td>村/街道</td></tr>"); 48 bw.newLine(); 49 bw.write("<tr><td></td><td>"); 50 bw.write(name); 51 bw.write("</td><td></td><td></td><td></td><td></td><td></td></tr>"); 52 53 bw.newLine(); 54 55 System.out.println("爬取:"+name); 56 57 readShi(a,bw); 58 59 bw.newLine(); 60 bw.write("</table></body></html>"); 61 bw.flush(); 62 bw.close(); 63 } 64 } 65 } 66 67 /** 68 * 读市的数据 69 * @param list 70 * @throws Exception 71 */ 72 public static void readShi(String url,BufferedWriter bw) throws Exception{ 73 String content = getContent(baseUrl+url).toUpperCase(); 74 String[] citys = content.split("CITYTR"); 75 //'><TD><A HREF='11/1101.HTML'>110100000000</A></TD><TD><A HREF='11/1101.HTML'>市辖区</A></TD></td><TR CLASS=' 76 for(int c=1,len=citys.length; c<len; c++){ 77 String[] strs = citys[c].split("<A HREF='"); 78 String cityUrl = null; 79 for(int si = 1; si<3; si++){ 80 if(si==1){//取链接和编码 81 cityUrl = strs[si].substring(0, strs[si].indexOf("'>")); 82 String cityCode = strs[si].substring(strs[si].indexOf("'>")+2, strs[si].indexOf("</A>")); 83 84 bw.write("<tr><td>"); 85 bw.write(cityCode); 86 bw.write("</td>"); 87 }else{ 88 bw.write("<td></td><td>"); 89 bw.write(strs[si].substring(strs[si].indexOf("'>")+2, strs[si].indexOf("</A>"))); 90 bw.write("</td><td></td><td></td><td></td><td></td></tr>"); 91 92 System.out.println("爬取:"+strs[si].substring(strs[si].indexOf("'>")+2, strs[si].indexOf("</A>"))); 93 } 94 } 95 bw.newLine(); 96 readXian(cityUrl.substring(0, cityUrl.indexOf("/")+1),cityUrl,bw); 97 } 98 } 99 100 /** 101 * 读县的数据 102 * @param url 103 * @throws Exception 104 */ 105 public static void readXian(String prix,String url,BufferedWriter bw) throws Exception{ 106 String content = getContent(baseUrl+url).toUpperCase(); 107 String[] citys = content.split("COUNTYTR"); 108 for(int i=1; i<citys.length; i++){ 109 String cityUrl = null; 110 111 //发现石家庄有一个县居然没超链接,特殊处理 112 if(citys[i].indexOf("<A HREF='")==-1){ 113 bw.write("<tr><td>"); 114 bw.write(citys[i].substring(6, 18)); 115 bw.write("</td>"); 116 117 bw.write("<td></td><td></td><td>"); 118 bw.write(citys[i].substring(citys[i].indexOf("</TD><TD>")+9,citys[i].lastIndexOf("</TD>"))); 119 bw.write("</td><td></td><td></td><td></td></tr>"); 120 }else{ 121 String[] strs = citys[i].split("<A HREF='"); 122 for(int si = 1; si<3; si++){ 123 if(si==1){//取链接和编码 124 cityUrl = strs[si].substring(0, strs[si].indexOf("'>")); 125 String cityCode = strs[si].substring(strs[si].indexOf("'>")+2, strs[si].indexOf("</A>")); 126 127 bw.write("<tr><td>"); 128 bw.write(cityCode); 129 bw.write("</td>"); 130 }else{ 131 bw.write("<td></td><td></td><td>"); 132 bw.write(strs[si].substring(strs[si].indexOf("'>")+2, strs[si].indexOf("</A>"))); 133 bw.write("</td><td></td><td></td><td></td></tr>"); 134 } 135 } 136 } 137 bw.newLine(); 138 if(null!=cityUrl){ 139 readZhen(prix,cityUrl,bw); 140 } 141 } 142 } 143 144 /** 145 * 读镇的数据 146 * @param url 147 * @throws Exception 148 */ 149 public static void readZhen(String prix,String url,BufferedWriter bw) throws Exception{ 150 String content = getContent(baseUrl+prix+url).toUpperCase(); 151 String myPrix = (prix+url).substring(0, (prix+url).lastIndexOf("/")+1); 152 String[] citys = content.split("TOWNTR"); 153 for(int i=1; i<citys.length; i++){ 154 String[] strs = citys[i].split("<A HREF='"); 155 String cityUrl = null; 156 for(int si = 1; si<3; si++){ 157 if(si==1){//取链接和编码 158 cityUrl = strs[si].substring(0, strs[si].indexOf("'>")); 159 String cityCode = strs[si].substring(strs[si].indexOf("'>")+2, strs[si].indexOf("</A>")); 160 161 bw.write("<tr><td>"); 162 bw.write(cityCode); 163 bw.write("</td>"); 164 }else{ 165 bw.write("<td></td><td></td><td></td><td>"); 166 bw.write(strs[si].substring(strs[si].indexOf("'>")+2, strs[si].indexOf("</A>"))); 167 bw.write("</td><td></td><td></td></tr>"); 168 } 169 } 170 bw.newLine(); 171 readCun(myPrix,cityUrl,bw); 172 } 173 } 174 175 /** 176 * 读村/街道的数据 177 * @param url 178 * @throws Exception 179 */ 180 public static void readCun(String prix,String url,BufferedWriter bw) throws Exception{ 181 String content = getContent(baseUrl+prix+url).toUpperCase(); 182 String[] citys = content.split("VILLAGETR"); 183 for(int i=1; i<citys.length; i++){ 184 String[] strs = citys[i].split("<TD>"); 185 186 bw.write("<tr><td>"); 187 bw.write(strs[1].substring(0, strs[1].indexOf("</TD>"))); 188 bw.write("</td>"); 189 190 bw.write("<td></td><td></td><td></td><td></td>"); 191 bw.write("<td>"); 192 bw.write(strs[2].substring(0, strs[2].indexOf("</TD>"))); 193 bw.write("</td><td>"); 194 bw.write(strs[3].substring(0, strs[3].indexOf("</TD>"))); 195 bw.write("</td></tr>"); 196 } 197 } 198 199 //设置代理 200 public static void initProxy(String host, String port) { 201 System.setProperty("http.proxyType", "4"); 202 System.setProperty("http.proxyPort", port); 203 System.setProperty("http.proxyHost", host); 204 System.setProperty("http.proxySet", "true"); 205 } 206 207 //获取网页的内容 208 public static String getContent(String strUrl) throws Exception { 209 try { 210 URL url = new URL(strUrl); 211 BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(),Charset.forName(CHARSET))); 212 String s = ""; 213 StringBuffer sb = new StringBuffer(""); 214 while ((s = br.readLine()) != null) { 215 sb.append(s); 216 } 217 218 br.close(); 219 return sb.toString(); 220 } catch (Exception e) { 221 System.out.println("can't open url:"+strUrl); 222 throw e; 223 } 224 } 225 }
运行后获取的文件如下:
各位可以根据自己的需求修改生成的文件的格式,或者直接将结果插入自己的数据库皆可。