zoukankan      html  css  js  c++  java
  • 使用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 }

    运行后获取的文件如下:

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

  • 相关阅读:
    深入Log4J源码之Log4J Core
    ScheduledThreadPoolExecutor与System#nanoTime
    []JSR 133 (Java Memory Model) FAQ
    happens-before俗解
    ScheduledThreadPoolExecutor实现原理
    Java Timer&TimerTask原理分析
    Java 编程的动态性,第 1 部分: 类和类装入
    结合反射与 XML 实现 Java 编程的动态性
    Java 日志缓存机制的实现
    Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析
  • 原文地址:https://www.cnblogs.com/yangzhilong/p/3530700.html
Copyright © 2011-2022 走看看