HTML parseren met PHP met DiDOM

Af en toe moeten ontwikkelaars webpagina's schrapen om wat informatie van een website te krijgen. Stel dat u bijvoorbeeld werkt aan een persoonlijk project waarbij u geografische informatie over de hoofdsteden van verschillende landen van Wikipedia moet krijgen. Dit handmatig invoeren kost veel tijd. Je kunt het echter heel snel doen door de Wikipedia-pagina met behulp van PHP te schrapen. U kunt de HTML ook automatisch ontleden om specifieke informatie te krijgen in plaats van de hele opmaak handmatig te doorlopen.

In deze zelfstudie leren we over een snelle, gemakkelijk te gebruiken HTML-parser genaamd DiDOM. We beginnen met het installatieproces en leren vervolgens informatie uit verschillende elementen op een webpagina extraheren met behulp van verschillende soorten selectors zoals tags, klassen, enz..

Installatie en gebruik

U kunt DiDOM eenvoudig in uw projectdirectory installeren door de volgende opdracht uit te voeren:

componist vereist imangazaliev / didom

Nadat u de bovenstaande opdracht hebt uitgevoerd, kunt u HTML laden van een tekenreeks, een lokaal bestand of een webpagina. Hier is een voorbeeld:

require_once (vendor / autoload.php); gebruik DiDom \ Document; $ document = nieuw document ($ washington_dc_html_string); $ document = nieuw document ('washington_dc.html', waar); $ url = 'https://en.wikipedia.org/wiki/Washington,_D.C.'; $ document = nieuw document ($ url, true);

Wanneer u besluit HTML van een document te ontleden, kan het al in een variabele worden geladen en opgeslagen. In dergelijke gevallen kunt u eenvoudig die variabele doorgeven aan Document() en DiDOM bereidt de tekenreeks voor op parseren.

Als de HTML van een bestand of een URL moet worden geladen, kunt u dat als eerste parameter doorgeven aan Document() en stel de tweede parameter in op waar.

U kunt ook een nieuw maken Document object met behulp van nieuw document() zonder parameters. In dit geval kunt u de methode bellen loadHtml () om HTML te laden van een string en loadHtmlFile () om HTML vanuit een bestand of webpagina te laden.

HTML-elementen zoeken

Het eerste dat je moet doen voordat je de HTML of tekst uit een element haalt, is het element zelf vinden. De eenvoudigste manier om dat te doen is eenvoudigweg het vind() methode en geef de CSS-selector door voor het bedoelde element als de eerste parameter.

U kunt de XPath ook doorgeven voor een element als de eerste parameter van de vind() methode. Dit vereist echter dat u slaagt Query :: TYPE_XPATH als de tweede parameter.

Als u alleen XPath-waarden wilt gebruiken voor het vinden van een HTML-element, kunt u eenvoudig de XPath () methode in plaats van passeren Query :: TYPE_XPATH als de tweede parameter voor vind() elke keer.

Als DiDOM elementen kan vinden die overeenkomen met de doorgegeven CSS-selector of XPATH-expressie, retourneert deze een reeks exemplaren van DiDom \ Element. Als dergelijke elementen niet worden gevonden, wordt een lege array geretourneerd.

Aangezien deze methoden een array retourneren, hebt u rechtstreeks toegang tot het nde overeenkomende element met behulp van vinden () [n-1].

Een voorbeeld

In het volgende voorbeeld krijgen we de innerlijke HTML van alle koppen van het eerste en tweede niveau in het Wikipedia-artikel over Washington, D.C..

require_once (vendor / autoload.php); gebruik DiDom \ Document; $ document = nieuw document ('https://en.wikipedia.org/wiki/Washington,_D.C.', true); $ main_heading = $ document-> find ('h1.firstHeading') [0]; echo $ main_heading-> html (); $ sub_headings = $ document-> find ('h2'); foreach ($ sub_headings als $ sub_heading) if ($ sub_heading-> text ()! == 'Zie ook') echo $ sub_heading-> html ();  else break; 

We beginnen met het maken van een nieuw Document-object door de URL van het Wikipedia-artikel over Washington, D.C. door te geven. Daarna krijgen we het hoofdkopelement met behulp van de vind() methode en sla het op in een variabele met de naam $ main_heading. We zullen nu verschillende methoden op dit element kunnen noemen zoals tekst(), innerHTML (), html (), enz.

Voor de hoofdkop bellen we gewoon de html () methode die de HTML van het volledige headingelement retourneert. Evenzo kunnen we de HTML binnen een bepaald element krijgen door de innerHTML () methode. Soms zul je meer geïnteresseerd zijn in de platte tekst van een element in plaats van de HTML. In dergelijke gevallen kunt u eenvoudig de tekst() methode en er klaar mee zijn.

De koppen op niveau twee verdelen onze Wikipedia-pagina in goed gedefinieerde secties. Het is echter mogelijk dat u enkele van die subkoppen zoals "Zie ook", "Aantekeningen", enz. Wilt verwijderen.

Een manier om dit te doen is om alle koppen van niveau twee door te lopen en de waarde te controleren die wordt geretourneerd door de tekst() methode. We doorbreken de lus als de geretourneerde koptekst "Zie ook" is.

Je zou direct op het vierde of zesde niveau twee kunnen komen door te gebruiken $ Document-> vinden ( 'h2') [3] en $ Document-> vinden ( 'h2') [5] respectievelijk.

Door de DOM heen en weer bewegen

Als u eenmaal toegang heeft tot een bepaald element, kunt u met de bibliotheek de DOM-tree op en neer gaan om met gemak toegang te krijgen tot andere elementen.

U kunt naar de ouder van een HTML-element gaan met behulp van de ouder() methode. Evenzo kunt u de volgende of vorige broer of zus van een element gebruiken met behulp van de nextSibling () en previousSibling () methoden.

Er zijn ook veel methoden beschikbaar om toegang te krijgen tot de kinderen van een DOM-element. U kunt bijvoorbeeld een bepaald onderliggende element gebruiken met behulp van de kind (n) methode. Op dezelfde manier kunt u toegang krijgen tot het eerste of laatste kind van een bepaald element met behulp van de eerstgeborene() en laatste kind() methoden. U kunt alle kinderen van een bepaald DOM-element doorlopen met behulp van de kinderen() methode.

Zodra u bij een bepaald element bent, heeft u toegang tot de HTML enz. Met behulp van de html (), innerHTML (), en tekst() methoden.

In het volgende voorbeeld beginnen we met elementelementen van niveau twee en blijven we controleren of het volgende broertje-element wat tekst bevat. Zodra we een broer of zus element met wat tekst vinden, sturen we het naar de browser.

require_once (vendor / autoload.php); gebruik DiDom \ Document; $ document = nieuw document ('https://en.wikipedia.org/wiki/Washington,_D.C.', true); $ sub_headings = $ document-> find ('h2'); voor ($ i = 1; $ i < count($sub_headings); $i++)  if($sub_headings[$i]->text ()! == 'Zie ook') $ next_sibling = $ sub_headings [$ i] -> nextSibling (); while (! $ next_elem-> html ()) $ next_sibling = $ next_sibling-> nextSibling ();  echo $ next_elem-> html (). "
"; else break;

U kunt een vergelijkbare techniek gebruiken om alle elementen van de broer of zus door te lussen en alleen de tekst uitvoeren als deze een bepaalde tekenreeks bevat of als het element van de broer of zus een alinea-tag is, enz. Als u eenmaal de basis kent, is het vinden van de juiste informatie eenvoudig.

Elementattributen manipuleren

De mogelijkheid om de kenmerkwaarde voor verschillende elementen te verkrijgen of in te stellen, kan in bepaalde situaties zeer nuttig zijn. We kunnen bijvoorbeeld de waarde van de src attribuut voor alle img tags in ons Wikipedia-artikel met behulp van $ Image_elem-> attr ( 'src'). Op dezelfde manier kun je de waarde van krijgen href attributen voor alle een tags in een document.

Er zijn drie manieren om de waarde van een bepaald kenmerk voor een HTML-element te krijgen. U kunt de getAttribute ( 'attrName') methode en geef de naam van het attribuut waarin u geïnteresseerd bent als parameter door. U kunt ook de attr ( 'attrName') methode, die net zo werkt getAttribute (). Ten slotte kunt u met de bibliotheek ook direct de kenmerkwaarde gebruiken $ Elem-> attrName. Dit betekent dat je de waarde van de kunt krijgen src attribuut voor een beeldelement direct met behulp van $ ImageElem-> src.

require_once (vendor / autoload.php); gebruik DiDom \ Document; $ document = nieuw document ('https://en.wikipedia.org/wiki/Washington,_D.C.', true); $ images = $ document-> find ('img'); foreach ($ images as $ image) echo $ image-> src. "
";

Zodra u toegang heeft tot de src attributen, kunt u de code schrijven om automatisch alle afbeeldingsbestanden te downloaden. Op deze manier kunt u veel tijd besparen.

U kunt ook de waarde van een gegeven kenmerk instellen met behulp van drie verschillende technieken. Ten eerste kunt u de setAttribute ('attrName', 'attrValue') methode om de attribuutwaarde in te stellen. U kunt ook de attr ('attrName', 'attrValue') methode om de attribuutwaarde in te stellen. Ten slotte kunt u de attribuutwaarde voor een bepaald element met behulp van $ Elem-> attrName = 'attrValue'.

Elementen toevoegen, verwijderen en vervangen

U kunt ook wijzigingen aanbrengen in het geladen HTML-document met behulp van verschillende methoden die door de bibliotheek worden aangeboden. U kunt bijvoorbeeld elementen toevoegen, vervangen of verwijderen uit de DOM-structuur met behulp van de appendChild (), vervangen(), en verwijderen() methoden.

Met de bibliotheek kunt u ook uw eigen HTML-elementen maken om ze aan het originele HTML-document toe te voegen. U kunt een nieuw Element-object maken met behulp van nieuw element ('tagName', 'tagContent').

Houd er rekening mee dat u een Niet-afgevangen fout: klasse 'Element' niet gevonden fout als uw programma de regel niet bevat gebruik DiDom \ Element voor het instantiëren van het elementobject.

Zodra u het element hebt, kunt u het toevoegen aan andere elementen in de DOM met behulp van de appendChild () methode of u kunt de vervangen() methode om het nieuw geïnstantieerde element te gebruiken als vervanging voor een oud HTML-element in het document. Het volgende voorbeeld moet helpen om dit concept verder te verduidelijken.

require_once (vendor / autoload.php); gebruik DiDom \ Document; gebruik DiDom \ Element; $ document = nieuw document ('https://en.wikipedia.org/wiki/Washington,_D.C.', true); // Dit zal resulteren in een fout. echo $ document-> find ('h2.test-heading') [0] -> html (). "\ n"; $ test_heading = nieuw element ('h2', 'Dit is testkop'.); $ test_heading-> class = 'test-heading'; $ Document-> vinden ( 'H1') [0] -> vervangen ($ test_heading); echo $ document-> find ('h2.test-heading') [0] -> html (). "\ n";

Aanvankelijk is er geen h2 element in ons document met de klas Test-titel. Daarom blijven we een foutmelding krijgen als we proberen toegang te krijgen tot een dergelijk element.

Nadat we hebben gecontroleerd dat er geen dergelijk element is, maken we een nieuw element h2 element en verander de waarde ervan klasse attribuut aan Test-titel.

Daarna vervangen we de eerste h1 element in het document met onze nieuw gecreëerde h2 element. De ... gebruiken vind() methode op ons document om de h2 rubriek met klasse Test-titel zal nu een element teruggeven.

Laatste gedachten

Deze tutorial behandelde de basisprincipes van de PHP DiDOM HTML-parser. We zijn begonnen met de installatie en hebben vervolgens geleerd hoe u HTML kunt laden uit een tekenreeks, bestand of URL. Daarna hebben we besproken hoe een bepaald element te vinden op basis van de CSS-selector of XPath. We hebben ook geleerd hoe we de broers en zussen, ouders of kinderen van een element kunnen krijgen. In de rest van de secties is besproken hoe we de kenmerken van een bepaald element kunnen manipuleren of elementen in een HTML-document kunnen toevoegen, verwijderen en vervangen.

.