使用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 }

 

 

运行后获取的文件如下:

 

各位可以根据自己的需求修改生成的文件的格式,或者直接将结果插入自己的数据库皆可。

posted @ 2014-01-23 09:50  自行车上的程序员  阅读(7628)  评论(12编辑  收藏  举报