【问题标题】:How to avoid surrounding html head tags in Jsoup parse如何避免在 Jsoup 解析中环绕 html 头标签
【发布时间】: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>

请帮忙。

【问题讨论】:

标签: java html parsing jsoup


【解决方案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>
    

    【讨论】:

      猜你喜欢
      • 2012-04-02
      • 1970-01-01
      • 2012-10-01
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 2014-04-25
      • 1970-01-01
      相关资源
      最近更新 更多