很早之前发过一个SQL的行政区划代码,是到县一级的,这次的代码是到村一级的。
中国行政区划代码数据库文件 - 最新县及县以上行政区划代码(截止2012年10月31日)
http://blog.csdn.net/isea533/article/details/9140313
2012年统计用区划代码和城乡划分代码
数据来源:http://www.stats.gov.cn/zjtj/tjbz/tjyqhdmhcxhfdm/2012/
格式:XML
预览图:
下载地址:
全国数据(所有数据都在一个XML内):http://pan.baidu.com/s/1hqxD6vU
分省数据:http://pan.baidu.com/s/1c0nCrhm
全国+分省数据:http://pan.baidu.com/s/1o6yNmZK
如果想自己获取,可以运行下面文件(源码在最下面):
Jar文件:http://pan.baidu.com/s/1i30trNJ
XML使用方法:用你会的方法读取XML即可,总比网页获取方便。或者看下面的源码,使用xstream直接读取。
JAR使用方法:如java -jar iseaSpider.jar d:/folderA/ 行政区划_ALL.xml
程序不自动创建目录,请保证目录存在。
程序代码:
一共三个类,其中有两个类代码比较少,直接上截图:
枚举对象:
节点对象,setter和getter省略
依赖JAR包:
技术说明:使用jsoup抓取数据,使用xstream读写xml,具体看代码:
package com.isea.aab301; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; import com.thoughtworks.xstream.XStream; /** * 获取行政区划信息,写入到xml文件 * @author liuzh * */ public class Spider { public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36"; private static final String BASE_URL = "http://www.stats.gov.cn/zjtj/tjbz/tjyqhdmhcxhfdm/2012/"; private static final String INDEX = "index.html"; private int total = 0; private String filePath; public void setFilePath(final String filePath) { String path = filePath.replaceAll("\\\\", "/"); if(!path.endsWith("/")){ path+="/"; } this.filePath = path; } /** * @param args */ public static void main(String[] args) { if(args.length<1||args.length>2){ System.out.println("参数错误"); System.out.println("程序需要一个保存XML的路径和一个可选参数xml文件名,xml文件名默认为\"行政区划_ALL.xml\""); System.out.println("如java -jar iseaSpider.jar d:/folderA/ 行政区划_ALL.xml"); System.out.println("如果字符串有空格,请使用双引号\""); return; } Spider spider = new Spider(); String fileName = "行政区划_ALL.xml"; if(args.length==2){ fileName = args[1]; } spider.setFilePath(args[0]); List<Isea> iseaList = spider.getALL(); //写入到xml try { //spider.toXml(iseaList,"d:/a.xml"); spider.toXml(iseaList,fileName); } catch (Exception e) { e.printStackTrace(); } } /** * 写入到xml * @param list * @param filePath * @throws Exception */ public void toXml(List<Isea> list,String fileName) throws Exception{ XStream xstream = new XStream(); xstream.alias("areas", List.class); xstream.autodetectAnnotations(true); FileOutputStream fos = null; try { fos = new FileOutputStream(new File(filePath+fileName)); fos.write("<?xml version=\"1.0\" encoding=\"GBK\" ?>\n".getBytes()); xstream.toXML(list, fos); } finally { try { if(fos!=null){ fos.close(); } } catch (Exception e) { throw new Exception(e.getMessage()); } } } /** * 写入到xml * @param list * @param filePath * @throws Exception */ @SuppressWarnings("unchecked") public List<Isea> fromXml(String fileName) { System.out.println("读取:"+fileName); XStream xstream = new XStream(); xstream.alias("areas", ArrayList.class); xstream.alias("area", Isea.class); xstream.autodetectAnnotations(true); FileInputStream fis = null; try { fis = new FileInputStream(new File(filePath+fileName)); return (List<Isea>)xstream.fromXML(new File(filePath+fileName),Charset.forName("UTF8")); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if(fis!=null){ try { fis.close(); } catch (IOException e) { } } } return null; } /** * 判断文件是否存在 * @param fileName * @return */ private boolean fileExists(String fileName){ File file = new File(filePath+fileName); if(file.exists()){ return true; } return false; } /** * 获取全部级别信息 * @return */ public List<Isea> getALL(){ Document doc = getDoc(BASE_URL+INDEX); List<Isea> iseaList = getProvince(doc); for(Isea isea:iseaList){ if(fileExists(isea.getText()+".xml")){ //已经存在..直接读取 isea.setChildren(fromXml(isea.getText()+".xml")); } else { isea.setChildren(getCity(isea)); //单个文件写入 try { toXml(isea.getChildren(), isea.getText()+".xml"); } catch (Exception e) { System.out.println(e.getMessage()); } } } return iseaList; } /** * 获取省-直辖市地址 * @param baseDoc * @return */ public List<Isea> getProvince(Document baseDoc){ Elements elements = baseDoc.select(".provincetr td a"); Iterator<Element> iter = elements.iterator(); Element element = null; List<Isea> list = new ArrayList<Isea>(); Isea a = null; while (iter.hasNext()) { element = iter.next(); a = new Isea(); String href = element.attr("href"); a.setType(DM.PROVINCE.toString()); a.setLevel(1); a.setHref(BASE_URL+href); a.setText(element.text()); a.setCode(href.substring(0,href.lastIndexOf("."))); System.out.println("省:"+a.getText() + " - 代码:"+a.getCode()); list.add(a); } return list; } /** * 获取市 * @param baseDoc * @return */ public List<Isea> getCity(Isea isea){ if(isea.getHref()==null||isea.getHref().equals("")){ return null; } String baseURL = isea.getHref(); baseURL = baseURL.substring(0,baseURL.lastIndexOf("/")+1); return getBase(isea,DM.CITY,baseURL); } /** * 获取县区 * @param baseDoc * @return */ public List<Isea> getCounty(Isea isea){ //http://www.stats.gov.cn/zjtj/tjbz/tjyqhdmhcxhfdm/2012/13/ 1301.html if(isea.getHref()==null||isea.getHref().equals("")){ return null; } String baseURL = isea.getHref(); baseURL = baseURL.substring(0,baseURL.lastIndexOf("/")+1); return getBase(isea,DM.COUNTY,baseURL); } /** * 获取乡镇 * @param baseDoc * @return */ public List<Isea> getTown(Isea isea){ //http://www.stats.gov.cn/zjtj/tjbz/tjyqhdmhcxhfdm/2012/13/01/ 130102.html //http://www.stats.gov.cn/zjtj/tjbz/tjyqhdmhcxhfdm/2012/13/01/02/ 130102001.html if(isea.getHref()==null||isea.getHref().equals("")){ return null; } String baseURL = isea.getHref(); baseURL = baseURL.substring(0,baseURL.lastIndexOf("/")+1); return getBase(isea,DM.TOWN,baseURL); } /** * 获取村社区 * @param baseDoc * @return */ public List<Isea> getvillage(Isea isea){ return getBase(isea,DM.VILLAGE,null); } /** * 获取基础 * @param baseDoc * @return */ public List<Isea> getBase(Isea isea,DM dm,String baseURL){ if(isea.getHref()==null){ return null; } Document doc = getDoc(isea.getHref()); if(doc==null){ return null; } Elements elements = doc.select(dm.val()); Iterator<Element> iter = elements.iterator(); Element element = null; List<Isea> list = new ArrayList<Isea>(); Isea a = null; while (iter.hasNext()) { element = iter.next(); Elements es = null; es = element.select("td"); Iterator<Element> is = es.iterator(); a = new Isea(); //设置类型 - 村一级的特殊 a.setType(dm.toString()); //等级 a.setLevel(isea.getLevel()+1); Element el = null; if(is.hasNext()){ el = is.next(); if(el.select("a").size()>0){ String href = el.select("a").first().attr("href"); if(href!=null&&!href.equals("")&&baseURL!=null){ a.setHref(baseURL+href); } else { a.setHref(null); } } else { a.setHref(null); } a.setCode(el.text()); } //VILLAGE特殊 if(dm ==DM.VILLAGE){ if(is.hasNext()){ el = is.next(); a.setType(el.text()); } } if(is.hasNext()){ //从这个上面也能获取URL,如果URL不存在,则将之前的URL = null el = is.next(); if(el.select("a").size()>0){ String href = el.select("a").first().attr("href"); if(href!=null&&!href.equals("")&&baseURL!=null){ a.setHref(baseURL+href); } else { a.setHref(null); } } else { a.setHref(null); } a.setText(el.text()); } System.out.println("序号:"+(total++)+" - 名称:"+a.getText() + " - 代码:"+a.getCode()); //获取子节点 switch (dm) { case CITY: //获取子节点 a.setChildren(getCounty(a)); break; case COUNTY: a.setChildren(getTown(a)); break; case TOWN: a.setChildren(getvillage(a)); break; default: break; } list.add(a); } return list; } /** * 获取网页内容 * @param url * @return */ public Document getDoc(String url){ Document doc = null; try { doc = Jsoup.connect(url).timeout(0).userAgent(USER_AGENT).get(); } catch (Exception e) { System.out.println(e.getMessage()); } return doc; } }
主要代码很简单,上面是为了处理一些特殊情况,代码量增加不少。。
为了防止获取过程中断线等异常情况,程序会分省写入xml,再次执行的时候会直接读取已有的xml,不会从头开始。
使用上面XML的时候,上面源码中提供了方法:
/** * 写入到xml * @param list * @param filePath * @throws Exception */ @SuppressWarnings("unchecked") public List<Isea> fromXml(String fileName) { System.out.println("读取:"+fileName); XStream xstream = new XStream(); xstream.alias("areas", ArrayList.class); xstream.alias("area", Isea.class); xstream.autodetectAnnotations(true); FileInputStream fis = null; try { fis = new FileInputStream(new File(filePath+fileName)); return (List<Isea>)xstream.fromXML(new File(filePath+fileName),Charset.forName("UTF8")); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if(fis!=null){ try { fis.close(); } catch (IOException e) { } } } return null; }
转载或分享数据请注明作者。