Java 提取 HTML 文本内容:两种轻量级实现方案对比

在日常的 Java 开发中,我们经常会遇到处理 HTML 内容的场景。无论是做简单的网页数据抓取、处理富文本编辑器提交的内容,还是对文档进行全文索引,从 HTML 中剥离标签、提取纯文本都是一个绕不开的基础需求。

HTML 作为一种标记语言,包含了大量用于控制样式的标签(如 <div><span><p>)以及脚本代码。如果我们直接使用正则表达式去处理这些嵌套复杂的标签,不仅代码容易出错,而且维护成本较高。

本文将介绍两种处理思路:一种是利用第三方文档处理库(以 Spire.Doc for Java 为例)将 HTML 作为文档解析;另一种是主流的轻量级 HTML 解析器方案。通过对比,帮助开发者根据自身场景做出合理的技术选型。

环境准备

  • JDK 1.8 及以上版本
  • Maven 项目管理工具

1. 为什么不能直接用正则表达式?

在处理 HTML 转文本时,正则表达式是最直观的想法,但它存在明显的局限性:

  • 无法处理嵌套标签 :例如 <div>a<p>b</p>c</div>,正则很难正确匹配层级关系。
  • 容易误匹配:标签内的属性、注释、CDATA 等特殊结构容易干扰匹配结果。
  • 维护困难:面对不同来源的 HTML(如缺失闭合标签、大小写不一致),正则规则会变得臃肿且脆弱。

因此,推荐使用成熟的解析方案。

2. 方案一:文档转换器方式

该方案借助第三方文档处理库,将 HTML 映射为文档对象模型,然后调用获取文本的方法。

2.1 项目依赖配置

pom.xml 中添加如下依赖:

xml 复制代码
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.doc</artifactId>
        <version>14.3.1</version>
    </dependency>
</dependencies>

:该库提供免费版和商业版。对于基础的文本提取需求,免费版通常足够。

2.2 核心实现

java 复制代码
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import java.io.FileWriter;
import java.io.IOException;

public class HtmlTextExtractor {

    public static void main(String[] args) {
        // 1. 实例化 Document 对象
        Document document = new Document();

        // 2. 加载 HTML 文件(指定格式为 Html)
        document.loadFromFile("input.html", FileFormat.Html);

        // 3. 提取纯文本内容
        String extractedText = document.getText();

        // 4. 输出或保存结果
        System.out.println("提取的文本内容:\n" + extractedText);

        // 可选:保存到 txt 文件
        try (FileWriter writer = new FileWriter("output.txt")) {
            writer.write(extractedText);
            System.out.println("\n文本已成功保存到 output.txt");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代码解析

  • Document 类通常用于处理 Word 文档,但它同样支持 FileFormat.Html 格式。加载时,库内部会解析 HTML 标签,将其映射为段落、表格等文档元素。
  • getText() 方法遍历文档树,提取所有可见文本,同时跳过控制字符和标签代码。

2.3 处理 URL 网页

如果需要直接抓取线上的网页内容,可以结合 Java 原生的 HttpClient 获取网页源代码后再解析:

java 复制代码
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;

public class UrlTextExtractor {

    public static void main(String[] args) {
        String urlStr = "https://example.com";
        
        try {
            String htmlPath = fetchHtmlFromUrl(urlStr, "temp.html");
            Document doc = new Document();
            doc.loadFromFile(htmlPath, FileFormat.Html);
            String text = doc.getText();
            System.out.println(text);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String fetchHtmlFromUrl(String urlString, String savePath) throws Exception {
        URL url = new URL(urlString);
        URLConnection conn = url.openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestProperty("User-Agent", "Mozilla/5.0");
        
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
             FileWriter writer = new FileWriter(savePath)) {
            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(line);
                writer.write("\n");
            }
        }
        return savePath;
    }
}

注意 :解析 URL 时需遵守目标网站的 robots.txt 协议及数据获取的合规性要求。

3. 方案二:轻量级 HTML 解析器方式(以 Jsoup 为例)

相比文档转换方式,Jsoup 是专门为 HTML 解析设计的轻量级库,在社区中使用更为广泛。

3.1 依赖配置

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

3.2 核心实现

java 复制代码
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.File;

public class JsoupExtractor {

    public static void main(String[] args) throws Exception {
        // 加载 HTML 文件
        Document doc = Jsoup.parse(new File("input.html"), "UTF-8");
        
        // 提取纯文本(自动去除标签)
        String text = doc.text();
        
        System.out.println(text);
    }
}

Jsoup 的 text() 方法会递归获取所有可见文本,并用空格连接块级元素的内容,输出结果更适合阅读。

3.3 直接解析 URL

Jsoup 内置了网络请求能力,代码更为简洁:

java 复制代码
Document doc = Jsoup.connect("https://example.com")
    .userAgent("Mozilla/5.0")
    .timeout(5000)
    .get();
String text = doc.text();

4. 方案对比与适用场景

维度 文档转换方式(Spire.Doc) 轻量级解析器(Jsoup)
设计定位 文档处理(Word、HTML 等) HTML 解析专用
API 复杂度 较高(需了解 Document 模型) 简单直观
HTML 容错能力 较强 很强(业界公认)
网络请求 需自行实现 内置支持
依赖体积 较大(包含文档处理能力) 小巧(约 500KB)
扩展性 可转为 Word 等其他格式 聚焦 HTML/CSS 选择器

各自的适用场景

  • 文档转换方式:适合需要同时处理 Word 文档和 HTML 文件的场景,或希望统一文档处理逻辑的项目。
  • 轻量级解析器:适合纯 HTML 提取、网页抓取、需要按 CSS 选择器提取特定元素内容的场景。

5. 两种方案的共同局限性

无论选择哪种方案,在提取纯文本时都需要注意以下几点:

  1. 格式信息丢失:提取结果仅包含文本,原 HTML 中的表格布局、字体大小、颜色、图片链接等富媒体信息均会丢失。
  2. 编码处理 :如果 HTML 未正确声明 charset,可能需要手动指定编码,否则可能出现中文乱码。
  3. 大文件性能:对于数十 MB 的超大 HTML 文件,两种方案的内存占用都会显著上升,建议分块或流式处理。

6. 总结

从 HTML 中提取纯文本是 Java 开发中的常见需求。本文对比了两种可行的技术方案:

文档转换方式以 Spire.Doc for Java 为例,其特点是将 HTML 视为文档对象进行解析,API 封装程度较高,但依赖体积偏大,适合需要统一处理 Word 和 HTML 格式的项目。

轻量级解析器以 Jsoup 为例,它是专门为 HTML 设计的工具,API 简洁、HTML 容错能力强,并且内置了网络请求支持,在社区中使用广泛,是纯文本提取场景下的主流选择。

开发者可以根据项目现有依赖、体积敏感度以及是否需要额外的 HTML 操作(如选择器提取、DOM 修改)来选择合适的方案。如果项目仅需简单的去标签处理,Jsoup 可能是更轻量的选择;如果项目中已经引入了文档处理相关依赖,则可以直接复用文档转换方式。

相关推荐
程序边界1 小时前
行标识符的秘密:OID和ROWID的技术演进之路
后端
lihao lihao1 小时前
Linux文件与fd
java·linux·算法
golang学习记1 小时前
Go 结构化日志新宠:`slog` 入门与实战指南(附避坑秘籍)
后端
Java爱好狂.2 小时前
Redis高级笔记:原理+集群+应用+拓展+源码
java·数据库·redis·spring·java面试·后端开发·java八股文
lee_curry2 小时前
jvm中的内存模型
java·jvm·内存模型
tltwuyulw2 小时前
Java的函数式编程(三)
java·后端
ch.ju2 小时前
Java程序设计(第3版)第二章——嵌套循环
java
直奔標竿2 小时前
Java开发者AI转型第九课!突破知识边界!企业级 RAG (检索增强生成) 核心架构与 ETL 管道初探
java·开发语言·人工智能·后端·spring
skilllite作者2 小时前
SkillLite Rust 沙箱与 AI Agent 自进化实战指南
开发语言·人工智能·后端·架构·rust