JavaRush /Java блог /Random /Лёгкий парсинг HTML с помощью jsoup
Stanislav
21 уровень
Москва

Лёгкий парсинг HTML с помощью jsoup

Статья из группы Random
Возможно, когда-нибудь вам будет необходимо получить информацию с какого-либо сайта либо HTML-документа в своем приложении, и я без лишних слов скажу, что использование библиотеки jsoup существенно упростит вашу задачу. Как говорится на wiki, jsoup — это Java-библиотека с открытым исходным кодом, предназначенная для анализа, извлечения и управления данными, хранящимися в документах HTML.

Быстрый старт

Библиотеку можно скачать в виде jar файла и поместить в проект, а также подключить с помощью Maven/Gradle. Ссылку на официальный сайт я оставлю в конце статьи: там вы сможете найти актуальную версию библиотеки. В примере будем использовать подключение через Maven. Добавим зависимость:

<​dependency​>
  <​groupId>org.jsoup<​/groupId>
  <​artifactId>jsoup<​/artifactId>
  <​version>1.11.3<​/version>
<​/dependency>

Использование

Первым делом вам необходимо получить экземпляр класса Document из org.jsoup.nodes.Document с указанием на источник для разбора. Им может выступать как локальный файл, так и ссылка. Для примера, в данной статье мы будем использовать сайт yandex.ru и попытаемся получить их актуальную новостную ленту:

		Document doc = Jsoup.connect("https://yandex.ru/")
                .userAgent("Chrome/4.0.249.0 Safari/532.5")
                .referrer("http://www.google.com")
                .get();
User Agent является идентификатором, который сообщается посещаемому сайту. На многих сайтах он является важнейшим критерием для антиспам фильтра. Referrer содержит URL источника запроса. Метод get() вызывает обрабатываемое исключение IOException, так что мы можем обернуть все в try/catch блок, либо просто перебросить его дальше с помощью throws. На данный момент мы получили исходный код данной страницы. При необходимости библиотека jsoup сама может восстановить поврежденные элементы. Теперь нам остается лишь сузить поиск до отдельного блока. Метод select() имеет большую выборку в использовании: он позволяет искать элементы по тегу, атрибутам, классу и другим параметрам. Почти все современные браузеры поддерживают возможность быстрого поиска исходного кода выбранного элемента. Нехитрыми манипуляциями, мы находим исходный код нужного нам элемента и получаем div блок с указанным классом, его мы и будем использовать для выборки. Лёгкий парсинг HTML с помощью jsoup - 1Воспользуемся классом Elements из org.jsoup.select.Elements, для выборки всех элементов из нашего выбранного блока.

Elements listNews = doc.select("div#tabnews_newsc.content-tabs__items.content-tabs__items_active_true");
Сейчас мы имеем что то вроде этого: Лёгкий парсинг HTML с помощью jsoup - 2Теперь нам остается лишь использовать небольшой цикл для пробора всех элементов:

for (Element element : listNews.select("a"))
            System.out.println(element.text());
Метод text() позволяет отбросить код разметки и оставляет лишь сочетание текста для всех входящих элементов. Результат выполнения будет таков: Лёгкий парсинг HTML с помощью jsoup - 3Нетрудно заметить, что реальное количество полученных строк не соответствует фактическому отображению на странице. В этом и заключаются подводные камни. Если посмотреть исходный код разметки, можно заметить, что последняя новость анимационно меняется с определенным интервалом времени. Часть таких "камней" решается дополнительной выборкой, ну и конечно тестами. Может оказаться так, что первые пять элементов будут содержать нужную нам информацию, а на шестом элементе будет лишь заскриптованная пустая строка. Бывает и такое, что блоки не будут обладать какими-либо идентификаторами, тогда есть возможностью прямо указать с помощью метода get(int index) на номер позиции рассматриваемого элемента.

System.out.println(listNews.select("a").get(2).text());

Заключение

В данном примере показана лишь малая часть того, на что способен jsoup. Не стоит отменять и тот факт, что сайты нередко обновляются, изменяя структуру кода разметки, так что при работе с парсингом нужно быть готовым адаптироваться к изменениям. Больше информации и актуальную версию вы можете получить на официальном сайте jsoup.org, более подробно почитать про классы и методы можно по ссылке o7planning.org. Оставлю ссылку на мой github, на момент написания статьи там находится несколько Telegram-ботов, которые используют Jsoup для получения и выдачи информации.
Комментарии (32)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Roman Уровень 33
19 декабря 2023
Весь день сегодня убил, пытаясь проверить эту статью. Мой вывод - не надо пытаться её осознать, потому что она уж слишком общая (как искать ёжика в тумане). Вывел в консоль некоторую инфу с Мэйл.ру (там новости прям на главной).

        Document doc = Jsoup.connect("https://mail.ru/")
                .userAgent("Chrome/4.0.249.0 Safari/532.5")
                .referrer("http://www.google.com")
                .get();

        //по разным заголовкам: политика, спорт, авто и т.д.
        Elements listNews = doc.select("div.news__list__item__wrap");

        //новости на главной
        Elements listNewsSimple = doc.select("div.news__list__item.news__list__item_simple");

        //гороскоп
        Elements listHor = doc.select("div.horoscope__forecast");

        for (Element element : listNewsSimple.select("a"))
            System.out.println(element.text());
Чтобы найти требуемый div для select, нужно смотреть в дебаггере или вывести куда-то весь считанный в doc файл. Только там будет корректный. В браузере выдаёт лажу.
Ilya Maystrenko Уровень 28
20 января 2023
Всем хэллоу. Есть проблема с парсингом по значению атрибута. Document childDoc = Jsoup.connect(el.absUrl("href")).get(); Elements childDescriptions = childDoc.getElementsByAttributeValueContaining("content", "смотреть"); Метод не присваивает значения переменной childDescriptions, хотя в окне Evaluate считает корректно. При этом со значениями, состоящими не из иириллицы проблем никаких нет. P.S. Проверял на другом компе, все работает отлично вне зависимости от типа символов.
Kurama Уровень 50
28 ноября 2022
Вернусь сюда, когда начну учить maven или gradle...
апецт Уровень 50
15 ноября 2022
почему в аргументе "a"?

listNews.select("a")
Евгений Уровень 38
27 декабря 2021
Для тех, кто ничё не понял:
Alena Palasionak Уровень 37
4 октября 2021
Простое видео, чтобы попробовать спарсить картинки.
Макс Дудин Уровень 41
17 сентября 2021
В общем и целом понятно, что это всё как-то можно использовать в практических целях... не более того
Александр Уровень 40
10 сентября 2021
Библиотеку можно скачать с сайта: https://jsoup.org/download файл актуальной версии jsoup-1.14.2.jar (code library). В Idea: File > Project Structure > Modules, выбрать вкладку Dependencies, нажать + и добавить скачанный jar, поставить галочку и нажать Apply. Библиотека должна появиться в External Libraries.
Илья Уровень 30
11 апреля 2021
Из этого примера должно что-то выводится? Или это, так, описания ради?.. Скопировал код, чтоб увидеть результат, а в результате пустота..

         Document doc = Jsoup.connect("https://yandex.ru/")
                .userAgent("Chrome/4.0.249.0 Safari/532.5")
                .referrer("http://www.google.com")
                .get();
        Elements listNews = doc.select("div#tabnews_newsc.content-tabs__items.content-tabs__items_active_true");
        for (Element element : listNews.select("a"))
            System.out.println(element.text());
barracuda Уровень 41 Expert
29 октября 2020
Что-то из этого я понял.