Administrator
Published on 2026-03-10 / 7 Visits
0

Jsoup 核心使用方式完整总结

#AI

Jsoup 核心使用方式完整总结

Jsoup 是一款基于 Java 开发的 HTML/XML 解析工具,遵循 WHATWG HTML5 规范,能将各类不规范的 HTML 解析为标准 DOM 树,提供了 DOM 遍历、CSS 选择器、XPath 选择器等便捷的 API,支持从 URL、文件、字符串中解析内容,还能完成 HTML 内容操作、XSS 过滤等功能,是 Java 开发中网页爬虫、HTML 处理的主流工具。

本文结合 Jsoup 官方文档与第三方实战教程,从环境搭建核心对象获取元素查找数据提取实战案例高级特性六个维度,详细总结其使用方式。

一、环境搭建

Jsoup 基于 Maven/Gradle 进行依赖管理,也可直接下载 JAR 包引入项目,官方最新版本为 1.21.1,第三方实战常用稳定版 1.12.1。

1. Maven 依赖

<!-- 稳定版 1.12.1 -->
<dependency>
  <groupId>org.jsoup</groupId>
  <artifactId>jsoup</artifactId>
  <version>1.12.1</version>
</dependency>

<!-- 官方最新版 1.21.1 -->
<dependency>
  <groupId>org.jsoup</groupId>
  <artifactId>jsoup</artifactId>
  <version>1.21.1</version>
</dependency>

2. Gradle 依赖

implementation 'org.jsoup:jsoup:1.21.1'

二、核心对象:Document 的获取

Jsoup 所有操作均围绕 org.jsoup.nodes.Document 对象展开,该对象代表解析后的 HTML 文档,可从URL本地文件字符串三种来源获取,同时支持自定义请求参数模拟浏览器行为。

1. 从 URL 解析(爬虫常用)

通过 Jsoup.connect(String url) 方法创建连接,支持设置请求头、Cookie、超时时间、请求参数等,最终通过 get()/post() 发送请求并解析为 Document。

基础用法

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;

public class JsoupUrlDemo {
    public static void main(String[] args) throws IOException {
        // 直接连接 URL 并解析
        Document doc = Jsoup.connect("https://www.baidu.com").get();
        // 获取网页标题
        System.out.println(doc.title());
    }
}

自定义请求参数(模拟浏览器)

Document doc = Jsoup.connect("https://example.com")
        .data("query", "Java") // 设置请求参数
        .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0") // 请求头:浏览器标识
        .cookie("auth", "token123") // 设置 Cookie
        .timeout(3000) // 超时时间 3 秒
        .header("Referer", "https://baidu.com") // 自定义请求头
        .post(); // 发送 POST 请求(get() 为 GET 请求)

2. 从本地文件解析

适用于本地 HTML 文件的解析,通过 Jsoup.parse(File file, String charset, String baseUri) 实现,baseUri 用于解析相对路径。

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.File;
import java.io.IOException;

public class JsoupFileDemo {
    public static void main(String[] args) throws IOException {
        File input = new File("D:/test.html"); // 本地 HTML 文件路径
        // 解析文件,编码为 UTF-8,baseUri 为网页根路径
        Document doc = Jsoup.parse(input, "UTF-8", "https://example.com");
    }
}

3. 从字符串解析

适用于已有 HTML 字符串的场景(如通过 HttpClient 获取的网页源码),直接通过 Jsoup.parse(String html) 解析。

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class JsoupStringDemo {
    public static void main(String[] args) {
        String html = "<html><head><title>测试页面</title></head><body><p>Hello Jsoup</p></body></html>";
        Document doc = Jsoup.parse(html);
        System.out.println(doc.title()); // 输出:测试页面
    }
}

三、元素查找:从 Document 中获取 Element/Elements

Jsoup 提供DOM 原生方式CSS 选择器方式两种元素查找方法,其中 CSS 选择器方式功能更强大、语法更简洁,是实际开发的首选;官方还支持 XPath 选择器,进一步提升查找灵活性。

1. DOM 原生方式

通过元素的ID、标签名、类名、属性等原生 DOM 方法查找,方法名语义化,易于理解,适用于简单的元素查找。

方法名功能说明
getElementById(String id)通过 ID 获取单个元素(Element)
getElementsByTag(String tagName)通过标签名获取元素集合(Elements)
getElementsByClass(String className)通过类名获取元素集合(Elements)
getElementsByAttribute(String key)通过属性名获取元素集合(Elements)
getElementsByAttributeValue(String key, String value)通过属性名+属性值获取元素集合(Elements)
getAllElements()获取文档中所有元素(Elements)

示例

// 通过 ID 获取元素
Element logo = doc.getElementById("logo");
// 通过标签名获取所有 p 标签
Elements pList = doc.getElementsByTag("p");
// 通过类名获取所有 class="content" 的元素
Elements contentList = doc.getElementsByClass("content");
// 通过属性名获取所有带 href 属性的元素
Elements hrefList = doc.getElementsByAttribute("href");

2. CSS 选择器方式(核心)

通过 Element.select(String cssQuery) 方法实现,支持所有 CSS 标准选择器+Jsoup 扩展伪选择器,语法与 jQuery 一致,适用于复杂的元素筛选,是 Jsoup 最核心的功能之一。

2.1 基础选择器(CSS 标准)

涵盖通配符、标签、ID、类、属性等基础筛选规则,可自由组合使用。

选择器语法功能说明示例
*匹配所有元素doc.select("*")
tag匹配指定标签名的元素doc.select("div")(所有 div 标签)
#id匹配指定 ID 的元素doc.select("#wrap")(ID 为 wrap 的元素)
.class匹配指定类名的元素doc.select(".masthead")(类为 masthead 的元素)
[attr]匹配包含指定属性的元素doc.select("[href]")(带 href 属性的元素)
[attr=val]匹配属性值等于 val 的元素doc.select("[width=500]")
[attr^=val]匹配属性值以 val 开头的元素doc.select("a[href^=http:]")(http 开头的链接)
[attr$=val]匹配属性值以 val 结尾的元素doc.select("img[src$=.png]")(png 后缀的图片)
[attr*=val]匹配属性值包含 val的元素doc.select("a[href*=/search/]")(包含/search/的链接)
[attr~=regex]匹配属性值符合正则的元素`doc.select("img[src~=(?i)\.(png
el#id/el.class/el[attr]元素+ID/类/属性组合doc.select("div#logo")(ID 为 logo 的 div)

2.2 层级关系选择器

用于筛选父子、兄弟、后代关系的元素,精准定位嵌套结构中的目标元素。

选择器语法功能说明示例
ancestor child匹配祖先元素下的所有后代子元素doc.select(".body p")(.body 下的所有 p 标签)
parent > child匹配父元素的直接子元素(非后代)doc.select("div.content > p")(div.content 直接子元素 p)
siblingA + siblingB匹配紧接在 siblingA 后的相邻同级元素doc.select("li + li")(li 后的下一个 li)
siblingA ~ siblingX匹配 siblingA 后的所有同级元素doc.select("h1 ~ p")(h1 后的所有 p 标签)
el1, el2, el3匹配多个选择器的并集doc.select("a[href], div, h3")(带 href 的 a + 所有 div + 所有 h3)

2.3 Jsoup 扩展伪选择器(重点)

Jsoup 在 CSS 标准基础上扩展了大量伪选择器,用于按索引、文本、子元素等筛选,是复杂筛选的关键,索引从 0 开始

伪选择器语法功能说明示例
:lt(n)匹配同级索引小于 n的元素doc.select("td:lt(3)")(前 3 个 td 标签)
:gt(n)匹配同级索引大于 n的元素doc.select("div p:gt(2)")(div 下索引>2 的 p 标签)
:eq(n)匹配同级索引等于 n的元素doc.select("input:eq(1)")(第二个 input 标签)
:has(selector)匹配包含指定子元素的元素doc.select("div:has(p)")(包含 p 标签的 div)
:not(selector)匹配不满足指定选择器的元素doc.select("div:not(.logo)")(类不是 logo 的 div)
:contains(text)匹配包含指定文本的元素(忽略大小写,文本可在后代中)doc.select("p:contains(Jsoup)")(包含 Jsoup 的 p 标签)
:containsOwn(text)匹配直接包含指定文本的元素(文本仅在自身,非后代)doc.select("p:containsOwn(Java)")
:matches(regex)匹配文本符合正则的元素(忽略大小写,文本可在后代)doc.select("div:matches((?i)login)")(包含 login 的 div,忽略大小写)
:empty匹配空元素(无子元素/有效文本)doc.select("li:not(:empty)")(非空的 li 标签)
:first-child匹配父元素的第一个子元素doc.select("div > p:first-child")
:last-child匹配父元素的最后一个子元素doc.select("ol > li:last-child")

2.4 官方新增伪选择器(1.21.1+)

官方最新版本新增了更强大的伪选择器,进一步提升筛选能力:

  • :is(selector list):匹配任意一个选择器的元素,如 :is(h1, h2, h3)(所有标题标签);
  • :containsWholeText(text):匹配包含原文本的元素(区分空格/换行,不做文本归一化);
  • :nth-child(an+b):按公式匹配子元素,如 tr:nth-child(2n+1)(表格奇数行);
  • :matchText:将文本节点视为元素,支持匹配文本节点,如 p:matchText:firstChild

CSS 选择器综合示例

// 选择所有带 href 属性的 a 标签
Elements links = doc.select("a[href]");
// 选择 class 为 masthead 的第一个 div 标签
Element masthead = doc.select("div.masthead").first();
// 选择 h3 标签内的直接子元素 a 标签
Elements resultLinks = doc.select("h3 > a");
// 选择包含“2020年高职扩招”的 td 下的 a 标签(实战常用)
Elements schoolLinks = doc.select("td a[href]:contains(2020年高职扩招)");

3. XPath 选择器

Jsoup 官方支持 XPath 语法查找元素,需结合 XPathEvaluator 使用,适用于习惯 XPath 的开发者,可实现更灵活的节点遍历。

示例

import org.jsoup.nodes.Document;
import org.jsoup.select.XPathEvaluator;
import org.jsoup.select.XPathResult;

public class JsoupXPathDemo {
    public static void main(String[] args) throws Exception {
        Document doc = Jsoup.connect("https://example.com").get();
        // 定义 XPath 表达式:选择所有 div 下的 p 标签
        XPathEvaluator evaluator = XPathEvaluator.compile("//div/p");
        XPathResult result = evaluator.evaluate(doc);
        // 遍历结果
        result.forEach(element -> System.out.println(element.text()));
    }
}

四、数据提取:从 Element/Elements 中获取内容

找到目标元素后,通过 Jsoup 提供的 API 提取文本、HTML 内容、属性值、URL等核心数据,ElementsElement 的集合,可通过遍历获取单个 Element 后再提取数据。

1. 文本提取

方法功能说明
Element.text()获取元素的纯文本内容(去除所有 HTML 标签,合并后代文本)
Element.ownText()获取元素自身的纯文本(不包含后代元素的文本)

示例

// 获取元素所有纯文本
String text = element.text();
// 获取元素自身纯文本
String ownText = element.ownText();

2. HTML 内容提取

方法功能说明
Element.html()获取元素内部的 HTML 内容(包含子元素标签)
Node.outerHtml()获取元素自身+内部的全部 HTML 内容(包含当前元素标签)
Document.html()获取整个文档的 HTML 内容

示例

// 内部 HTML(子元素)
String innerHtml = element.html();
// 全部 HTML(自身+子元素)
String outerHtml = element.outerHtml();

3. 属性值提取

核心方法:Element.attr(String key),传入属性名即可获取属性值,支持所有 HTML 原生属性(href、src、class、id 等),是爬虫提取链接、图片地址的核心方法。

示例

// 提取 a 标签的链接(href)
String href = element.attr("href");
// 提取 img 标签的图片地址(src)
String src = element.attr("src");
// 提取元素的类名(class)
String className = element.attr("class");

4. URL 标准化提取

针对链接(href)、图片地址(src)等相对路径,Jsoup 提供了绝对路径转换方法,避免路径失效。

// 提取绝对路径的链接(自动拼接 baseUri)
String absHref = element.absUrl("href");
// 提取绝对路径的图片地址
String absSrc = element.absUrl("src");

5. 集合遍历提取

Elements 是元素集合,需通过增强 for 循环流式遍历提取每个元素的内容:

Elements links = doc.select("a[href]");
// 增强 for 循环
for (Element link : links) {
    String text = link.text(); // 链接文本
    String href = link.absUrl("href"); // 绝对链接
    System.out.println(text + " : " + href);
}
// 流式遍历(Java 8+)
links.stream().forEach(link -> {
    System.out.println(link.text() + " : " + link.absUrl("href"));
});

五、实战案例:网页数据爬取(高职扩招信息抓取)

结合上述所有知识点,实现多页网页爬取:抓取教育网站上 2020 年高职扩招的学校名称及对应链接,覆盖URL 拼接、CSS 选择器筛选、元素遍历、数据提取核心步骤。

完整代码

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;

/**
 * Jsoup 实战:抓取2020年高职扩招学校名称及链接
 */
@Slf4j
public class JsoupCrawlDemo {
    public static void main(String[] args) throws IOException {
        // 目标URL(分页参数为?page=1、?page=2...)
        String baseUrl = "http://xxx/result/query";
        // 爬取第1-5页
        for (int i = 1; i < 6; i++) {
            String url = baseUrl + "?page=" + i;
            // 1. 连接URL并解析为Document
            Document doc = Jsoup.connect(url).timeout(5000).get();
            log.info("开始爬取第{}页,URL:{}", i, url);

            // 2. CSS选择器筛选目标元素:td下带href、包含指定文本的a标签
            Elements schoolLinks1 = doc.select("td a[href]:contains(2020年高职扩招)");
            Elements schoolLinks2 = doc.select("td a[href]:contains(2020年扩招)");
            // 合并两个结果集,避免遗漏
            schoolLinks1.addAll(schoolLinks2);
            log.info("第{}页找到{}所学校", i, schoolLinks1.size());

            // 3. 遍历元素,提取数据
            if (!schoolLinks1.isEmpty()) {
                for (Element link : schoolLinks1) {
                    String schoolName = link.text(); // 学校名称
                    String schoolHref = link.absUrl("href"); // 学校链接(绝对路径)
                    log.info("学校名称:{},链接:{}", schoolName, schoolHref);
                }
            }
        }
    }
}

核心要点

  1. 分页处理:通过拼接 ?page=i 实现多页爬取;
  2. 精准筛选:使用 :contains 伪选择器筛选包含指定文本的元素,避免无效数据;
  3. 结果合并:将两个相似条件的结果集合并,防止数据遗漏;
  4. 绝对路径:使用 absUrl() 提取链接,避免相对路径导致的访问失败;
  5. 超时设置:通过 timeout(5000) 设置超时,防止请求阻塞。

六、Jsoup 高级特性

爬取需要登录的网页时,通过 Jsoup 的 Connection 对象执行登录请求,获取返回的 Cookie,后续请求携带该 Cookie 即可实现登录态保持。

import org.jsoup.Jsoup;
import org.jsoup.Connection;
import org.jsoup.Connection.Response;
import java.io.IOException;
import java.util.Map;

public class JsoupLoginDemo {
    public static void main(String[] args) throws IOException {
        // 登录接口URL
        String loginUrl = "http://www.iotcloud168.com:8083/user/login?username=181228001&password=123";
        // 执行登录请求
        Connection connect = Jsoup.connect(loginUrl);
        Response response = connect.execute();
        // 获取登录后的Cookie
        Map<String, String> cookies = response.cookies();

        // 后续请求携带Cookie,实现登录态
        Document doc = Jsoup.connect("http://www.iotcloud168.com:8083/user/info")
                .cookies(cookies) // 携带登录Cookie
                .get();
    }
}

2. HTML 内容操作

Jsoup 支持对 HTML 元素进行新增、修改、删除操作,适用于 HTML 文档处理。

// 修改元素文本
element.text("新的文本内容");
// 修改元素HTML
element.html("<p>新的HTML内容</p>");
// 修改元素属性
element.attr("href", "https://new-url.com");
// 新增子元素
element.append("<span>新增子元素</span>");
// 删除元素
element.remove();

3. XSS 过滤(HTML 清洗)

Jsoup 提供内置的 XSS 过滤工具,可通过白名单过滤不安全的 HTML 标签和属性,防止用户提交的内容包含 XSS 攻击代码。

import org.jsoup.Jsoup;
import org.jsoup.safety.Safelist;

public class JsoupXssDemo {
    public static void main(String[] args) {
        // 待清洗的HTML(包含恶意脚本)
        String unsafeHtml = "<p>测试</p><script>alert('XSS')</script><img src=x onerror=alert(1)>";
        // 使用官方默认白名单(仅允许基本的文本标签)
        Safelist safelist = Safelist.basic();
        // 清洗HTML,过滤恶意代码
        String safeHtml = Jsoup.clean(unsafeHtml, safelist);
        System.out.println(safeHtml); // 输出:<p>测试</p><img>
    }
}

Jsoup 提供多种预设白名单,可根据需求选择:Safelist.none()(无标签)、Safelist.simpleText()(仅文本)、Safelist.basic()(基本文本标签)、Safelist.relaxed()(宽松模式,允许大部分标签)。

4. 大文档高效解析

针对超大 HTML 文档,Jsoup 提供 StreamParser 实现流式解析,避免一次性加载整个文档到内存,提升解析效率。

import org.jsoup.parser.StreamParser;
import java.io.FileReader;
import java.io.Reader;

public class JsoupStreamDemo {
    public static void main(String[] args) throws Exception {
        Reader reader = new FileReader("D:/large.html");
        // 流式解析,逐行处理
        StreamParser parser = new StreamParser(reader);
        parser.parse((event, position) -> {
            // 处理解析事件(如标签开始、文本节点等)
            System.out.println(event);
            return true; // 继续解析
        });
    }
}

七、核心总结

  1. 核心定位:Jsoup 是 Java 生态最优秀的 HTML 解析工具,主打便捷性兼容性,能处理各类不规范的 HTML;
  2. 核心流程获取Document查找Element/Elements提取数据,是爬虫开发的固定流程;
  3. 核心技能:CSS 选择器是 Jsoup 的核心,掌握基础选择器+层级选择器+扩展伪选择器,就能解决 99% 的元素查找问题;
  4. 实战技巧:提取链接时优先使用 absUrl() 转换为绝对路径,爬取多页时做好超时设置,登录场景需管理 Cookie;
  5. 高级能力:除了爬虫,Jsoup 还能实现 HTML 内容操作、XSS 过滤、大文档流式解析,是前端/后端 HTML 处理的通用工具。

Jsoup 遵循 MIT 开源协议,源码托管在 GitHub,官方文档提供了丰富的示例和 Cookbook,是学习和使用的最佳参考。

https://jsoup.org/
https://jsoup.org/apidocs/org/jsoup/select/Selector.html
https://tio-boot.litongjava.com/zh/34_spider/01.html