如何避免在 Jsoup 解析中环绕 html 头标签

Posted

技术标签:

【中文标题】如何避免在 Jsoup 解析中环绕 html 头标签【英文标题】:How to avoid surrounding html head tags in Jsoup parse 【发布时间】:2014-11-28 04:57:10 【问题描述】:

我尝试使用 Jsoup 解析给定的 html 内容。在 Jsoup.parse() 之后,html 输出将 html、head 和 body 标记附加到输入。我只想忽略这些。

示例输入:

<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>

Java 代码:

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class HTMLParse 

    public static void main(String args[]) throws IOException 
        try
            File input = new File("/ab.html");
            String html = FileUtils.readFileToString(input, null);

            Document doc = Jsoup.parseBodyFragment(html);
            doc.outputSettings().prettyPrint(false);
            System.out.println(doc.html());
        
        catch(Exception e)
            e.printStackTrace();
        
    

实际输出:

<html><head></head><body><p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>
    </body></html>

预期输出:

<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>

请帮忙。

【问题讨论】:

这应该对您有所帮助。 ***.com/questions/17492396/… @Jitendra 我想要这样的财产。 nekohtml.sourceforge.net/faq.html#fragments 【参考方案1】:

原因:

parseBodyFragment() 以及所有其他parse() 方法默认使用HTML 解析器。而那些总是添加 HTML-Shell(&lt;html&gt;…&lt;/html&gt;&lt;head&gt;…&lt;/head&gt; 等)。

解决方案:

不要使用 HTML 解析器,而是使用 XML 解析器 ;-)

Document doc = Jsoup.parse(html, "", Parser.xmlParser());

替换那一行,你的问题就解决了。

示例:

final String html = "<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>";

Document docHtml = Jsoup.parse(html);
Document docXml = Jsoup.parse(html, "", Parser.xmlParser());

System.out.println("******* HTML *******\n" + docHtml);
System.out.println();
System.out.println("*******  XML *******\n" + docXml);

输出:

******* HTML *******
<html>
 <head></head>
 <body>
  <p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>
 </body>
</html>

*******  XML *******
<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>

【讨论】:

一个潜在的缺点是你没有得到任何的 HTML 整理——XML 解析器不关心 HTML5 结构并让内容按原样通过。如果您想整理 HTML 正文,请使用 Jsoup.parseBodyFragment(html).body(); 这仅适用于您的 html 是 xml。不幸的是,如果你有诸如 img 标签之类的没有终止的东西,xml 解析器将假定以下标签在里面。【参考方案2】:

要获得预期的输出,它实际上是:

final String html = "<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>";
Document doc = Jsoup.parseBodyFragment(html);
doc.outputSettings().prettyPrint(false);

System.out.println(doc.body().html());

【讨论】:

【参考方案3】:

您可以尝试使用 XML 解析器,但这并不总是有效,因为 HTML 并不总是 XML;它通常具有未终止的标签,例如 &lt;img&gt;&lt;br&gt;。最好坚持使用 HTML 解析器。您可以依赖&lt;html&gt;&lt;head&gt;&lt;body&gt; 标签,它们很容易丢弃。只需通过选择 body 标记并请求其 HTML 来获取您的 HTML 片段。

Document doc = Jsoup.parseBodyFragment(html);
        doc.outputSettings().prettyPrint(false);
        System.out.println(doc.select("body").html());

【讨论】:

赞成 xml 解析器的警告。尽管我的 jsoup 用例是纠正图像,但我几乎做到了。还想在 body 元素上评论 .html() 只是内部 html。它不包括周围的body标签。【参考方案4】:

您也可以将 Jsoup.parse 与 HTML 解析器一起使用。您需要做的就是剥离 htmlbody 包装器。

这可以通过选择body 元素并展开它来完成:

String input = "<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>";
Node content = Jsoup.parse(input).body().unwrap();
System.out.println(content.html());

body() 选择 body 元素,unwrap() 删除正文,只保留内容。

所以输出是:

<p><b>This <i>is</i></b> <i>my sentence</i> of text.</p>

【讨论】:

以上是关于如何避免在 Jsoup 解析中环绕 html 头标签的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Jsoup 转义 html?

如何将用 Jsoup(Java html 解析器)制作的文档转换为字符串

Jsoup解析HTML

jsoup 解析HTML信息

(转载)Html解析工具Jsoup

jsoup教程