Получить все img src с помощью Jsoup

#java #jsoup

#java #jsoup

Вопрос:

У меня есть HTML-код со следующими img src частями:

 <img src="https://lh3.googleusercontent.com/...rw" srcset="https://lh3.googleusercontent.com/...rw 2x" class="T75of DYfLw" width="551" height="310" alt="Screenshot Image"">
  
 <img data-src="https://lh3.googleusercontent.com/...w720-h310-rw" ... data-srcset="https://lh3.googleusercontent.com/... w1440-h620-rw 2x" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="width="551" height="310" alt="Screenshot Image">
  

Я хочу получить все скриншоты с атрибутом alt=Screenshot Image . Итак, мне нужно значение внутри атрибута srcset и data-srcset (2 разных имени атрибута = 2 разных случая).

Я написал этот код:

 List<String> src = htmlDocument.select("img[src]").stream()
                .filter(img -> img.attr("alt").equals("Screenshot Image"))
                .map(element -> element.absUrl("data-srcset").replace("2x", ""))
                //or for 1st case
                .map(element -> element.absUrl("srcset")..
                //
                .collect(Collectors.toList());
  

Но теперь я не могу получить это значение из первого случая, где этот атрибут является srcset , а не data-srcset . Могу ли я получить src для обоих сценариев без дополнительной итерации — например, не создавать другой поток, а затем объединить все результаты в одну коллекцию? Может быть, какое-нибудь регулярное выражение и другой метод (похоже, .absUrl не работает с регулярными выражениями) в библиотеке Jsoup могут помочь?

И мне не нравится часть с replace (возможно, какой-то src будет содержать 2x как собственную часть).

 .map(element -> element.absUrl("data-srcset").replace("2x", ""))
  

Но без этой манипуляции я получу некорректный src.

 https://lh3.googleusercontent.com/Z...=w1440-h620-rw 2x
  

Могу ли я улучшить это replace решение с помощью чего-либо еще?

Ответ №1:

Вы могли бы попробовать создать коллекцию коллекций, а затем flatMap

 List<String> src = htmlDocument.select("img[src]").stream()
            .filter(img -> img.attr("alt").equals("Screenshot Image"))
            .map(element -> {
                List<String> url = new ArrayList<>();
                url.add( element.absUrl("data-srcset").replace("2x", ""));
                url.add( element.absUrl("srcset"));
                return url;
            })
            .flatMap(List::stream)
            .collect(Collectors.toList());
  

Для вашего последнего ответа, предполагая, что ваши URL-адреса не содержат пробелов, вы могли бы использовать

 StringUtils.substringBefore(element.absUrl("data-srcset")," ")
  

Редактировать

Я предположил, что у вас могут быть как srcset, так и data-srcset в одном изображении. Повторное чтение приводит к лучшему подходу

     List<String> src = htmlDocument.select("img[src]").stream()
                .filter(img -> img.attr("alt").equals("Screenshot Image"))
                .map(element -> StringUtils.isNotEmpty(element.absUrl("srcset")) ? 
                   element.absUrl("srcset") : 
                   element.absUrl("data-srcset").replace("2x", ""))
                .collect(Collectors.toList());