PHP: Daten innerhalb von HTML Tags extrahieren

5 05 2012

Um an die Links in einem String zu gelangen, sieht man immer wieder abenteuerliche Regex http://de3.php.net/regex Konstrukte. Eines haben diese neben der schlechten Lesbarkeit häufig gemeinsam, nämlich dass sie nicht zuverlässig arbeiten. Statt also das Rad neu zu erfinden, sollte man hier besser auf die gegebenen Funktionen des Document Object Models zurück greifen.

Wir wollen also aus einem Text alle Werte in <a href=“http://www.example.org/„> heraus filtern. Zu beachten ist, dass damit keine unverlinkten URLs gesucht werden, sondern nur der Inhalt innerhalb des href=“…“

<?php

$text = 'Lorem ipsum dolor sit amet, consetetur http://example.org sadipscing 
elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, sed diam voluptua. At <a 
href="http://suchen.mobile.de/auto/search.html?scopeId=C&isSearchRequest=true&sortOption.sortBy=price.consumerGrossEuro">vero</a> 
eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no 
sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, 
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et 
dolore magna aliquyam erat, sed diam voluptua. <a 
href="http://www.example.com#link">www.example.net</a>At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea 
takimata sanctus est Lorem ipsum dolor sit amet.';

// Erzeuge ein neues DOM Dokument
$dom = new DOMDocument();
// Keine Fehlerpruefung erzwingen
$dom->strictErrorChecking = false;
// Den String einlesen
@$dom->loadHTML($text);
// Die Links innerhalb des <a ...> Tags suchen
$links = $dom->getElementsByTagName('a');
// Fuer alle gefundenen Links
foreach($links as $link) {
	// Wenn der a Tag ein Attribut href hat...
	if ($link->hasAttribute('href')) {
		// ...den Inhalt auslesen
		$href = $link->getAttribute('href');
		// Bildschirmausgabe
		echo $href.'<br />';
   }
}

Die Ausgabe liefert uns beide Links:
http://suchen.mobile.de/auto/search.html?scopeId=C&isSearchRequest=true&sortOption.sortBy=price.consumerGrossEuro
http://www.example.com#link

Mittels XPath kann man auch innerhalb beliebiger Tags nach Inhalten suchen. Nehmen wir an, wir möchten alle Texte innerhalb der <td>…</td> Tags von Tabellen. Das Beispiel entsprechend angepasst:

<?php

$text = 'Lorem ipsum dolor sit amet, consetetur http://example.org sadipscing 
elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, sed diam voluptua. At <a 
href="http://suchen.mobile.de/auto/search.html?scopeId=C&isSearchRequest=true&sortOption.sortBy=price.consumerGrossEuro">vero</a> 
eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no 
sea takimata sanctus est Lorem ipsum dolor sit amet. 
<table>
<thead>
<tr><th>Kopf</th></tr>
</thead>
<tbody>
<tr><td>Zeile 1</td></tr>
<tr><td>Zeile 2</td></tr>
<tr><td>Zeile 3</td></tr>
</tbody>
</table>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. 
<a href="http://www.example.com#link">www.example.net</a>At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea 
takimata sanctus est Lorem ipsum dolor sit amet.';

$dom = new DOMDocument();
$dom->strictErrorChecking = false;
@$dom->loadHTML($text);
// XPath erzeugen
$xpath = new DOMXPath($dom);
// Der Pfad zu unseren gewuenschten Inhalten: table -> tbody -> tr -> td
// Würden wir den Wert eines Attributs suche, müssten wir dieses mit @ kennzeichnen
// Beispiel: $xpath->query('//a/@href');
$inhalte = $xpath->query('//table/tbody/tr/td');
foreach($inhalte as $inhalt) {
    echo $inhalt->nodeValue.'<br />';
}

Als Ausgabe erhalten wir:

Zeile 1
Zeile 2
Zeile 3
Advertisements

Aktionen

Information

3 responses

20 04 2013
Einer der nur ein Komentar abgeben will

Sehr gut, genau so was habe ich gesucht, da Regex wirklich nicht immer so toll für diese Funktion ist.

13 04 2017
Manfred

Um Daten aus einer HTML-Seite zu extrahieren gibts im PHP-Framework rexo einen flexiblen Befehl: http://spam.ch/?pg=docu&m=func&pag=url

24 04 2017
aaaaaprvdgrwwelt

Dafür gibt es sicherlich in so ziemlich jedem Framework Befehle. Was mir nach kurzer Recherche an Rexo aufgefallen ist, wäre neben dem grausamen Quellcode die Tatsache, dass sehr häufig als Frage oder Hinweis getarnte Kommentare zu irgendwelchen Artikeln zu finden sind, die immer auf Rexo linken. Deshalb ist dein Link hier raus, du elendiger Spammer!

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s




%d Bloggern gefällt das: