Jsoup爬虫入门实战(包含页数区间进行查询)

Jsoup爬虫入门实战(包含页数区间进行查询)

简介

jsoup是一款Java的HTML解析器,主要用来对HTML解析。

在爬虫的时候,当我们用HttpClient之类的框架,获取到网页源码之后,需要从网页源码中取出我们想要的内容,

就可以使用jsoup这类HTML解析器了。可以非常轻松的实现。

虽然jsoup也支持从某个地址直接去爬取网页源码,但是只支持HTTP,HTTPS协议,支持不够丰富。

代码讲解

创建项目

创建一个springboot项目
在这里插入图片描述
随便加一点依赖
在这里插入图片描述

pom.xml

引入jsoup依赖
在这里插入图片描述
完整的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.8</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>Jsoup</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Jsoup</name>
    <description>Jsoup</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
<!--        解析网页-->
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.10.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

创建文件

在这里插入图片描述
在网页中寻找商品栏目

在这里插入图片描述

  • 项目结构
    在这里插入图片描述
    演示代码
public class HtmlParseUtil {
    public static void main(String[] args) throws IOException {
        // 获取请求 https://search.jd.com/Search?keyword=java
        // 定义URL
        String url = "https://search.jd.com/Search?keyword=java";
        // 解析网页
        Document doucument = Jsoup.parse(new URL(url), 30000);
        // 对于document对象,所有js中可以使用的方法,这里都能使用
        Element element = doucument.getElementById("J_goodsList");
        System.out.println(element.html());
    }
}

运行结果
这里就是把网页中J_goodsList中包含的内容打印出来了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 这里才是图片的正确存放地址
    在这里插入图片描述

  • 这里是存放其他信息的地方
    在这里插入图片描述

完整代码

public class HtmlParseUtil {
    public static void main(String[] args) throws IOException {
        // 获取请求 https://search.jd.com/Search?keyword=java
        // 定义URL
        String url = "https://search.jd.com/Search?keyword=java";
        // 解析网页
        Document doucument = Jsoup.parse(new URL(url), 30000);
        // 对于document对象,所有js中可以使用的方法,这里都能使用
        Element element = doucument.getElementById("J_goodsList");
        // 打印整个网页的内容
//        System.out.println(element.html());

        // 获取所有的li元素
        Elements elements = element.getElementsByTag("li");

        for (Element el: elements){
            // 阴暗图片会延迟加载所以这个图片的 显示位置不一定是src
            // 比如京东现在是 data-lazy-img
            String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
            String price = el.getElementsByClass("p-price").eq(0).text();
            String title = el.getElementsByClass("p-name").eq(0).text();
            System.out.println(img);
            System.out.println(price);
            System.out.println(title);
            System.out.println("==============================================");
        }
    }
}

运行结果
成功的获取了信息
在这里插入图片描述

封装类和方法

  • 首先创建一个Content类存放爬取结果的基础信息

  • 然后封装方法并测试
    通过指定这个parseID中的传入的参数就可以指定爬取什么方面的内容,比如这篇文章里面的心理学
package com.example.jsoup.utils;

import com.example.jsoup.pojo.Content;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

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

        new HtmlParseUtil().parseJD("心理学").forEach((System.out::println));
    }
    // 封装成为一个函数
    public List<Content> parseJD(String keywords) throws IOException{
        // 首先处理一下,防止中文报错的情况发生
        keywords = URLEncoder.encode(keywords, String.valueOf(StandardCharsets.UTF_8));
        // 获取请求 https://search.jd.com/Search?keyword=java
        // 定义URL
        String url = "https://search.jd.com/Search?keyword="+ keywords;
        // 解析网页
        Document doucument = Jsoup.parse(new URL(url), 30000);
        // 对于document对象,所有js中可以使用的方法,这里都能使用
        Element element = doucument.getElementById("J_goodsList");

        ArrayList<Content> goodslist = new ArrayList<>();

        // 获取所有的li元素
        Elements elements = element.getElementsByTag("li");
        for (Element el: elements){
            // 阴暗图片会延迟加载所以这个图片的 显示位置不一定是src
            // 比如京东现在是 data-lazy-img
            String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
            String price = el.getElementsByClass("p-price").eq(0).text();
            String title = el.getElementsByClass("p-name").eq(0).text();

            Content content = new Content();
            content.setTitle(title);
            content.setPrice(price);
            content.setImg(img);
            goodslist.add(content);
        }
        return goodslist;
    }
}

运行结果
在这里插入图片描述
很显然现在可以了,但是我们现在还差一个分页查询的功能,我们希望可以分页查询。

按页数查询

首先我们是需要分析一下,这个分页查询,需要多观察结果这个网站的URL的格式。
第一页这个pages是1
在这里插入图片描述

第二页这个pages是3
在这里插入图片描述

第三页是5
在这里插入图片描述

然后这个pages的规律我们就找到了2n-1
然后我们的代码就可以写出来了。
在这个版本的代码中,我们就可以指定这个页数了,分页进行爬取,然后还可以优化,比如给这个函数,加上爬取多少多少页到多少多少页的数据。

完整代码如下

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

        new HtmlParseUtil().parseJD("心理学", 2).forEach((System.out::println));
    }
    // 封装成为一个函数
    public List<Content> parseJD(String keywords, Integer num) throws IOException{
        // 首先处理一下,防止中文报错的情况发生
        keywords = URLEncoder.encode(keywords, String.valueOf(StandardCharsets.UTF_8));
        num = 2 * num - 1;
        // 获取请求 https://search.jd.com/Search?keyword=java
        // 定义URL
        String url = "https://search.jd.com/Search?keyword="+ keywords + "&pvid=b96720a855674429be9c864dd9bc1f25&page=" + num;
        // 解析网页
        Document doucument = Jsoup.parse(new URL(url), 30000);
        // 对于document对象,所有js中可以使用的方法,这里都能使用
        Element element = doucument.getElementById("J_goodsList");

        ArrayList<Content> goodslist = new ArrayList<>();

        // 获取所有的li元素
        Elements elements = element.getElementsByTag("li");
        for (Element el: elements){
            // 阴暗图片会延迟加载所以这个图片的 显示位置不一定是src
            // 比如京东现在是 data-lazy-img
            String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
            String price = el.getElementsByClass("p-price").eq(0).text();
            String title = el.getElementsByClass("p-name").eq(0).text();

            Content content = new Content();
            content.setTitle(title);
            content.setPrice(price);
            content.setImg(img);
            goodslist.add(content);
        }
        return goodslist;
    }
}

按页数区间进行查询

在这个版本中,我添加了按照页数区间的功能,这样的话,我们就可以查询的时候,不需要自己手动翻页了,自动翻页更为方便。

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

        new HtmlParseUtil().parseJD("心理学", 1, 2).forEach((System.out::println));
    }
    // 封装成为一个函数
    public List<Content> parseJD(String keywords, Integer leftNum, Integer rightNum) throws IOException{
        // 首先处理一下,防止中文报错的情况发生
        keywords = URLEncoder.encode(keywords, String.valueOf(StandardCharsets.UTF_8));
        leftNum = 2 * leftNum - 1;
        rightNum = 2 * rightNum - 1;
        // 获取请求 https://search.jd.com/Search?keyword=java
        // 定义URL
        String url = "https://search.jd.com/Search?keyword="+ keywords + "&pvid=b96720a855674429be9c864dd9bc1f25&page=";


        ArrayList<Content> goodslist = new ArrayList<>();

        for (int i = leftNum; i <= rightNum; ++ i){
            String newUrl = url + i;
            // 解析网页
            Document doucument = Jsoup.parse(new URL(url), 30000);
            // 对于document对象,所有js中可以使用的方法,这里都能使用
            Element element = doucument.getElementById("J_goodsList");
            // 获取所有的li元素
            Elements elements = element.getElementsByTag("li");
            for (Element el: elements){
                // 阴暗图片会延迟加载所以这个图片的 显示位置不一定是src
                // 比如京东现在是 data-lazy-img
                String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
                String price = el.getElementsByClass("p-price").eq(0).text();
                String title = el.getElementsByClass("p-name").eq(0).text();

                Content content = new Content();
                content.setTitle(title);
                content.setPrice(price);
                content.setImg(img);
                goodslist.add(content);
            }
        }

        return goodslist;
    }
}

运行结果
在这里插入图片描述

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客李华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值