首页 > 解决方案 > 如何使用 JSOUP 获取文本与给定单词列表中的大多数单词匹配的特定标签?

问题描述

我正在尝试获取在给定单词列表中具有最大匹配单词数的整个标签!即例如:考虑 html :

<div id="productTitle" class="a-size-large">Hello world, good morning, have a happy day</div> <div id="productTitle2" class="a-size-large">Hello people of this planet!.</div>

考虑使用 jsoup lib 的 java 代码:

String html = "<div id="productTitle" class="a-size-large">Hello world, good morning, have a happy day</div> <div id="productTitle2" class="a-size-large">Hello people of this planet!.</div>";
Document doc = Jsoup.parse(html);    
List<String> words = new ArrayList<>(Arrays.asList("hello", "world", "morning"));
Element elmnt = doc.select("*:matchesOwn("+words+")");
System.out.println(elmnt.cssSelector());

预期输出: #productTitle

标签: javajsoup

解决方案


不幸的是,没有这样的选择器。您可以创建一个小算法来代替:

用于Document.getAllElements()获取文档中所有元素的列表。要获取元素的实际文本,请使用Element.ownText(). 现在您可以将该文本拆分为单词并计算所有单词:

String html = "<div id=\"productTitle\" class=\"a-size-large\">Hello world, good morning, have a happy day</div> <div id=\"productTitle2\" class=\"a-size-large\">Hello people of this planet!.</div>";
Document doc = Jsoup.parse(html);
List<String> words = Arrays.asList("hello", "world", "morning");

Element elmnt = doc.getAllElements().stream()
        .collect(Collectors.toMap(e -> countWords(words, e.ownText()), Function.identity(), (e0, e1) -> e1, TreeMap::new))
        .lastEntry().getValue();

这使用 Java Streams 和 aTreeMap将单词数映射到元素。如果两个或多个元素具有相同数量的单词,则最后一个使用。我你喜欢用第一个你可以用(e0, e1) -> e0

要计算列表中给出的单词,您还可以使用 Java Streams。您可以使用这样的方法:

private long countWords(List<String> words, String text) {
    return Arrays.stream(text.split("[^\\w]+"))
            .map(String::toLowerCase)
            .filter(words::contains)
            .count();
}

这会拆分所有非单词字符的文本。您可以更改它以满足您的需求。

您共享的 HTML 代码的结果elmnt.cssSelector()将是#productTitle.


推荐阅读