使用Java删除HTML标签

评论 0 浏览 0 2021-11-12

1.概述

有时,我们想删除所有的HTML标签,并从一个HTML文档的字符串中提取文本。

这个问题看起来很简单。然而,根据不同的要求,它可以有不同的变体。

在本教程中,我们将讨论如何使用Java来实现这一目标。

2.使用Regex

由于我们已经把HTML作为一个String变量,我们需要做一种文本处理。

当遇到文本处理问题时,正则表达式(Regex)可能是第一个出现的想法。

从一个字符串中删除HTML标签对Regex来说不是一个挑战,因为不管是开始还是结束的HTML元素,它们都是按照模式“<…>”进行的。

如果我们把它翻译成Regex,就是“<[^>]*>”或者“<.*?>”

我们应该注意,Regex默认进行贪婪匹配。也就是说,Regex “<.*>”对我们的问题不起作用,因为我们想从‘<‘直到下一个‘>‘而不是一行中的最后一个‘>‘。

现在,让我们来测试一下它是否能从HTML源中删除标签。

2.1.从example1.html删除标签

在我们测试删除HTML标签之前,首先让我们创建一个HTML的例子,比如说example1.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>This is the page title</title>
</head>
<body>
    <p>
        If the application X doesn't start, the possible causes could be:<br/>
        1. <a href="maven.com">Maven</a> is not installed.<br/>
        2. Not enough disk space.<br/>
        3. Not enough memory.
    </p>
</body>
</html>

现在,让我们写一个测试,并使用String.replaceAll()来删除HTML标签。

String html = ... // load example1.html
String result = html.replaceAll("<[^>]*>", "");
System.out.println(result);

如果我们运行测试方法,我们就会看到结果。



    This is the page title


    
        If the application X doesn't start, the possible causes could be:
        1. Maven is not installed.
        2. Not enough disk space.
        3. Not enough memory.


输出看起来很不错。这是因为所有的HTML标签都已被删除。

它保留了剥离的HTML中的空白处。但我们在处理提取的文本时,可以很容易地删除或跳过这些空行或空白处。到目前为止,一切都很好。

2.2.从example2.html删除标签

正如我们刚才所看到的,使用Regex来删除HTML标签是非常直接的。然而,这种方法可能有问题,因为我们无法预测会得到什么HTML源

例如,一个HTML文档可能有<script><style>标签,而我们可能不想在结果中出现它们的内容。

此外,<script><style>,甚至<body>标签中的文本可能包含“<”或“>”字符。如果是这种情况,我们的Regex方法可能会失败。

现在,让我们来看看另一个HTML例子,比如说example2.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>This is the page title</title>
</head>
<script>
    // some interesting script functions
</script>
<body>
    <p>
        If the application X doesn't start, the possible causes could be:<br/>
        1. <a
            id="link"
            href="http://maven.apache.org/">
            Maven
            </a> is not installed.<br/>
        2. Not enough (<1G) disk space.<br/>
        3. Not enough (<64MB) memory.<br/>
    </p>
</body>
</html>

这一次,我们有一个<script>标签和<body>标签中的“<”字符。

如果我们在example2.html上使用同样的方法,我们会得到(空行已被删除)。

   This is the page title
    // some interesting script functions    
        If the application X doesn't start, the possible causes could be:
        1. 
            Maven
             is not installed.
        2. Not enough (
        3. Not enough (

显然,由于“<”字符,我们失去了一些文本。

因此,使用Regex来处理XML或HTML是脆弱的。相反,我们可以选择一个HTML分析器来完成这项工作。

接下来,我们将讨论几个易于使用的HTML库,以提取文本。

3.使用Jsoup

Jsoup是一个流行的HTML解析器。要从一个HTML文档中提取文本,我们可以简单地调用Jsoup.parse(htmlString).text()

首先,我们需要将Jsoup库添加到classpath。例如,假设我们使用Maven来管理项目的依赖关系。

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.14.3</version>
</dependency>

现在,让我们用我们的example2.html来测试它。

String html = ... // load example2.html
System.out.println(Jsoup.parse(html).text());

如果我们让这个方法运行一下,它就会打印出来。

This is the page title If the application X doesn't start, the possible causes could be: 1. Maven is not installed. 2. Not enough (<1G) disk space. 3. Not enough (<64MB) memory.

如输出结果所示,Jsoup已经成功地从HTML文档中提取了文本。另外,<script>元素中的文本也被忽略了。

此外,默认情况下,Jsoup将删除所有的文本格式和空白,如换行符

但是,如果需要的话,我们也可以要求Jsoup保留换行符

4.使用HTMLCleaner

HTMLCleaner是另一个HTML解析器。它的目标是使来自 Web 的“格式错误和肮脏”的 HTML 适合进一步处理。

首先,让我们在我们的pom.xml中添加HTMLCleaner的依赖关系

<dependency>
    <groupId>net.sourceforge.htmlcleaner</groupId>
    <artifactId>htmlcleaner</artifactId>
    <version>2.25</version>
</dependency>

我们可以设置各种选项,以控制HTMLCleaner的解析行为。

在这里,作为一个例子,让我们告诉HTMLCleaner在解析example2.html时,跳过<script>元素。

String html = ... // load example2.html
CleanerProperties props = new CleanerProperties();
props.setPruneTags("script");
String result = new HtmlCleaner(props).clean(html).getText().toString();
System.out.println(result);

如果我们运行测试,HTMLCleaner就会产生这样的输出。

    This is the page title


    
        If the application X doesn't start, the possible causes could be:
        1. 
            Maven
             is not installed.
        2. Not enough (<1G) disk space.
        3. Not enough (<64MB) memory.

正如我们所看到的,<script>元素中的内容被忽略了。

此外,它将<br/>标签转换为提取的文本中的换行符。如果格式很重要,这可能很有帮助。

另一方面,HTMLCleaner保留了剥离后的HTML源的空白处。因此,例如,文本“1. Maven is not installed”被分成了三行。

5.使用Jericho

最后,我们将看到另一个HTML解析器 – Jericho。它有一个很好的功能:用简单的文本格式化来渲染HTML标记。我们稍后将看到它的运行。

像往常一样,让我们首先在pom.xml中添加Jericho的依赖

<dependency>
    <groupId>net.htmlparser.jericho</groupId>
    <artifactId>jericho-html</artifactId>
    <version>3.4</version>
</dependency>

在我们的example2.html中,我们有一个超链接“Maven (http://maven.apache.org/)“。现在,假设我们想在结果中同时出现链接的URL和链接文本。

要做到这一点,我们可以创建一个Renderer对象,并使用includeHyperlinkURLs选项。

String html = ... // load example2.html
Source htmlSource = new Source(html);
Segment segment = new Segment(htmlSource, 0, htmlSource.length());
Renderer htmlRender = new Renderer(segment).setIncludeHyperlinkURLs(true);
System.out.println(htmlRender);

接下来,让我们执行测试并检查输出结果。

If the application X doesn't start, the possible causes could be:
1. Maven <http://maven.apache.org/> is not installed.
2. Not enough (<1G) disk space.
3. Not enough (<64MB) memory.

正如我们在上面的结果中看到的,文本已经被漂亮的格式化了。另外,<title>元素中的文本被默认忽略了。

链接的URL也被包括在内。除了渲染链接(<a>),Jericho支持渲染其他HTML标签,例如<hr/>,<br/>,项目符号列表(<ul><li>)等

6.结论

在这篇文章中,我们已经解决了去除HTML标签和提取HTML文本的不同方法。

我们应该注意,使用Regex来处理XML/HTML并不是一个好的做法

一如既往,本文的完整源代码可以在GitHub上找到。

最后更新2023-02-19
0 个评论