Как получить конкретный тег, где текст соответствует большинству слов в данном списке слов, используя JSOUP? - PullRequest
0 голосов
/ 05 мая 2019

Я пытаюсь получить весь тег, в котором максимальное количество слов совпадает в данном списке слов !. например: Рассмотрим 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>

Рассмотрим код Java, используя jsoup lib:

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

1 Ответ

0 голосов
/ 06 мая 2019

К сожалению, такого селектора нет.Вы можете создать небольшой алгоритм, который делает это вместо этого:

Используйте 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 и TreeMap для сопоставления количества слов с элементом.Если два или более элементов имеют одинаковое количество слов, последний использовавшийся.Если вы хотите использовать первое, что вы можете использовать (e0, e1) -> e0.

Для подсчета слов, приведенных в списке, вы также можете использовать потоки Java.Вы можете использовать метод, подобный этому:

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

Это разбивает текст на все несловарные символы.Вы можете изменить это в соответствии с вашими потребностями.

Результат elmnt.cssSelector() для предоставленного вами HTML-кода будет #productTitle.

...