HTML ontleden in Java met Jsoup

1. Overzicht

Jsoup is een open source Java-bibliotheek die voornamelijk wordt gebruikt voor het extraheren van gegevens uit HTML. Het stelt je ook in staat om HTML te manipuleren en uit te voeren. Het heeft een gestage ontwikkelingslijn, geweldige documentatie en een vloeiende en flexibele API. Jsoup kan ook worden gebruikt om XML te ontleden en op te bouwen.

In deze tutorial gebruiken we de Spring Blog om een ​​scraping-oefening te illustreren die verschillende functies van jsoup demonstreert:

  • Laden: de HTML ophalen en ontleden in een Document
  • Filteren: het selecteren van de gewenste gegevens in Elementen en het doorkruisen
  • Extraheren: attributen, tekst en HTML van knooppunten verkrijgen
  • Wijzigen: knopen toevoegen / bewerken / verwijderen en hun attributen bewerken

2. Maven Afhankelijkheid

Om gebruik te maken van de jsoup-bibliotheek in uw project, voegt u de afhankelijkheid toe aan uw pom.xml:

 org.jsoup jsoup 1.10.2 

U kunt de nieuwste versie van jsoup vinden in de Maven Central-repository.

3. Jsoup in een oogopslag

Jsoup laadt de HTML van de pagina en bouwt de bijbehorende DOM-structuur. Deze structuur werkt op dezelfde manier als de DOM in een browser en biedt methoden die vergelijkbaar zijn met jQuery en vanilla JavaScript om tekst / HTML / attributen te selecteren, door te lopen, te manipuleren en elementen toe te voegen / te verwijderen.

Als u vertrouwd bent met selectors aan de clientzijde en DOM-traversing / -manipulatie, zult u jsoup zeer vertrouwd vinden. Controleer hoe gemakkelijk het is om de alinea's van een pagina af te drukken:

Document doc = Jsoup.connect ("// voorbeeld.com"). Get (); doc.select ("p"). forEach (System.out :: println);

Houd er rekening mee dat jsoup alleen HTML interpreteert - het interpreteert geen JavaScript. Daarom worden wijzigingen in de DOM die normaal zouden plaatsvinden nadat de pagina is geladen in een JavaScript-geactiveerde browser, niet zichtbaar in jsoup.

4. Laden

De laadfase omvat het ophalen en ontleden van de HTML in een Document. Jsoup garandeert het parseren van elke HTML, van de meest ongeldige tot de volledig gevalideerde, zoals een moderne browser zou doen. Het kan worden bereikt door een Draad, een InputStream, een het dossier of een URL.

Laten we een Document van de Spring Blog-URL:

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

Let op de krijgen methode, vertegenwoordigt het een HTTP GET-aanroep. U kunt ook een HTTP POST doen met de post methode (of je zou een methode die het type HTTP-methode als parameter ontvangt).

Als u abnormale statuscodes (bijv. 404) moet detecteren, moet u de HttpStatusException uitzondering:

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

Soms moet de verbinding wat meer worden aangepast. Jsoup.connect (...) geeft een terug Verbinding waarmee u onder andere de user-agent, verwijzer, time-out voor verbinding, cookies, postgegevens en headers kunt instellen:

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

Omdat de verbinding een vloeiende interface volgt, kunt u deze methoden koppelen voordat u de gewenste HTTP-methode aanroept:

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

U kunt meer te weten komen over de Verbinding instellingen door te bladeren door de overeenkomstige Javadoc.

5. Filteren

Nu we de HTML hebben omgezet in een Document, is het tijd om er doorheen te navigeren en te vinden wat we zoeken. Dit is waar de gelijkenis met jQuery / JavaScript duidelijker is, omdat de selectors en doorloopmethoden vergelijkbaar zijn.

5.1. Selecteren

De Documentselecteer methode ontvangt een Draad die de selector vertegenwoordigt, met dezelfde selector-syntaxis als in een CSS of JavaScript, en haalt de overeenkomende lijst op van Elementen. Deze lijst mag leeg zijn, maar niet nul.

Laten we een paar selecties bekijken met behulp van de selecteer methode:

Elements links = doc.select ("a"); Elements secties = doc.select ("sectie"); Elements logo = doc.select (". Spring-logo - container"); Elementen pagination = doc.select ("# pagination_control"); Elements divsDescendant = doc.select ("header div"); Elements divsDirect = doc.select ("header> div");

U kunt ook meer expliciete methoden gebruiken die zijn geïnspireerd door de browser-DOM in plaats van de generieke selecteer:

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

Sinds Element is een superklasse van Documentvindt u meer informatie over het werken met de selectiemethoden in het Document en Element Javadocs.

5.2. Oversteken

Doorkruisen betekent navigeren door de DOM-structuur. Jsoup biedt methoden die werken op het Document, op een set van Elementen, of op een specifiek Element, zodat u naar de ouders, broers en zussen of kinderen van een knooppunt kunt navigeren.

U kunt ook naar de eerste, de laatste en de nde springen (met behulp van een op 0 gebaseerde index) Element in een set van Elementen:

Element firstSection = secties.first (); Element lastSection = secties.last (); Element secondSection = secties.get (2); Elements allParents = firstSection.parents (); Element ouder = firstSection.parent (); Elementen kinderen = firstSection.children (); Elements broers en zussen = firstSection.siblingElements ();

U kunt ook selecties doorlopen. In feite alles van het type Elementen kan worden herhaald:

secties.forEach (el -> System.out.println ("sectie:" + el));

U kunt een selectie maken die beperkt is tot een eerdere selectie (subselectie):

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

6. Extractie

We weten nu hoe we specifieke elementen kunnen bereiken, dus het is tijd om hun inhoud te krijgen, namelijk hun attributen, HTML of onderliggende tekst.

Bekijk dit voorbeeld dat het eerste artikel van de blog selecteert en de datum, de eerste sectietekst en ten slotte de binnenste en buitenste HTML krijgt:

Element firstArticle = doc.select ("artikel"). First (); Element timeElement = firstArticle.select ("tijd"). First (); String dateTimeOfFirstArticle = timeElement.attr ("datetime"); Element sectionDiv = firstArticle.select ("sectie div"). First (); String sectionDivText = sectionDiv.text (); String articleHtml = firstArticle.html (); String outerHtml = firstArticle.outerHtml ();

Hier zijn enkele tips waarmee u rekening moet houden bij het kiezen en gebruiken van selectors:

  • Vertrouw op de functie "Bron weergeven" van uw browser en niet alleen op de pagina DOM, aangezien deze mogelijk is gewijzigd (selecteren in de browserconsole kan andere resultaten opleveren dan jsoup)
  • Ken je selectors, want er zijn er veel en het is altijd goed om ze in ieder geval eerder te hebben gezien; het beheersen van selectors kost tijd
  • Gebruik een speelplaats voor selectors om ermee te experimenteren (plak daar een voorbeeld-HTML)
  • Wees minder afhankelijk van paginawijzigingen: streef naar de kleinste en minst compromitterende selectors (bijv. Prefereer id. Gebaseerd)

7. Wijzigen

Wijzigen omvat het instellen van attributen, tekst en HTML van elementen, evenals het toevoegen en verwijderen van elementen. Het wordt gedaan met de DOM-structuur die eerder is gegenereerd door jsoup - de Document.

7.1. Attributen en innerlijke tekst / HTML instellen

Net als in jQuery hebben de methoden om attributen, tekst en HTML in te stellen dezelfde naam, maar ontvangen ze ook de in te stellen waarde:

  • attr () - stelt de waarden van een attribuut in (het creëert het attribuut als het niet bestaat)
  • tekst() - stelt element innerlijke tekst in, vervangt inhoud
  • html () - stelt element innerlijke HTML in, ter vervanging van inhoud

Laten we eens kijken naar een snel voorbeeld van deze methoden:

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

7.2. Elementen maken en toevoegen

Om een ​​nieuw element toe te voegen, moet u het eerst bouwen door te instantiëren Element. Zodra het Element is gebouwd, kunt u deze aan een andere toevoegen Element de ... gebruiken appendChild methode. De nieuw gemaakte en toegevoegde Element zal worden ingevoegd aan het einde van het element waar appendChild wordt genoemd:

Element link = new Element (Tag.valueOf ("a"), "") .text ("Bekijk deze geweldige website!") .Attr ("href", "//baeldung.com") .attr ("target" , "_blank"); firstArticle.appendChild (link);

7.3. Elementen verwijderen

Om elementen te verwijderen, moet u ze eerst selecteren en het verwijderen methode.

Laten we bijvoorbeeld alles verwijderen

  • tags die de "navbar-link ” klas van Document, en alle afbeeldingen uit het eerste artikel:

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

    7.4. Het gewijzigde document converteren naar HTML

    Eindelijk, aangezien we het Document, willen we misschien ons werk controleren.

    Om dit te doen, kunnen we het Document DOM-structuur door het selecteren, doorlopen en extraheren met behulp van de gepresenteerde methoden, of we kunnen eenvoudig de HTML ervan extraheren als een Draad de ... gebruiken html () methode:

    String docHtml = doc.html ();

    De Draad output is een nette HTML.

    8. Conclusie

    Jsoup is een geweldige bibliotheek om elke pagina te schrapen. Als u Java gebruikt en geen scraping via de browser nodig heeft, is dit een bibliotheek waarmee u rekening moet houden. Het is vertrouwd en gemakkelijk te gebruiken omdat het gebruik maakt van de kennis die u mogelijk heeft over front-end ontwikkeling en goede praktijken en ontwerppatronen volgt.

    U kunt meer leren over het scrapen van webpagina's met jsoup door de jsoup-API te bestuderen en het jsoup-kookboek te lezen.

    De broncode die in deze tutorial wordt gebruikt, is te vinden in het GitHub-project.