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