当前位置: 首页 > 面试题库 >

Jsoup-仅保留标签并删除所有文本

夹谷信鸿
2023-03-14
问题内容

我正在尝试使用Jsoup删除HTML页面的标签之间的所有文本

例如,如果输入的HTML是

<!DOCTYPE html>
<html>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
</body>
</html>

输出应为

<!DOCTYPE html>
<html>
<body>
<h1></h1>
<p></p>
</body>
</html>

基本上,我想删除由返回的内容 doc.text()

我发现有很多帖子是相反的,只保留文本,而没有什么可以解决我的问题。有关如何执行此操作的任何想法?

编辑

maverick9999提出的解决方案将解决大多数情况。

但是,正如注释中所注意到的,此解决方案还将删除嵌套标签。

举个例子:

    String str = "<!DOCTYPE html>" +
                "<html>" +
                "<body>" +
                "<div class='foo'>text <div class='THIS DIV WILL BE REMOVED'>text</div> text </div>" +
                "<h1>My First Heading</h1>\n" +
                "<p>My first paragraph.</p>\n" +
                "</body>\n" +
                "</html>";

        Document doc=Jsoup.parse(str);
        removeAllTexts(doc);
        System.out.println(doc);

        Elements all=doc.select("*");
        Iterator<Element>iterator=all.iterator();
        while(iterator.hasNext()){
            Element e=iterator.next();
            if(!e.ownText().isEmpty()){
                e.text("");
            }
        }

        System.out.println(doc);

将在输出中删除一个div:

    <html>
     <head></head>
     <body>
      <div class="foo">
      </div>
     </body>
    </html>

有什么想法可以避免这种情况?

编辑2

由于某种原因,标签“ meta”被Jsoup视为自动关闭。因此,如果您有这样的事情:

System.out.println("\n\n----");
String html = "<!DOCTYPE html>\r\n"
+ "<html>\r\n"
+ "<head>\n" 
+ "<meta content=\"/myimage.png\" itemprop=\"image\">\n"
+ "<title>Title</title>\n" 
+ "<script>Random Javascript here</script>"
+ "</meta>"
+ "</head>"
+ "<body>\r\n"
+ "<h1>My First <i>Heading</i></h1>\r\n"
+ "<hr/>\r\n"
+ "<p>My first paragraph.</p>\r\n"
+ "<p> <div class='foo'>text <div class='bar'> text </div> text </div> </p>\r\n"
+ "</body>\r\n" 
+ "</html>";

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

这样,之后的所有标签meta将无法读取。使用Pshemo解决方案,脚本将被删除,如果您有br带有子标签的标签(例如),它们也将被删除。我最终得到了以下解决方案(感谢Pshemo的帮助):

   public static void printNodes(Node node) {
        String name = node.nodeName();
        if (name.equals("#doctype")) {
            System.out.println(node);
        } else if (name.equals("#text")) {
            return;
        } else if (name.equals("#document")) {
            for (Node n : node.childNodes())
                printNodes(n);
        } 
        // There is no reason to have text here, so print everything
        else if (name.equals("head") || name.equals("script")){
            System.out.println(node.toString());
        }
        else {
            if (!Tag.valueOf(name).isSelfClosing() || node.childNodeSize()>0) {
                System.out.println("<" + name + getAttributes(node) + ">");
                for (Node n : node.childNodes())
                    printNodes(n);
                System.out.println("</" + name + ">");
            } else {
                // System.out.println("debug: " + name + " is self closing");
                System.out.println("<" + name + getAttributes(node) + "/>");
            }
        }
    }

   public static String getAttributes(Node node) {
        StringBuilder sb = new StringBuilder();
        for (Attribute attr : node.attributes()) {
            sb.append(" ").append(attr.getKey()).append("=\"")
                    .append(attr.getValue()).append("\"");
        }
        return sb.toString();
    }

问题答案:

以下代码应使用嵌套标签解决您的问题:

更新的代码:

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

for (Element el : doc.select("*")){
    if (!el.ownText().isEmpty()){
        for (TextNode node : el.textNodes())
            node.remove();
    }
}

System.out.println(doc);


 类似资料:
  • 我正在尝试使用 Jsoup 删除 HTML 页面标记之间的所有文本 例如,如果输入HTML是 输出应该是 基本上,我想删除返回的内容。 我找到了很多相反的帖子,只保留文本,但没有解决我的问题。知道怎么做吗? 编辑 maverick9999:https://stackoverflow.com/a/24292349/3589481提出的解决方案将解决大部分情况。 然而,正如评论中提到的,这个解决方案也

  • 问题内容: 假设我有一个这样的html片段: 我想从中提取的是: 所以我的问题是:如何从html中剥离所有包装标签,并仅以与html中相同的顺序获取文本?正如您在标题中看到的那样,我想使用jsoup进行解析。 重音html的示例(注意’á’字符): 我想要的是: 这个html并不是静态的,通常我只希望通用html片段的每个文本都以已解码的人类可读形式显示,宽度换行。 问题答案: 使用Jsoup:

  • 假设我有一个像这样的html片段: 我想从中得到的是: 所以我的问题是:如何从html中去掉所有包装标签,只得到与html中相同顺序的文本?正如您在标题中看到的,我想使用jsoup进行解析。 重音html示例(请注意“á”字符): 我想要的是: 这个html不是静态的,一般来说,我只是想解码人类可读形式的通用html片段的每一个文本,宽度线中断。

  • 这似乎是一个简单的解决方案,但我一辈子都无法解决。 我有一个由< code >混合组成的元素集合 我想做的就是保留所有东西(包括标签和它的字符串),这是一个干净的

  • 我想清除所有筛选规则,但保留筛选本身。 有没有直接快速的方法去做呢? 我找到的代码是: 它获取筛选器对象,我对筛选器#的选项数量是有限的。 注意:删除此筛选器,但我需要保留它。

  • 问题内容: 问题是这样的:我有一个像这样的XML片段: 为了得到结果,我想删除所有-和-Tags,但保留它们的(文本)内容和子节点不变。另外,-Element应该保持不变。结果应该这样 目前,我将回到一个非常肮脏的把戏:我将etree.tostring这个片段,通过正则表达式删除有问题的标签,并用etree.fromstring结果替换原始片段(不是真正的代码,但是应该这样): 我知道我可能可以使