Skip to content

Java Jsoup 使用笔记

Jsoup 是一个 Java 库,用于解析 HTML 文档、提取数据和处理 DOM 结构。它类似于 jQuery 的 API,适用于网页抓取和数据提取。

1. 引入 Jsoup

Maven 依赖

xml

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.17.2</version> <!-- 最新版本 -->
</dependency>

Gradle 依赖

gradle
implementation 'org.jsoup:jsoup:1.17.2'

2. 基本用法

(1) 从 URL 获取 HTML

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

public class JsoupExample {
    public static void main(String[] args) throws Exception {
        // 获取网页内容
        Document doc = Jsoup.connect("https://example.com").get();
        System.out.println(doc.title()); // 输出网页标题
    }
}

(2) 从字符串解析 HTML

java
String html = "<html><head><title>Test</title></head><body><p>Hello Jsoup</p></body></html>";
Document doc = Jsoup.parse(html);
System.out.println(doc.title()); // 输出 "Test"

(3) 从本地文件解析 HTML

java
File input = new File("example.html");
Document doc = Jsoup.parse(input, "UTF-8");
System.out.println(doc.title());

3. 数据提取(CSS 选择器)

(1) 提取单个元素

java
Document doc = Jsoup.connect("https://example.com").get();
Element title = doc.selectFirst("h1"); // 获取第一个 <h1> 标签
System.out.println(title.text());

(2) 提取多个元素

java
Elements links = doc.select("a[href]"); // 获取所有带 href 的 <a> 标签
for (Element link : links) {
    System.out.println(link.attr("href")); // 输出链接
    System.out.println(link.text()); // 输出链接文本
}

(3) 常用 CSS 选择器

选择器示例说明
tagdiv选择所有 <div>
.class.header选择 class="header" 的元素
#id#main选择 id="main" 的元素
[attr][href]选择带 href 属性的元素
parent > childdiv > p选择 <div> 下的直接 <p>
ancestor descendantdiv p选择 <div> 下的所有 <p>

4. 数据操作

(1) 获取属性

java
Element link = doc.selectFirst("a");
String href = link.attr("href"); // 获取 href 属性
String text = link.text(); // 获取文本内容
String html = link.html(); // 获取内部 HTML

(2) 修改 HTML

java
Element div = doc.selectFirst("div.content");
div.text("New Content"); // 修改文本
div.append("<p>New Paragraph</p>"); // 追加 HTML
div.attr("class", "updated"); // 修改 class

(3) 删除元素

java
Element footer = doc.selectFirst("footer");
footer.remove(); // 删除元素

5. 处理表单

(1) 提交 GET 请求

java
Document doc = Jsoup.connect("https://example.com/search")
    .data("q", "Java") // 参数
    .get();
System.out.println(doc.body());

(2) 提交 POST 请求

java
Document doc = Jsoup.connect("https://example.com/login")
    .data("username", "admin", "password", "123456")
    .post();
System.out.println(doc.title());

(3) 设置请求头

java
Document doc = Jsoup.connect("https://example.com")
    .header("User-Agent", "Mozilla/5.0")
    .header("Accept-Language", "en-US")
    .get();

6. 代理 & 超时设置

(1) 使用代理

java
Document doc = Jsoup.connect("https://example.com")
    .proxy("127.0.0.1", 8080) // 代理 IP 和端口
    .get();

(2) 设置超时

java
Document doc = Jsoup.connect("https://example.com")
    .timeout(5000) // 5秒超时
    .get();

7. 处理相对路径

java
Document doc = Jsoup.connect("https://example.com").get();
Element img = doc.selectFirst("img");
String absUrl = img.absUrl("src"); // 获取绝对 URL
System.out.println(absUrl);

8. 实战示例:爬取新闻标题

java
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class NewsCrawler {
    public static void main(String[] args) throws Exception {
        String url = "https://news.baidu.com";
        Document doc = Jsoup.connect(url).get();
        
        Elements news = doc.select(".hotnews a"); // 选择热门新闻
        for (Element item : news) {
            String title = item.text();
            String link = item.absUrl("href");
            System.out.println(title + " -> " + link);
        }
    }
}

9. 常见问题

(1) 403 Forbidden

原因:网站检测到爬虫。 • 解决方案

java
Document doc = Jsoup.connect(url)
    .userAgent("Mozilla/5.0") // 模拟浏览器
    .referrer("https://google.com") // 伪造来源
    .get();

(2) 中文乱码

解决方案

java
Document doc = Jsoup.parse(new URL(url).openStream(), "UTF-8", url);

(3) 动态加载内容

Jsoup 无法解析 JavaScript 动态生成的内容,需配合 SeleniumHtmlUnit


10. 总结

功能方法
获取 HTMLJsoup.connect(url).get()
解析 HTMLJsoup.parse(html)
提取元素doc.select("css")
获取属性element.attr("href")
获取文本element.text()
修改 HTMLelement.html("new")
提交表单.data("key", "value").post()
代理设置.proxy("ip", port)

🚀 适用场景: • 静态网页抓取(新闻、博客、论坛)。 • 数据清洗(提取特定内容)。 • 简单爬虫(无需 JavaScript 渲染)。

如果需要抓取动态内容(如 SPA 网站),建议结合 SeleniumPlaywright

✨ 网站运行时间: 3年11月15天 ❤️ 道阻且长,行则将至 - 微信号: heikedreamer