HTML in Java mit Jsoup analysieren

Analysieren von HTML in Java mit Jsoup

1. Überblick

Jsoup ist eine Open-Source-Java-Bibliothek, die hauptsächlich zum Extrahieren von Daten aus HTML verwendet wird. Sie können damit auch HTML bearbeiten und ausgeben. Es verfügt über eine stetige Entwicklungslinie, eine hervorragende Dokumentation und eine flüssige und flexible API. Jsoup kann auch zum Parsen und Erstellen von XML verwendet werden.

In diesem Tutorial verwenden wirSpring Blog, um eine Scraping-Übung zu veranschaulichen, die verschiedene Funktionen von jsoup demonstriert:

  • Laden: Abrufen und Parsen des HTML-Codes inDocument

  • Filtern: Wählen Sie die gewünschten Daten inElements aus und durchlaufen Sie sie

  • Extrahieren: Erhalten von Attributen, Text und HTML von Knoten

  • Ändern: Hinzufügen / Bearbeiten / Entfernen von Knoten und Bearbeiten ihrer Attribute

2. Maven-Abhängigkeit

Fügen Sie die Abhängigkeit zu Ihrenpom.xml hinzu, um die jsoup-Bibliothek in Ihrem Projekt zu verwenden:


    org.jsoup
    jsoup
    1.10.2

Sie finden die neueste Version vonjsoup im Maven Central-Repository.

3. Jsoup auf einen Blick

Jsoup lädt den Seiten-HTML-Code und erstellt den entsprechenden DOM-Baum. Dieser Baum funktioniert genauso wie das DOM in einem Browser und bietet ähnliche Methoden wie jQuery und Vanilla JavaScript zum Auswählen, Durchlaufen, Bearbeiten von Text / HTML / Attributen und Hinzufügen / Entfernen von Elementen.

Wenn Sie mit clientseitigen Selektoren und DOM-Traversing / Manipulation vertraut sind, ist Ihnen jsoup sehr vertraut. Überprüfen Sie, wie einfach es ist, die Absätze einer Seite zu drucken:

Document doc = Jsoup.connect("http://example.com").get();
doc.select("p").forEach(System.out::println);

Denken Sie daran, dass jsoup nur HTML interpretiert - es interpretiert kein JavaScript. Daher werden Änderungen am DOM, die normalerweise nach dem Laden von Seiten in einem JavaScript-fähigen Browser vorgenommen werden, in jsoup nicht angezeigt.

4. Wird geladen

Die Ladephase umfasst das Abrufen und Parsen des HTML-Codes inDocument. Jsoup garantiert das Parsen von HTML, vom ungültigsten bis zum vollständig validierten, wie es ein moderner Browser tun würde. Dies kann durch Laden vonString,InputStream,File oder einer URL erreicht werden.

Laden wir einDocument von der Spring Blog-URL:

String blogUrl = "https://spring.io/blog";
Document doc = Jsoup.connect(blogUrl).get();

Beachten Sie dieget-Methode, die einen HTTP-GET-Aufruf darstellt. Sie können auch einen HTTP-POST mit der Methodepost ausführen (oder Sie können einenmethod verwenden, der den HTTP-Methodentyp als Parameter empfängt).

Wenn Sie abnormale Statuscodes erkennen müssen (z. 404) sollten Sie die Ausnahme vonHttpStatusExceptionabfangen:

try {
   Document doc404 = Jsoup.connect("https://spring.io/will-not-be-found").get();
} catch (HttpStatusException ex) {
   //...
}

Manchmal muss die Verbindung etwas individueller gestaltet werden. Jsoup.connect(…) gibtConnection zurück, mit dem Sie unter anderem den Benutzeragenten, den Referrer, das Verbindungszeitlimit, Cookies, Postdaten und Header festlegen können:

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

Da die Verbindung einer fließenden Schnittstelle folgt, können Sie diese Methoden verketten, bevor Sie die gewünschte HTTP-Methode aufrufen:

Document docCustomConn = Jsoup.connect(blogUrl)
  .userAgent("Mozilla")
  .timeout(5000)
  .cookie("cookiename", "val234")
  .cookie("anothercookie", "ilovejsoup")
  .referrer("http://google.com")
  .header("headersecurity", "xyz123")
  .get();

Sie können mehr über die Einstellungen vonConnectiondurchbrowsing the corresponding Javadoc erfahren.

5. Filtern

Nachdem wir den HTML-Code inDocumentkonvertiert haben, ist es an der Zeit, darin zu navigieren und das zu finden, wonach wir suchen. Hier zeigt sich eine größere Ähnlichkeit mit jQuery / JavaScript, da die Selektoren und Traversierungsmethoden ähnlich sind.

5.1. Auswählen

DieDocumentselect-Methode empfängt einString, das den Selektor darstellt, unter Verwendung derselben Selektorsyntaxas in a CSS or JavaScript und ruft die übereinstimmende Liste vonElements ab. Diese Liste kann leer sein, aber nichtnull.

Schauen wir uns einige Auswahlen mit derselect-Methode an:

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");

Sie können auch explizitere Methoden verwenden, die vom Browser-DOM inspiriert sind, anstatt der generischenselect:

Element pag = doc.getElementById("pagination_control");
Elements desktopOnly = doc.getElementsByClass("desktopOnly");

DaElement eine Oberklasse vonDocument ist, können Sie in den JavadocsDocument undElement mehr über die Arbeit mit den Auswahlmethoden erfahren.

5.2. Durchqueren

Traversing means navigating across the DOM tree. Jsoup bietet Methoden, die mitDocument,Elements, oder bestimmtenElement arbeiten und es Ihnen ermöglichen, zu den Eltern, Geschwistern oder Kindern eines Knotens zu navigieren .

Sie können auch zum ersten, letzten und n-ten (unter Verwendung eines 0-basierten Index)Element in einer Menge vonElements springen:

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

Sie können auch eine Auswahl durchlaufen. Tatsächlich kann alles vom TypElements iteriert werden:

sections.forEach(el -> System.out.println("section: " + el));

Sie können eine Auswahl auf eine vorherige Auswahl beschränken (Unterauswahl):

Elements sectionParagraphs = firstSection.select(".paragraph");

6. Extrahieren

Wir wissen jetzt, wie bestimmte Elemente erreicht werden. Daher ist es an der Zeit, deren Inhalt abzurufen - nämlich deren Attribute, HTML oder untergeordneten Text.

Schauen Sie sich dieses Beispiel an, in dem der erste Artikel aus dem Blog ausgewählt und das Datum, der Text des ersten Abschnitts und schließlich der innere und äußere HTML-Code abgerufen werden:

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

Hier sind einige Tipps, die Sie bei der Auswahl und Verwendung von Selektoren beachten sollten:

  • Verlassen Sie sich auf die Funktion „Quelltext anzeigen“ Ihres Browsers und nicht nur auf das Seiten-DOM, da es sich möglicherweise geändert hat (die Auswahl an der Browserkonsole kann zu anderen Ergebnissen führen als jsoup).

  • Know your selectors, da es viele von ihnen gibt und es immer gut ist, sie zumindest vorher gesehen zu haben; Das Beherrschen von Selektoren braucht Zeit

  • Use a playground for selectors, um mit ihnen zu experimentieren (fügen Sie dort ein Beispiel-HTML ein)

  • Seien Sie weniger abhängig von Seitenänderungen: Streben Sie die kleinsten und am wenigsten gefährdenden Selektoren an (z. lieber id. basierend)

7. Ändern

Das Ändern umfasst das Festlegen von Attributen, Text und HTML von Elementen sowie das Anhängen und Entfernen von Elementen. Dies erfolgt mit dem DOM-Baum, der zuvor von jsoup generiert wurde -Document.

7.1. Festlegen von Attributen und innerem Text / HTML

Wie in jQuery tragen die Methoden zum Festlegen von Attributen, Text und HTML dieselben Namen, erhalten jedoch auch den festzulegenden Wert:

  • attr() - Legt die Werte eines Attributs fest (es erstellt das Attribut, wenn es nicht vorhanden ist).

  • text() - Legt den inneren Text des Elements fest und ersetzt den Inhalt

  • html() - Setzt das innere HTML des Elements und ersetzt den Inhalt

Schauen wir uns ein kurzes Beispiel für diese Methoden an:

timeElement.attr("datetime", "2016-12-16 15:19:54.3");
sectionDiv.text("foo bar");
firstArticle.select("h2").html("
");

7.2. Elemente erstellen und anhängen

Um ein neues Element hinzuzufügen, müssen Sie es zuerst erstellen, indem SieElement instanziieren. Sobald dasElement erstellt wurde, können Sie es mit derappendChild-Methode an ein anderesElement anhängen. Die neu erstellten und angehängtenElement werden am Ende des Elements eingefügt, in demappendChild heißt:

Element link = new Element(Tag.valueOf("a"), "")
  .text("Checkout this amazing website!")
  .attr("href", "http://example.com")
  .attr("target", "_blank");
firstArticle.appendChild(link);

7.3. Elemente entfernen

Um Elemente zu entfernen, müssen Sie sie zuerst auswählen und die Methoderemoveausführen.

Entfernen wir beispielsweise alle<li>-Tags, die die Klasse "navbar-link”" enthalten, ausDocument, und alle Bilder aus dem ersten Artikel:

doc.select("li.navbar-link").remove();
firstArticle.select("img").remove();

7.4. Konvertieren des geänderten Dokuments in HTML

Da wir dieDocument geändert haben, möchten wir möglicherweise unsere Arbeit überprüfen.

Zu diesem Zweck können wir den DOM-Baum vonDocumentdurch Auswählen, Durchlaufen und Extrahieren mit den vorgestellten Methoden untersuchen oder einfach den HTML-Code alsStringmit der Methode vonhtml() extrahieren:

String docHtml = doc.html();

Die Ausgabe vonStringist ein ordentliches HTML.

8. Fazit

Jsoup ist eine großartige Bibliothek, um jede Seite zu kratzen. Wenn Sie Java verwenden und kein browserbasiertes Scraping benötigen, ist dies eine Bibliothek, die berücksichtigt werden muss. Es ist vertraut und einfach zu verwenden, da es das Wissen nutzt, das Sie möglicherweise über die Front-End-Entwicklung haben, und bewährten Praktiken und Entwurfsmustern folgt.

Sie können mehr über das Scraping von Webseiten mit jsoup erfahren, indem Sie diejsoup API studieren und diejsoup cookbook lesen.

Der in diesem Tutorial verwendete Quellcode befindet sich inGitHub project.