«1. Обзор
Jsoup — это библиотека Java с открытым исходным кодом, используемая в основном для извлечения данных из HTML. Он также позволяет вам манипулировать и выводить HTML. Он имеет постоянную линию разработки, отличную документацию и удобный и гибкий API. Jsoup также можно использовать для анализа и построения XML.
В этом руководстве мы будем использовать блог Spring, чтобы проиллюстрировать упражнение по очистке, демонстрирующее несколько функций jsoup:
-
Загрузка: выборка и анализ HTML в документе Фильтрация: выбор нужных данных в элементах и их обход Извлечение: получение атрибутов, текста и HTML узлов Модификация: добавление/редактирование/удаление узлов и редактирование их атрибутов
2. Зависимость Maven
Чтобы использовать библиотеку jsoup в своем проекте, добавьте зависимость в свой pom .xml:
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.2</version>
</dependency>
Последнюю версию jsoup можно найти в репозитории Maven Central.
3. Обзор Jsoup
Jsoup загружает HTML-код страницы и строит соответствующее DOM-дерево. Это дерево работает так же, как DOM в браузере, предлагая методы, аналогичные jQuery и ванильному JavaScript, для выбора, перемещения, управления текстом/HTML/атрибутами и добавления/удаления элементов.
Если вы знакомы с селекторами на стороне клиента и перемещением/манипулированием DOM, вы найдете jsoup очень знакомым. Проверьте, насколько просто распечатать абзацы страницы:
Document doc = Jsoup.connect("http://example.com").get();
doc.select("p").forEach(System.out::println);
Имейте в виду, что jsoup интерпретирует только HTML — он не интерпретирует JavaScript. Поэтому изменения в DOM, которые обычно происходят после загрузки страницы в браузере с поддержкой JavaScript, не будут видны в jsoup.
4. Загрузка
Этап загрузки включает выборку и преобразование HTML в документ. Jsoup гарантирует синтаксический анализ любого HTML, от самого недействительного до полностью проверенного, как это сделал бы современный браузер. Этого можно добиться, загрузив строку, поток ввода, файл или URL-адрес.
Давайте загрузим документ из URL-адреса блога Spring:
String blogUrl = "https://spring.io/blog";
Document doc = Jsoup.connect(blogUrl).get();
Обратите внимание на метод get, он представляет собой вызов HTTP GET. Вы также можете выполнить HTTP POST с методом post (или вы можете использовать метод, который получает тип метода HTTP в качестве параметра).
Если вам нужно обнаружить аномальные коды состояния (например, 404), вы должны поймать исключение HttpStatusException:
try {
Document doc404 = Jsoup.connect("https://spring.io/will-not-be-found").get();
} catch (HttpStatusException ex) {
//...
}
Иногда соединение нужно настроить немного по-другому. Jsoup.connect(…) возвращает соединение, которое позволяет вам установить, среди прочего, пользовательский агент, реферер, время ожидания соединения, файлы cookie, данные публикации и заголовки:
Connection connection = Jsoup.connect(blogUrl);
connection.userAgent("Mozilla");
connection.timeout(5000);
connection.cookie("cookiename", "val234");
connection.cookie("cookiename", "val234");
connection.referrer("http://google.com");
connection.header("headersecurity", "xyz123");
Document docCustomConn = connection.get();
Поскольку соединение следует свободному интерфейс, вы можете связать эти методы перед вызовом нужного метода HTTP:
Document docCustomConn = Jsoup.connect(blogUrl)
.userAgent("Mozilla")
.timeout(5000)
.cookie("cookiename", "val234")
.cookie("anothercookie", "ilovejsoup")
.referrer("http://google.com")
.header("headersecurity", "xyz123")
.get();
Вы можете узнать больше о настройках соединения, просмотрев соответствующий документ Javadoc.
5. Фильтрация
Теперь, когда мы преобразовали HTML в документ, пришло время перемещаться по нему и находить то, что мы ищем. Здесь сходство с jQuery/JavaScript более очевидно, так как его селекторы и методы обхода аналогичны.
5.1. Выбор
Метод выбора документа получает строку, представляющую селектор, используя тот же синтаксис селектора, что и в CSS или JavaScript, и извлекает соответствующий список элементов. Этот список может быть пустым, но не нулевым.
Давайте посмотрим на некоторые выборки, используя метод select:
Elements links = doc.select("a");
Elements sections = doc.select("section");
Elements logo = doc.select(".spring-logo--container");
Elements pagination = doc.select("#pagination_control");
Elements divsDescendant = doc.select("header div");
Elements divsDirect = doc.select("header > div");
Вы также можете использовать более явные методы, основанные на DOM браузера, вместо общего выбора:
Element pag = doc.getElementById("pagination_control");
Elements desktopOnly = doc.getElementsByClass("desktopOnly");
Поскольку Element является суперклассом документа, вы можете узнать больше о работе с методами выбора в документах Javadoc и Element.
5.2. Обход
Обход означает навигацию по дереву DOM. Jsoup предоставляет методы, которые работают с документом, набором элементов или конкретным элементом, позволяя вам переходить к родительским, одноуровневым или дочерним элементам узла.
Кроме того, вы можете перейти к первому, последнему и n-му (используя индекс, начинающийся с 0) Элементу в наборе Элементов:
Element firstSection = sections.first();
Element lastSection = sections.last();
Element secondSection = sections.get(2);
Elements allParents = firstSection.parents();
Element parent = firstSection.parent();
Elements children = firstSection.children();
Elements siblings = firstSection.siblingElements();
Вы также можете перебирать выборки. На самом деле, все элементы типа Elements могут быть итерированы:
sections.forEach(el -> System.out.println("section: " + el));
«
Elements sectionParagraphs = firstSection.select(".paragraph");
«Вы можете сделать выбор, ограниченный предыдущим выбором (подвыбор):
6. Извлечение
Теперь мы знаем, как получить доступ к определенным элементам, поэтому пришло время получить их содержимое, а именно их атрибуты. , HTML или дочерний текст.
Element firstArticle = doc.select("article").first();
Element timeElement = firstArticle.select("time").first();
String dateTimeOfFirstArticle = timeElement.attr("datetime");
Element sectionDiv = firstArticle.select("section div").first();
String sectionDivText = sectionDiv.text();
String articleHtml = firstArticle.html();
String outerHtml = firstArticle.outerHtml();
Взгляните на этот пример, который выбирает первую статью из блога и получает ее дату, текст первого раздела и, наконец, ее внутренний и внешний HTML:
-
Вот несколько советов, которые следует иметь в виду. при выборе и использовании селекторов:
полагайтесь на функцию «Просмотр исходного кода» вашего браузера, а не только на DOM страницы, поскольку она могла измениться (выбор в консоли браузера может дать результаты, отличные от jsoup). Знайте свои селекторы, поскольку они их много, и всегда хорошо хотя бы увидеть их раньше; освоение селекторов требует времени Используйте игровую площадку для селекторов, чтобы экспериментировать с ними (вставьте туда образец HTML) Будьте менее зависимы от изменений страницы: стремитесь к самым маленьким и наименее компрометирующим селекторам (например, предпочитайте селекторы на основе идентификатора)
7. Модификация ~~ ~ Модификация включает в себя настройку атрибутов, текста и HTML элементов, а также добавление и удаление элементов. Это делается для дерева DOM, ранее сгенерированного jsoup — Document.
7.1. Установка атрибутов и внутреннего текста/HTML
Как и в jQuery, методы для установки атрибутов, текста и HTML имеют одинаковые имена, но также получают устанавливаемое значение:
-
attr() — устанавливает значения атрибута (он создает атрибут, если он не существует) text() — устанавливает внутренний текст элемента, заменяя содержимое html() — устанавливает внутренний HTML элемента, заменяя содержимое
Давайте рассмотрим краткий пример этих методов:
timeElement.attr("datetime", "2016-12-16 15:19:54.3");
sectionDiv.text("foo bar");
firstArticle.select("h2").html("<div><span></span></div>");
7.2. Создание и добавление элементов
Чтобы добавить новый элемент, вам нужно сначала создать его, создав экземпляр Element. После создания элемента вы можете добавить его к другому элементу с помощью метода appendChild. Вновь созданный и добавленный элемент будет вставлен в конец элемента, где вызывается appendChild:
Element link = new Element(Tag.valueOf("a"), "")
.text("Checkout this amazing website!")
.attr("href", "http://baeldung.com")
.attr("target", "_blank");
firstArticle.appendChild(link);
7.3. Удаление элементов
Чтобы удалить элементы, вам нужно сначала выбрать их и запустить метод удаления.
Например, давайте удалим из документа все теги \u003cli\u003e, содержащие класс «navbar-link», и все изображения из первой статьи:
doc.select("li.navbar-link").remove();
firstArticle.select("img").remove();
7.4. Преобразование измененного документа в HTML
Наконец, поскольку мы изменяли документ, мы могли бы захотеть проверить нашу работу.
Для этого мы можем исследовать DOM-дерево документа, выбирая, перемещаясь и извлекая его с помощью представленных методов, или мы можем просто извлечь его HTML как строку с помощью метода html():
String docHtml = doc.html();
Строковый вывод представляет собой аккуратный HTML.
8. Заключение
Jsoup — отличная библиотека для очистки любой страницы. Если вы используете Java и вам не требуется парсинг на основе браузера, следует принять во внимание эту библиотеку. Он знаком и прост в использовании, поскольку он использует знания, которые могут у вас быть в области разработки интерфейса, и следует передовым методам и шаблонам проектирования.
Вы можете узнать больше об очистке веб-страниц с помощью jsoup, изучив API jsoup и прочитав кулинарную книгу jsoup.
Исходный код, используемый в этом руководстве, можно найти в проекте GitHub.