Spring Boot基于Jsoup的爬虫实现

一、Jsoup简介

Jsoup是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

Jsoup是根据HTML页面的、、等标签来获取文本内容的,所以先分析一下目标页面结构。打开F12查看页面结构发现,我们要的目标数据在第5个标签 class 属性为provincetr 的 标签里。

图片

比如我们需要爬取的省份名称内容的页面结构如下:

复制代码
<tr class="provincetr">
     <td>
        <a href="11.html">北京市<br></a>
     </td>
     <td>
         <a href="12.html">天津市<br>
     </td>
     .........
</tr>

再拿到标签中标签属性就可以了,省份名称找到了,再看看省对应的城市名在哪里,属性href="11.html" 就是省份下对应的城市页面Url http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2018/11.html

二、爬虫实现

1、引入Jsoup依赖

复制代码
<dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.7.3</version>
</dependency>

2、代码编写

代码的实现也比较简单,只需要按照原网站的元素结构解析嵌套结构就可以了,如下所示。

复制代码
public static void parseProvinceName(Map<String, Map<String, String>> map, String url) throws IOException {


        /**
         * 获取页面文档数据
         */
        Document doc = Jsoup.connect(url).get();


        /**
         * 获取页面上所有的tbody标签
         */
        Elements elements = doc.getElementsByTag("tbody");


        /**
         * 拿到第五个tbody标签
         */
        Element element = elements.get(4);


        /**
         * 拿到tbody标签下所有的子标签
         */
        Elements childrens = element.children();


        /**
         * 当前页面的URL
         */
        String baseUri = element.baseUri();


        for (Element element1 : childrens) {

            Elements provincetrs = element1.getElementsByClass("provincetr");

            for (Element provincetr : provincetrs) {

                Elements tds = provincetr.getElementsByTag("td");
                for (Element td : tds) {


                    String provinceName = td.getElementsByTag("a").text();
                    String href = td.getElementsByTag("a").attr("href");


                    System.out.println(provinceName + "    " + baseUri + "/" + href);


                    map.put(provinceName, null);
                    /**
                      * 组装城市页面的URL,进入城市页面爬城市名称
                      */
                    parseCityName(map, baseUri + "/" + href, provinceName);
                }
            }
        }
    }

在抓取城市名称的时候有一点要注意,直辖市城市的省份和城市名称是一样的。

复制代码
    public static void parseCityName(Map<String, Map<String, String>> map, String url, String provinceName) throws IOException {


        Document doc = Jsoup.connect(url).get();
        Elements elements = doc.getElementsByTag("tbody");
        Element element = elements.get(4);
        Elements childrens = element.children();


        /**
         * 
         */
        String baseUri = element.baseUri();
        Map<String, String> cityMap = new HashMap<>();


        for (Element element1 : childrens) {


            Elements citytrs = element1.getElementsByClass("citytr");


            for (Element cityTag : citytrs) {
                Elements tds = cityTag.getElementsByTag("td");


                /**
                 * 直辖市,城市名就是本身
                 */
                String cityName = tds.get(1).getElementsByTag("a").text();

                if (cityName.equals("市辖区")) {
                    cityName = provinceName;
                }
                String href1 = tds.get(1).getElementsByTag("a").attr("href");


                System.out.println(cityName + " " + href1);

                cityMap.put(cityName, href1);
            }
        }
        map.put(provinceName, cityMap);
    }

下面是一段测试代码。

复制代码
public class test2 {


    public static void main(String[] args) throws IOException {

        Map<String, Map<String, String>> map = new HashMap<>();

        parseProvinceName(map, "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2018");

        System.out.println(JSON.toJSONString(map));
    }
}

需要说明的是,当前只要省份和城市名称,爬虫没有什么深度,如果还需要区县等信息,可以根据市后边的url 35/3508.html 继续往下爬取。

相关推荐
MetaLite1 小时前
SpringBoot接口分层规范-外网网关内部服务与参数边界
java·数据库·spring boot
凤山老林2 小时前
聊聊企业级 API 安全:Spring Boot 落地 OAuth 2.1、mTLS 与接口签名防篡改
spring boot·后端·安全·oauth
Bs_MoneyMagnet8 小时前
基于springboot+vue的旅游景区点评系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·旅游
ID34610744209 小时前
【课程设计】基于Spring Boot+Vue的校园共享无人机服务系统设计与实现-计算机毕设 附源码44219
javascript·vue.js·spring boot·python·node.js·php·课程设计
vx-程序开发11 小时前
【毕设分享】springboot废品上门回收微信小程序---附源码94491
java·spring boot·毕业设计·源码·课程设计·毕设·大作业
行百里er12 小时前
Spring Insight 里如何对 Span 进行清洗
spring boot·spring cloud·监控
谢亮_vipxieliang12 小时前
ValidX时间段验证详解:ISO 8601标准与简化格式
java·spring boot·后端·spring·spring cloud·hibernate
Bs_MoneyMagnet14 小时前
基于springboot+vue的爱心众筹系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·管理系统
EatFan14 小时前
从单体到模块化:我的 Spring Boot 项目为什么拆成 framework、module、server?
java·spring boot·后端
Bs_MoneyMagnet15 小时前
基于springboot+vue的在线音乐管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring