很早之前发过一个sql的行政区划代码,是到县一级的,这次的代码是到村一级的。
中国行政区划代码数据库文件 - 最新县及县以上行政区划代码(截止2012年10月31日)
http://www.jb51.cc/article/p-wwujmdhh-hs.html
数据来源: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,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,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",Charset.forName("UTF8"));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } finally {
- if(fis!=null){
- try {
- fis.close();
- } catch (IOException e) {
- }
- }
- }
- return null;
- }
转载或分享数据请注明作者。