Analyse af HTML i Java med Jsoup

1. Oversigt

Jsoup er et open source Java-bibliotek, der hovedsageligt bruges til at udtrække data fra HTML. Det giver dig også mulighed for at manipulere og output HTML. Det har en stabil udviklingslinje, god dokumentation og en flydende og fleksibel API. Jsoup kan også bruges til at analysere og opbygge XML.

I denne vejledning bruger vi Spring Blog til at illustrere en skrabende øvelse, der demonstrerer flere funktioner i jsoup:

  • Indlæser: henter og parser HTML til en Dokument
  • Filtrering: vælg de ønskede data i Elementer og krydser det
  • Uddrag: Hentning af attributter, tekst og HTML for noder
  • Ændring: tilføjelse / redigering / fjernelse af noder og redigering af deres attributter

2. Maven-afhængighed

For at gøre brug af jsoup-biblioteket i dit projekt skal du tilføje afhængigheden af ​​dit pom.xml:

 org.jsoup jsoup 1.10.2 

Du kan finde den nyeste version af jsoup i Maven Central-arkivet.

3. Overblik over Jsoup

Jsoup indlæser side-HTML og bygger det tilsvarende DOM-træ. Dette træ fungerer på samme måde som DOM i en browser og tilbyder metoder svarende til jQuery og vanilje JavaScript til at vælge, gennemgå, manipulere tekst / HTML / attributter og tilføje / fjerne elementer.

Hvis du er fortrolig med klientsidesvælgere og DOM-gennemkørsel / manipulation, finder du jsoup meget velkendt. Kontroller, hvor let det er at udskrive afsnit på en side:

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

Husk, at jsoup kun fortolker HTML - det fortolker ikke JavaScript. Derfor kan ændringer i DOM, der normalt ville finde sted efter sideindlæsning i en JavaScript-aktiveret browser, ikke ses i jsoup.

4. Indlæser

Indlæsningsfasen omfatter hentning og parsing af HTML til en Dokument. Jsoup garanterer parsing af enhver HTML, fra den mest ugyldige til de helt validerede, som en moderne browser ville gøre. Det kan opnås ved at indlæse en Snor, en InputStream, a Fil eller en URL.

Lad os indlæse en Dokument fra URL til forårets blog:

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

Læg mærke til metode repræsenterer det et HTTP GET-opkald. Du kan også lave en HTTP POST med stolpe metode (eller du kan bruge en metode som modtager HTTP-metodetypen som parameter).

Hvis du har brug for at opdage unormale statuskoder (f.eks. 404), skal du fange HttpStatusException undtagelse:

prøv {Document doc404 = Jsoup.connect ("// spring.io/will-not-be-found"). get (); } fange (HttpStatusException ex) {// ...}

Nogle gange skal forbindelsen være lidt mere tilpasset. Jsoup.connect (…) returnerer a Forbindelse som giver dig mulighed for at indstille blandt andet brugeragenten, henviseren, timeout for forbindelsen, cookies, indlægsdata og overskrifter:

Forbindelsesforbindelse = 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"); Dokument docCustomConn = forbindelse.get ();

Da forbindelsen følger en flydende grænseflade, kan du kæde disse metoder, inden du kalder den ønskede HTTP-metode:

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

Du kan lære mere om Forbindelse indstillinger ved at gennemse den tilsvarende Javadoc.

5. Filtrering

Nu hvor vi har konverteret HTML til en Dokument, det er tid til at navigere i det og finde det, vi leder efter. Det er her, ligheden med jQuery / JavaScript er mere tydelig, da dens vælgere og gennemkørselsmetoder er ens.

5.1. Vælger

Det DokumentVælg metoden modtager en Snor repræsenterer vælgeren ved hjælp af den samme selektor-syntaks som i en CSS eller JavaScript og henter den matchende liste over Elementer. Denne liste kan være tom, men ikke nul.

Lad os se på nogle valg ved hjælp af Vælg metode:

Elementslinks = doc.select ("a"); Elementsektioner = doc.select ("sektion"); Elementelogo = doc.select (". Spring-logo - container"); Elements pagination = doc.select ("# pagination_control"); Elements divsDescendant = doc.select ("header div"); Elements divsDirect = doc.select ("header> div");

Du kan også bruge mere eksplicitte metoder inspireret af browseren DOM i stedet for det generiske Vælg:

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

Siden Element er en superklasse af Dokument, kan du lære mere om at arbejde med udvælgelsesmetoderne i Dokument og Element Javadocs.

5.2. Traversering

Traversering betyder at navigere over DOM-træet. Jsoup giver metoder, der fungerer på Dokument, på et sæt af Elementer, eller på en bestemt Element, der giver dig mulighed for at navigere til en knuds forældre, søskende eller børn.

Du kan også springe til den første, den sidste og den nte (ved hjælp af et 0-baseret indeks) Element i et sæt af Elementer:

Element firstSection = sektioner. Første (); Element lastSection = sektioner. Sidste (); Element secondSection = sektioner.get (2); Elements allParents = firstSection.parents (); Elementforælder = firstSection.parent (); Elementer børn = firstSection.children (); Elements søskende = firstSection.siblingElements ();

Du kan også gentage gennem valg. Faktisk noget af typen Elementer kan gentages:

sektioner. forEach (el -> System.out.println ("sektion:" + el));

Du kan foretage et valg begrænset til et tidligere valg (undervalg):

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

6. Uddrag

Vi ved nu, hvordan man når ud til bestemte elementer, så det er tid til at få deres indhold - nemlig deres attributter, HTML eller underordnet tekst.

Se på dette eksempel, der vælger den første artikel fra bloggen og får sin dato, dens første sektionstekst og endelig dens indre og ydre HTML:

Element firstArticle = doc.select ("artikel"). First (); Element timeElement = firstArticle.select ("time"). First (); String dateTimeOfFirstArticle = timeElement.attr ("datetime"); Element sectionDiv = firstArticle.select ("sektion div"). First (); Streng sectionDivText = sectionDiv.text (); StrengeartikelHtml = firstArticle.html (); String outerHtml = firstArticle.outerHtml ();

Her er nogle tip, du skal huske på, når du vælger og bruger vælgere:

  • Stol på "Vis kilde" -funktionen i din browser og ikke kun på siden DOM, da den måske har ændret sig (valg ved browserkonsollen kan give andre resultater end jsoup)
  • Kend dine vælgere, da der er mange af dem, og det er altid godt at have i det mindste set dem før; mastering af vælgere tager tid
  • Brug en legeplads til vælgere til at eksperimentere med dem (indsæt en prøve-HTML der)
  • Vær mindre afhængig af sideændringer: sigter mod de mindste og mindst kompromitterende vælgere (f.eks. Foretrækker id. Baseret)

7. Ændring

Ændring omfatter indstillingsattributter, tekst og HTML for elementer samt tilføjelse og fjernelse af elementer. Det gøres til DOM-træet, der tidligere blev genereret af jsoup - the Dokument.

7.1. Indstilling af attributter og indre tekst / HTML

Som i jQuery bærer metoderne til at indstille attributter, tekst og HTML de samme navne, men modtager også den værdi, der skal indstilles:

  • attr () - indstiller en attributs værdier (det opretter attributten, hvis den ikke findes)
  • tekst() - indstiller elementets indre tekst, der erstatter indhold
  • html () - indstiller elementets indre HTML, der erstatter indhold

Lad os se på et hurtigt eksempel på disse metoder:

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

7.2. Oprettelse og tilføjelse af elementer

For at tilføje et nyt element skal du først bygge det ved at instantiere Element. En gang Element er blevet bygget, kan du føje det til en anden Element bruger appendChild metode. Det nyoprettede og vedhæftede Element indsættes i slutningen af ​​elementet hvor appendChild Hedder:

Elementlink = nyt element (Tag.valueOf ("a"), "") .text ("Checkout this amazing website!") .Attr ("href", "//baeldung.com") .attr ("target" , "_blank"); firstArticle.appendChild (link);

7.3. Fjernelse af elementer

For at fjerne elementer skal du først markere dem og køre fjerne metode.

Lad os for eksempel fjerne alt

  • tags, der indeholder “navbar-link ” klasse fra Dokument, og alle billeder fra den første artikel:

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

    7.4. Konvertering af det ændrede dokument til HTML

    Endelig, da vi ændrede Dokument, vil vi måske tjekke vores arbejde.

    For at gøre dette kan vi udforske Dokument DOM-træ ved at vælge, gennemgå og udtrække ved hjælp af de præsenterede metoder, eller vi kan simpelthen udtrække dets HTML som en Snor bruger html () metode:

    Streng docHtml = doc.html ();

    Det Snor output er en pæn HTML.

    8. Konklusion

    Jsoup er et fantastisk bibliotek til at skrabe enhver side. Hvis du bruger Java og ikke kræver browserbaseret skrabning, er det et bibliotek, der skal tages i betragtning. Det er velkendt og let at bruge, da det bruger den viden, du måtte have om front-end-udvikling, og følger god praksis og designmønstre.

    Du kan lære mere om skrabning af websider med jsoup ved at studere jsoup API og læse jsoup-kogebogen.

    Kildekoden, der bruges i denne vejledning, kan findes i GitHub-projektet.