Как избежать использования тегов заголовка HTML в Jsoup?

Используя 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>

Пожалуйста помоги.

3 ответа

Решение

Причина:

parseBodyFragment() как и все остальные parse() -методы используют парсер HTML по умолчанию. А те добавляют всегда HTML-оболочку (<html>…</html>, <head>…</head> так далее.).

Решение:

Только не используйте 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>

Чтобы получить ожидаемый результат, он будет:

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());

Вы можете попробовать использовать синтаксический анализатор XML, но это не всегда работает, потому что HTML не всегда XML; он часто имеет неопределенные теги, такие как <img> а также <br>, Лучше придерживаться парсера HTML. Вы можете положиться на <html>, <head>, а также <body> теги и их легко выбросить. Просто получите свой фрагмент HTML, выбрав тег body и запросите его HTML.

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

Вы можете использовать Jsoup.parse также с парсером HTML. Все, что вам нужно сделать, это снять html и body обертки прочь.

Это можно сделать, выбрав 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>
Другие вопросы по тегам