JSoup

Jsoup jest najpopularniejszą biblioteką w Javie przeznaczoną do projektów, w których wymagane są operacje takie jak:

  • pobieranie danych ze stron www
  • parsowanie źródła strony
  • wyciąganie ze źródła strony informacji o poszczególnych węzłach

Jeżeli więc w swoim programie chcesz zrobić rzeczy w stylu wyciągnięcie wszystkich nagłówków dostępnych na danej stronie, albo pobranie wszystkich odnośników, to Jsoup sprawdzi się tutaj idealnie. Rozwiązanie takie jest zdecydowanie lepsze niż próba wykorzystywania wyrażeń regularnych, ponieważ jak to się mówi, tworząc projekt mieliśmy jeden problem, zaczęliśmy korzystać z wyrażeń regularnych i teraz mamy dwa problemy.

Konfiguracja

Zanim zaczniemy korzystać z Jsoup musimy pobrać bibliotekę i dołączyć ją do swojego projektu. Najpierw pobierz najnowszą wersję z oficjalnej strony, a następnie w projekcie utwórz folder o nazwie np. lib, do którego skopiuj pobrany plik .jar. W przypadku Eclipse bibliotekę należy dodać do projektu klikając na nią prawym przyciskiem myszy i wybierając opcję Build Path > Add to build path.

jsoup build path

Pobieranie źródła strony

Pierwszym krokiem do tego, żeby wykonywać dowolne operacje na dokumentach (stronach www) jest ich pobranie. Można to robić ręcznie korzystając z klas takich jak URL, URLConnection, BufferedReader . Rozwiązanie takie jest jednak wtórne i jest trochę wynajdowaniem koła na nowo. Zamiast tego można skorzystać też z klas dostępnych w bibliotece Apache HTTP Components , jednak jest ona dedykowana do wykonywania zapytań i komunikacji HTTP, a nie do parsowania dokumentów. Jsoup łączy pobieranie danych z możliwością ich późniejszej modyfikacji. W celu pobrania źródła dowolnej strony www wystarczy wywołać jedną statyczną metodę Jsoup.connect() przekazując jej adres URL w postaci Stringa. W wyniku otrzymamy obiekt typu Connection , na którym możemy wywołać metodę get() lub post() odpowiadającym odpowiednim metodom HTTP i zwracającym obiekt typu Document , który reprezentuje dokument DOM. Metody get() , czy post() mogą rzucić wyjątek typu IOException (np. brak połączenia z internetem), który musimy obsłużyć lub zadeklarować go w sygnaturze metody.

import java.io.IOException;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

public class JsoupTest {
    public static void main(String[] args) throws IOException {
        Connection connect = Jsoup.connect("http://www.onet.pl/");
        Document document = connect.get();
    }
}

Obiekt Document jest podstawą niemal całego Jsoupa, reprezentuje on całe drzewo dokumentu i pozwala dostać się do poszczególnych węzłów źródła HTML.

Parsowanie dokumentu

Jeżeli nasz dokument nie jest zasobem, do którego możemy się odwołać poprzez protokół HTTP, czyli w ogólności nie jest stroną WWW na zewnętrznym serwerze, ale np. po prostu plikiem na dysku twardym lub zwykłym Stringiem wczytanym z dowolnego źródła, to możemy skorzystać z metody Jsoup.parse() , przekazując dokument HTML w postaci Stringa. W wyniku również otrzymamy obiekt typu Document.

Document parse = Jsoup.parse("<html><head></head><body></body></html>");

Ekstrakcja elementów

Czas na najciekawszą część, czyli wyciąganie informacji z dokumentu. Możemy się tutaj posługiwać przede wszystkim metodą select() przekazując jej jako argument selektor. Może to byś selektor CSS lub selektor wykorzystujący składnię opisaną w dokumentacji biblioteki. Załóżmy, że chcemy wyciągnąć wszystkie nagłówki <h1> ze strony głównej onetu. Zapiszemy wtedy:

import java.io.IOException;

import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class JsoupTest {
    public static void main(String[] args) throws IOException {
        Connection connect = Jsoup.connect("http://www.onet.pl/");
        Document document = connect.get();
        Elements allH1 = document.select("h1");
        for(Element elem: allH1) {
            System.out.println(elem.text());
        }
    }
}

Metoda select() zwróci nam obiekt typu Elements , który jest kolekcją obiektów Element, z których każdy reprezentuje pojedynczy nagłówek H1. Dzięki temu, że obiekt Elements implementuje interfejs Iterable , to możliwe jest iterowanie po nim z wykorzystaniem metody forEach. W celu pobrania zawartości tekstowej poszczególnych węzłów posługujemy się metodą text().

Jsuop posiada bardzo rozbudowane możliwości, takie jak pobieranie elementów strony, które posiadają atrybut o wskazanej wartości, czy na podstawie klas CSS. Oprócz tego bardzo przydatną opcją jest pobieranie elementów wykorzystując selektory CSS typu .titleContener > span:nth-child(1), który w wygodny sposób możemy pobrać wykorzystując np. narzędzia dla deweloperów wbudowane w przeglądarkę Firefox, czy Chrome:

unikalny selektor

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.