Java → Парсер HTML в Java (jsoup)

Авг 16, 2011


Не так давно, у меня возникла необходимость парсить html-страницы, выдирая из них нужные ссылки. Первая мысль была сделать это через регулярные выражения. Но здравый смысл подсказывал, что парсить html-код регулярками есть величайшее зло. Стыдно признаться, но программируя на языке Delphi я использовал именно их, так как нормальных средств и компонентов по разбору html-тэгов мне найти так и не удалось.

В противоположность этому, Java, благодаря своей популярности, обладает большим количеством различных библиотек - как встроенных, так и сторонних. Не долго думая, была выбрана первая попавшаяся библиотека - jsoup. Стоит сказать, что данная библиотека достаточно часто обновляется и поддерживает, что не мало важно, HTML5. На сайте представлены простые примеры в две строчки, с помощью которых можно приступать писать приложения, использующие jsoup даже без чтения JavaDoc.

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


Для начала необходимо скачать библиотеку jsoup-1.6.1.jar с официального сайта (название файла может отличаться) и аккуратно положить его рядом с файлом вашего класса, например Sample.java. После этого открываем в своем любимом редакторе файл Sample.java и пишем следующий код:

import org.jsoup.*;
import org.jsoup.nodes.*;
import org.jsoup.select.*;
import java.io.*;

public class Sample {
	public static void main(String[] args) throws IOException {
		Document doc = Jsoup.connect("http://tdlite.ru").get();
		Elements links = doc.getElementsByTag("a");
		for(Element link : links) {
			System.out.println(link.text());
		}
	}
}



Пояснения


Сначала мы импортируем все классы из следующих пакетов:

org.jsoup.*; - для класса Jsoup
org.jsoup.nodes.*; - для классов Document, Element
org.jsoup.select.*; - для класса Elements
java.io.*; - для класса IOException

Так как метод connect класса Jsoup может выбросить исключение, например, если соединение не удалось, нужно методу main сообщить об этом, добавив throws IOException. Также вы можете обработать исключение через try-catch, но в моем случае я не стал усложнять код.

Сразу после connect, вызывается метод get(), выполняющий обращение к указанному адресу через GET метод. Если вы хотите обратиться к сайту через POST, то необходимо заменить метод get() на post(), а параметры посылать функцией data() - более подробно об этом вы можете почитать в API.

Теперь, когда содержимое страницы получено, можно парсить html-код, используя различные методы класса Document. Например, использовав getElementsByTag("a") мы получим все ссылки, то есть все тэги A, в список links. Стоит сказать, что тот же самый эффект получится, если использовать селекторы - doc.select("a[href]"). Получить текст ссылки, или так называемый анкор, можно пройдясь по каждому элементу этого списка и вызвав метод text().

Компиляция


Поговорим о компиляции нашего класса Sample, так как она не совсем тривиальная. Компилятор пока не знает где искать библиотеку и поэтому ему нужно сообщить путь (classpath) к jsoup-1.6.1.jar:

javac -cp ./jsoup-1.6.1.jar Sample.java

Запуск скомпилированного класса необходимо также производить с указанием classpath, но при этом добавить путь к текущей директории, использовав точку и слэш, а в качестве разделителей путей, точку с запятой:

java -cp ./;./jsoup-1.6.1.jar Sample



Кодировка


Если выполнив этот пример в консоли, вы увидите кракозябры, то не пугайтесь - с библиотекой все в порядке. Скорей всего проблема в кодировке самой консоли и решить её можно прочитав предыдущую статью и добавив соответствующие строчки в начало метода main.

Всегда мечтал купить себе какой-нибудь старенький автомобиль и затюнинговать его так, чтобы было не отличить от спорт-кара. В этом всегда есть плюсы. Например, можно сделать тюнинг ВАЗ 2115 и кататься по городу, собирая взгляды мимо проходящих девушек. Однако, пока у меня машины не появилось, остается только любоваться на фотки тачек, пуская слюни.

Post to Twitter

Похожие статьи:

  1. Консольная кодировка в Java
  2. Двухтомник от Хорстманна

Комментарии (5)

  1. avatar

    Андрей
    Август 27th, 2011 at 17:37 #

    Спасибо! Очень пригодилось.

  2. avatar

    Bober
    Октябрь 27th, 2011 at 16:22 #

    Спасибо за статью.
    Но при помощи jsoup нет возможности ходить через прокси. Может я не прав и кто то подскажет как?

  3. avatar

    Алексей
    Февраль 8th, 2012 at 00:20 #

    Спасибо. Полезная либа.

  4. avatar

    Андрей
    Март 1st, 2012 at 17:07 #

    Неплохо. В документации нашёл пример, как можно посылать кукисы в запросе. Это очень полезная штука для сайтов без собственного API, где доступ к определённым ресурсам возможет только после авторизации.

    Для Delphi тоже не смог найти толкового парсера HTML. Может, в Indy не доглядел где-то.

  5. avatar

    Эрнест
    Май 4th, 2012 at 11:12 #

    Вот это круть! Вот это тема! Я хотел начинать писать парсер на c++ Qt, но теперь уже передумал :D

Ваш комментарий

Rambler's Top100 Яндекс.Метрика