Analysera HTML med PHP med DiDOM

Nu och då måste utvecklarna skrapa webbsidor för att få lite information från en webbplats. Låt oss till exempel säga att du arbetar med ett personligt projekt där du måste få geografisk information om huvudstäderna i olika länder från Wikipedia. Om du skriver in manuellt skulle det ta mycket tid. Du kan dock göra det väldigt snabbt genom att skrapa Wikipedia-sidan med hjälp av PHP. Du kan även automatiskt analysera HTML-koden för att få specifik information istället för att gå igenom hela markeringen manuellt.

I denna handledning lär vi oss om en snabb, lättanvänd HTML-parser som heter DiDOM. Vi kommer att börja med installationsprocessen och sedan lära dig att extrahera information från olika element på en webbsida med olika typer av selektörer som taggar, klasser etc..

Installation och användning

Du kan enkelt installera DiDOM i din projektkatalog genom att köra följande kommando:

kompositör kräver imangazaliev / didom

När du har kört ovanstående kommando kan du ladda HTML från en sträng, en lokal fil eller en webbsida. Här är ett exempel:

require_once ( 'säljaren / autoload.php'); använd DiDom \ Document; $ document = nytt dokument ($ washington_dc_html_string); $ document = nytt dokument ('washington_dc.html', true); $ url = 'https://en.wikipedia.org/wiki/Washington,_D.C.'; $ document = nytt dokument ($ url, true);

När du bestämmer dig för att analysera HTML från ett dokument, kan det redan laddas och lagras i en variabel. I sådana fall kan du enkelt överföra den variabeln till Dokumentera() och DiDOM kommer att förbereda strängen för analysering.

Om HTML måste laddas från en fil eller en URL kan du skicka den som den första parametern till Dokumentera() och ställ in den andra parametern till Sann.

Du kan också skapa en ny Dokumentera objekt genom att använda nytt dokument () utan några parametrar. I det här fallet kan du ringa metoden loadHtml () att ladda HTML från en sträng och loadHtmlFile () att ladda HTML från en fil eller webbsida.

Hitta HTML-element

Det första du behöver göra innan du får HTML eller text från ett element är att hitta själva elementet. Det enklaste sättet att göra det är att helt enkelt använda hitta() metod och passera CSS-väljaren för ditt avsedda element som den första parametern.

Du kan också skicka XPath till ett element som den första parametern för hitta() metod. Detta kräver dock att du ska passera Query :: TYPE_XPATH som den andra parametern.

Om du bara vill använda XPath-värden för att hitta ett HTML-element, kan du helt enkelt använda xpath () metod istället för att passera Query :: TYPE_XPATH som den andra parametern till hitta() varje gång.

Om DiDOM kan hitta element som matchar det passerade CSS-väljaren eller XPATH-uttrycket, returnerar det en rad instanser av DiDom \ Element. Om inga sådana element hittas kommer det att returnera en tom array.

Eftersom dessa metoder returnerar en matris kan du direkt komma åt det nth matchande elementet med hjälp av hitta () [n-1].

Ett exempel

I det följande exemplet kommer vi att få den inre HTML-filen från alla första och andra nivåns rubriker i Wikipedia-artikeln om Washington, D.C.

require_once ( 'säljaren / autoload.php'); använd DiDom \ Document; $ document = new 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 som $ sub_heading) om ($ sub_heading-> text ()! == 'Se också') echo $ sub_heading-> html ();  annars break; 

Vi börjar med att skapa ett nytt dokumentobjekt genom att skicka URL-adressen till Wikipedia-artikeln om Washington, D.C. Efter det får vi huvudrubrikelementet med hjälp av hitta() metod och lagra den inuti en variabel som heter $ main_heading. Vi kommer nu att kunna kalla olika metoder på detta element som text(), innerhtml (), html(), etc.

För huvudrubriken kallar vi bara html() metod som returnerar HTML för hela rubrikelementet. På samma sätt kan vi hämta HTML inuti ett visst element genom att använda innerhtml () metod. Ibland kommer du att vara mer intresserad av innehållet i en vanlig text i stället för dess HTML. I sådana fall kan du helt enkelt använda text() metod och görs med det.

Nivå två rubriker dela upp vår Wikipedia-sida i väldefinierade avsnitt. Men du kanske vill bli av med några av de underrubriker som "Se även", "Anteckningar", etc..

Ett sätt att göra det skulle vara att gå igenom alla nivå två rubriker och kontrollera det värde som returneras av text() metod. Vi bryter ut ur slingan om den returtexten är "Se även".

Du kan direkt komma till 4: e eller 6: e nivå två rubriken genom att använda $ Dokument-> hitta ( 'h2') [3] och $ Dokument-> hitta ( 'h2') [5] respektive.

Traversera upp och ner DOM

När du har tillgång till ett visst element tillåter biblioteket dig att korsa upp och ner DOM-trädet för att enkelt komma åt andra element.

Du kan gå till förälder till ett HTML-element med hjälp av förälder() metod. På samma sätt kan du komma till nästa eller föregående syskon av ett element med hjälp av nextSibling () och previousSibling () metoder.

Det finns många sätt att få tillgång till barnen till ett DOM-element också. Till exempel kan du komma till ett visst barnelement med hjälp av barn (n) metod. På samma sätt kan du få tillgång till det första eller sista barnet av ett visst element med hjälp av förstfödde() och sista barnet() metoder. Du kan slinga över alla barn i ett visst DOM-element med hjälp av barn() metod.

När du väl har tagit ett visst element kommer du kunna få tillgång till dess HTML etc. med hjälp av html(), innerhtml (), och text() metoder.

I följande exempel börjar vi med nivå två rubrikelement och fortsätt kontrollera om nästa syskonelement innehåller lite text. Så snart vi hittar ett syskonelement med lite text, skickar vi den till webbläsaren.

require_once ( 'säljaren / autoload.php'); använd DiDom \ Document; $ document = new Document ('https://en.wikipedia.org/wiki/Washington,_D.C.', true); $ sub_headings = $ document-> find ('h2'); för ($ i = 1; $ i < count($sub_headings); $i++)  if($sub_headings[$i]->text ()! == 'Se också') $ next_sibling = $ sub_headings [$ i] -> nextSibling (); medan (! $ next_elem-> html ()) $ next_sibling = $ next_sibling-> nextSibling ();  echo $ next_elem-> html (). "
"; else break;

Du kan använda en liknande teknik för att slinga igenom alla syskonelementen och bara skriva ut texten om den innehåller en viss sträng eller om syskonelementet är en stycke-etikett etc. När du väl vet grunderna är det lätt att hitta rätt information.

Manipulera Element Attribut

Möjligheten att få eller ange attributvärdet för olika element kan vara mycket användbart i vissa situationer. Till exempel kan vi få värdet av src attribut för alla img taggar i vår Wikipedia artikel med hjälp av $ Image_elem-> attr (src). På ett liknande sätt kan du få värdet av href attribut för alla en taggar i ett dokument.

Det finns tre sätt att få värdet av ett givet attribut för ett HTML-element. Du kan använda getAttribute ( 'attrName') metod och ge namnet på attributet du är intresserad av som en parameter. Du kan också använda attr ( 'attrName') metod som fungerar precis som getAttribute (). Slutligen tillåter biblioteket dig direkt att få attributvärdet med $ Elem-> attrName. Det betyder att du kan få värdet av src attribut för ett bildelement direkt genom att använda $ ImageElem-> src.

require_once ( 'säljaren / autoload.php'); använd DiDom \ Document; $ document = new Document ('https://en.wikipedia.org/wiki/Washington,_D.C.', true); $ images = $ document-> find ('img'); foreach ($ bilder som $ bild) echo $ image-> src. "
";

När du har tillgång till src attribut kan du skriva koden för att automatiskt ladda ner alla bildfiler. På så sätt kan du spara mycket tid.

Du kan också ange värdet för ett givet attribut med tre olika tekniker. Först kan du använda setAttribute ('attrName', 'attrValue') metod för att ange attributvärdet. Du kan också använda attr ('attrName', 'attrValue') metod för att ange attributvärdet. Slutligen kan du ange attributvärdet för ett givet element med $ Elem-> attrName = 'attrValue'.

Lägga till, ta bort och byta ut element

Du kan också göra ändringar i det laddade HTML-dokumentet med hjälp av olika metoder som tillhandahålls av biblioteket. Till exempel kan du lägga till, ersätta eller ta bort element från DOM-trädet med hjälp av appendChild (), byta ut(), och ta bort() metoder.

Biblioteket tillåter dig också att skapa egna HTML-element för att lägga till dem i det ursprungliga HTML-dokumentet. Du kan skapa ett nytt elementobjekt med hjälp av nytt element ('tagName', 'tagContent').

Tänk på att du får en Uncaught Error: Klass "Element" hittades inte fel om ditt program inte innehåller raden använd DiDom \ Element före instantiating elementobjektet.

När du har elementet kan du antingen lägga till det på andra element i DOM med hjälp av appendChild () metod eller du kan använda byta ut() metod för att använda det nyligen instantierade elementet som ersättning för något gammalt HTML-element i dokumentet. Följande exempel borde bidra till att ytterligare förtydliga detta begrepp.

require_once ( 'säljaren / autoload.php'); använd DiDom \ Document; använd DiDom \ Element; $ document = new Document ('https://en.wikipedia.org/wiki/Washington,_D.C.', true); // Detta kommer att resultera i fel. echo $ document-> find ('h2.test-heading') [0] -> html (). "\ n"; $ test_heading = nytt element ('h2', 'Detta är testrubrik.'); $ test_heading-> class = 'test-heading'; $ Dokument-> hitta ( 'h1') [0] -> byt ($ test_heading); echo $ document-> find ('h2.test-heading') [0] -> html (). "\ n";

Ursprungligen finns det ingen h2 element i vårt dokument med klassen testet rubrik. Därför kommer vi fortsätta att få ett fel om vi försöker komma åt ett sådant element.

Efter att ha verifierat att det inte finns något sådant, skapar vi en ny h2 element och ändra värdet av dess klass tillskriva testet rubrik.

Därefter byter vi ut den första h1 element i dokumentet med vår nyskapade h2 element. Använda hitta() metod på vårt dokument igen för att hitta h2 på väg med klassen testet rubrik kommer att returnera ett element nu.

Slutgiltiga tankar

Denna handledning omfattade grunderna i PHP DiDOM HTML parser. Vi började med installationen och lärde oss då att ladda HTML från en sträng, fil eller URL. Därefter diskuterade vi hur man hitta ett visst element baserat på CSS-väljaren eller XPath. Vi lärde oss också hur vi ska få syskon, förälder eller barn av ett element. Resten av avsnitten omfattade hur vi kan manipulera attributen till ett visst element eller lägga till, ta bort och ersätta element i ett HTML-dokument.

.