抓取国家统计局全国区划代码

最近工作中需要用到全国区划代码,感觉国家统计局提供的数据比较权威,而且也算比较新(截止到2014年10月31日),所以打算把这些数据抓下来。

这是国家统计局提供的查询页面:http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2014/index.html

首先分析下页面

<table class=‘provincetable‘ width=775>
    <tr>
        <td colspan=8 height=1 style=‘FONT-SIZE: 5px‘>&nbsp;</td>
    </tr>
    <tr class=‘provincehead‘>
        <td colspan=8 align=‘center‘ style=‘FONT-SIZE: 16px‘ height=39 vAlign=‘center‘ background=‘images/tiao.jpg‘>
            <strong>2014年统计用区划代码和城乡划分代码(截止2014年10月31日)</strong></td>
    </tr>
    <tr>
        <td colspan=8 height=50 style=‘FONT-SIZE: 12px‘>   统计用区划代码和城乡划分代码说明:统计用区划代码和城乡划分代码所涉及的数据,是国家统计局开展统计调查所涉及的区划范围,未包括我国台湾省、香港特别行政区、澳门特别行政区。
            <br>
        </td>
    </tr>
    <tr class=‘provincetr‘>
        <td><a href=‘11.html‘>北京市<br/></a></td>
        <td><a href=‘12.html‘>天津市<br/></a></td>
        <td><a href=‘13.html‘>河北省<br/></a></td>
        <td><a href=‘14.html‘>山西省<br/></a></td>
        <td><a href=‘15.html‘>内蒙古自治区<br/></a></td>
        <td><a href=‘21.html‘>辽宁省<br/></a></td>
        <td><a href=‘22.html‘>吉林省<br/></a></td>
        <td><a href=‘23.html‘>黑龙江省<br/></a></td>
    </tr>。。。
</table>

页面比较干净,用jsoup解析没有什么困难,所有的地区信息都是放在一个table中的,但是会有几点不同,第一,一级地区信息是从第四个tr开始的,其它等级的地区信息是从第二个tr开始的;第二,每一级地区信息的tr的class不一致;第三,最后一级地区以及市辖区td中的子元素不一致。

由于大部分地区信息的样式都是相同,所以可以有一个大致的思路,可以将全国的地区信息看做成一棵树,比如我们可以将中国看做是这棵树的根节点,然后遍历这棵树,将节点依次插入。

所以节点要定义name也就是地区名,id地区代码,childNodes该地区的下一级地区节点,还有一个就是url,我们利用url访问页面。

有了这个思路我们便可以进行遍历了。

PageFetcher根据url抓取得到页面,ContentParser页面解析器解析页面。

要将节点插入树中,我们首先要构造一个带有子节点的根节点,然后递归遍历所有节点。

由于从页面中取到的链接是一个相对路径,所以我们需要将该链接拼接成一个完整的url,并通过递归传递,当该节点的url为空并且该节点代码的第7位到第10位的值为000时,说明该节点为叶子节点,就会跳出循环不再往下递归。

    public void loadRegionNode(RegionNode regionNode, String superUrl) {

        String url = subUrl(superUrl) + regionNode.getUrl();

        FetchedPage fetchedPage = pageFetcher.getContentFromUrl(url);

        List<RegionNode> list;
        //首页数据已经预先加载
        if (regionNode.getChildNode() == null) {

            list = contentParser.parseHTML(fetchedPage);

        } else {
            list = regionNode.getChildNode();
        }

        //当list为null时则可能遍历到叶子节点
        if (list != null && list.size() > 0) {

            //将子节点插入
            regionNode.setChildNode(list);

            for (RegionNode node : list) {
                //该节点为叶子节点且为最后一级
                if(node.getUrl() == null && !node.getId().substring(6,12).equals("000000") ){
                    break;
                }

                loadRegionNode(node, url);
            }
        }
    }

根据各级地区页面样式的不同,可以利用jsoup定义一个页面解析器,不同等级的地区使用不同的解析策略,所以可以在ContentParser中进行判断,分别解析

    public static List<RegionNode> parseHTML(FetchedPage fetchedPage) {
        //当抓取的页面为空或者返回状态码不是200返回空
        if (fetchedPage == null || fetchedPage.getStatusCode() != 200) {
            return null;
        }
        List<RegionNode> regionNodeList = new ArrayList<RegionNode>();
        Document doc = Jsoup.parse(fetchedPage.getContent());
        //获取当前页面中的地区节点
        Elements tableSet = doc.getElementsByTag("TABLE");
        Element regionTable = tableSet.get(4);
        Elements trSet = regionTable.getElementsByTag("tr");
        for (int i = 1; i < trSet.size(); i++) {
            Element tr = trSet.get(i);
            Elements elements = tr.getAllElements();

            //当子元素数量等于3时,说明为没有子节点的市辖区
            if (elements.size() == 3) {
                Element codeTdTag = elements.get(1);
                Element nameTdTag = elements.get(2);
                String name = nameTdTag.text();
                String code = codeTdTag.text();
                RegionNode regionNode = new RegionNode();
                regionNode.setRegionName(name);
                regionNode.setId(code);
                regionNodeList.add(regionNode);
                System.out.println("code:"+code+";name:"+name);
                continue;
            }

            //当子元素数量等于4时,说明为叶子节点
            if (elements.size() == 4) {
                Element codeTdTag = elements.get(1);
                Element nameTdTag = elements.get(3);
                String name = nameTdTag.text();
                String code = codeTdTag.text();
                RegionNode regionNode = new RegionNode();
                regionNode.setRegionName(name);
                regionNode.setId(code);
                regionNodeList.add(regionNode);
                System.out.println("code:"+code+";name:"+name);
                continue;
            }
            Element codeATag = elements.get(2);
            Element nameATag = elements.get(4);
            String href = codeATag.attr("href");
            String code = codeATag.text();
            String name = nameATag.text();
            RegionNode regionNode = new RegionNode();
            regionNode.setId(code);
            regionNode.setRegionName(name);
            regionNode.setUrl(href);
            regionNodeList.add(regionNode);
            System.out.println("code:"+code+";name:"+name+";href:"+href);
        }
        return regionNodeList;
    }

大概需要等待一个小时,一个完整的树形结构的地区信息就抓取完成了,然后我们可以根据需要保存成json或者xml文件,或者直接保存到数据库中。

源码已经上传到我的github:https://github.com/gordonFm/regionSpider,编译即可运行,数据是以json格式保存的。

时间: 2024-10-07 12:19:47

抓取国家统计局全国区划代码的相关文章

【Heritrix源代码分析4】开始一个爬虫抓取的全流程代码分析

在创建一个job后,就要开始job的运行,运行的全流程如下: 1.在界面上启动job 2.index.jsp 查看上述页面对应的源代码 <a href='"+request.getContextPath()+"/console/action.jsp?action=start'>Start</a> 3.action.jsp String sAction = request.getParameter("action"); if(sAction !

抓取国家统计局2013年全国行政组织机构并插入mysql

数据库创建脚本: /* Navicat MySQL Data Transfer Source Server         : localhost Source Server Version : 50621 Source Host           : localhost:3306 Source Database       : cmm-db Target Server Type    : MYSQL Target Server Version : 50621 File Encoding   

Python 实现网络爬虫 抓取静态网页【代码】

#---------------------------------import--------------------------------------- #coding:utf-8 import urllib2; from BeautifulSoup import BeautifulSoup; #------------------------------------------------------------------------------ def main(): #抓 user

Winfrom 抓取web页面内容代码

WebRequest request = WebRequest.Create("http://1.bjapp.sinaapp.com/play.php?a=" + PageUrl); WebResponse response = request.GetResponse(); Stream resStream = response.GetResponseStream(); StreamReader sr = new StreamReader(resStream, System.Text.

hibernate抓取策略学习

一.hibernate抓取策略概述 Hibernate抓取策略(fetching strategy)是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候, Hibernate如何获取关联对象的策略.抓取策略可以在O/R映射的元数据中声明,也可以在特定的HQL 或条件查询(Criteria Query)中重载声明. 需要注意的是:hibernate的抓取策略只影响get load 方法,对hql是不影响的. 二.hibernate 抓取策略分类 hibernate有如下

从网页抓取数据的一般方法

首先要了解对方网页的执行机制 ,这能够用httpwacth或者httplook来看一下http发送和接收的数据.这两个工具应该说是比較简单易懂的.这里就不再介绍了.主要关注的内容是header和post的内容.通常会包括cookie,Referer页面和其它一些乱其八糟可能看不懂的变量,还有就是正常交互的參数,比方须要post或者get的querystring所包括的东西. httplook和httpwacth 网上有非常多下载的,这里推荐使用httpwach,由于能够直接嵌入到ie中,个人认为

Java抓取网页数据(原网页+Javascript返回数据)

转载请注明出处! 原文链接:http://blog.csdn.net/zgyulongfei/article/details/7909006 有时候因为种种原因,我们须要採集某个站点的数据,但因为不同站点对数据的显示方式略有不同! 本文就用Java给大家演示怎样抓取站点的数据:(1)抓取原网页数据:(2)抓取网页Javascript返回的数据. 一.抓取原网页. 这个样例我们准备从http://ip.chinaz.com上抓取ip查询的结果: 第一步:打开这个网页,然后输入IP:111.142.

Hibernate学习---第十一节:Hibernate之数据抓取策略&amp;批量抓取

1.hibernate 也可以通过标准的 SQL 进行查询 (1).将SQL查询写在 java 代码中 /** * 查询所有 */ @Test public void testQuery(){ // 基于标准的 sql 语句查询 String sql = "select * from t_person"; // 通过 createSQLQuery 获取 SQLQuery,而 SQLQuer 是 Query的子类 SQLQuery query = session.createSQLQue

利用scrapy抓取网易新闻并将其存储在mongoDB

好久没有写爬虫了,写一个scrapy的小爬爬来抓取网易新闻,代码原型是github上的一个爬虫,近期也看了一点mongoDB.顺便小用一下.体验一下NoSQL是什么感觉.言归正传啊.scrapy爬虫主要有几个文件须要改动.这个爬虫须要你装一下mongodb数据库和pymongo,进入数据库之后.利用find语句就能够查看数据库中的内容,抓取的内容例如以下所看到的: { "_id" : ObjectId("5577ae44745d785e65fa8686"), &qu