Wie kann man HTML/XML analysieren und daraus Informationen extrahieren?
Ich bevorzuge die Verwendung einer der native XML-Erweiterungen , da sie mit PHP gebündelt geliefert werden, normalerweise schneller sind als alle Bibliotheken von Drittanbietern und mir die gesamte Kontrolle über das Markup geben, die ich benötige.
Mit der DOM-Erweiterung können Sie XML-Dokumente über die DOM-API mit PHP bearbeiten. 5. Dies ist eine Implementierung des Document Object Model Core Level 3 des W3C, einer plattform- und sprachneutralen Schnittstelle, die Programme und unterstützt Skripte, um dynamisch auf den Inhalt, die Struktur und den Stil von Dokumenten zuzugreifen und diese zu aktualisieren.
DOM ist in der Lage, reales HTML (kaputt) zu analysieren und zu modifizieren und kann XPath-Abfragen . Es basiert auf libxml .
Es dauert einige Zeit, um mit DOM produktiv zu werden, aber diese Zeit lohnt sich auf jeden Fall, IMO. Da DOM eine sprachunabhängige Benutzeroberfläche ist, finden Sie Implementierungen in vielen Sprachen. Wenn Sie also Ihre Programmiersprache ändern müssen, wissen Sie wahrscheinlich bereits, wie Sie die DOM-API dieser Sprache verwenden.
Ein grundlegendes Anwendungsbeispiel finden Sie in Ergreifen des href-Attributs eines A-Elements und eine allgemeine konzeptionelle Übersicht finden Sie unter DOMDocument in php
Die Verwendung der DOM-Erweiterung wurde in StackOverflow ausführlich behandelt . Wenn Sie sich also für die Verwendung entscheiden, können Sie sicher sein, dass die meisten Probleme, auf die Sie stoßen, durch Suchen/Durchsuchen von Stack Overflow gelöst werden können.
Die XMLReader-Erweiterung ist ein XML-Pull-Parser. Der Leser fungiert als Cursor, der auf dem Dokumentenstrom vorwärts fährt und auf dem Weg an jedem Knoten anhält.
XMLReader basiert wie DOM auf libxml. Mir ist nicht bekannt, wie das HTML-Parser-Modul ausgelöst werden soll. Daher ist die Verwendung von XMLReader zum Parsen von fehlerhaftem HTML möglicherweise weniger robust als die Verwendung von DOM, wenn Sie ausdrücklich die Verwendung des HTML-Parser-Moduls von libxml anweisen können.
Ein grundlegendes Anwendungsbeispiel finden Sie unter Abrufen aller Werte von h1-Tags mit php
Mit dieser Erweiterung können Sie XML-Parser erstellen und anschließend Handler für verschiedene XML-Ereignisse definieren. Jeder XML-Parser verfügt auch über einige Parameter, die Sie anpassen können.
Die XML-Parser-Bibliothek basiert ebenfalls auf libxml und implementiert einen XML-Push-Parser im Stil SAX . Es ist möglicherweise eine bessere Wahl für die Speicherverwaltung als DOM oder SimpleXML, es ist jedoch schwieriger zu handhaben als der von XMLReader implementierte Pull-Parser.
Die SimpleXML-Erweiterung bietet ein sehr einfaches und einfach zu verwendendes Toolset zum Konvertieren von XML in ein Objekt, das mit normalen Eigenschaftenselektoren und Array-Iteratoren verarbeitet werden kann.
SimpleXML ist eine Option, wenn Sie wissen, dass HTML gültiges XHTML ist. Wenn Sie defektes HTML analysieren müssen, sollten Sie SimpleXml nicht einmal in Betracht ziehen, da es ersticken wird.
Ein grundlegendes Anwendungsbeispiel finden Sie unter Ein einfaches Programm zum CRUD-Knoten und Knotenwerte der XML-Datei und es gibt viele zusätzliche Beispiele im PHP Manual =.
Wenn Sie es vorziehen, eine 3rd-Party-Bibliothek zu verwenden, würde ich vorschlagen, eine Bibliothek zu verwenden, die tatsächlich DOM / libxml darunter anstelle von String-Analyse verwendet.
FluentDOM bietet eine jQuery-ähnliche, flüssige XML-Schnittstelle für das DOMDocument in PHP. Selektoren sind in XPath oder CSS geschrieben (unter Verwendung eines CSS-zu-XPath-Konverters). Aktuelle Versionen erweitern das DOM, indem sie Standardschnittstellen implementieren, und fügen Funktionen aus dem DOM Living Standard hinzu. FluentDOM kann Formate wie JSON, CSV, JsonML, RabbitFish und andere laden. Kann über Composer installiert werden.
Wa72\HtmlPageDom` ist eine PHP Bibliothek zur einfachen Bearbeitung von HTML-Dokumenten mit Hilfe von DomCrawler von Symfony2-Komponenten zum Durchlaufen des DOM-Baums und zur Erweiterung um Methoden zur Bearbeitung des DOM-Baums von HTML-Dokumenten.
phpQuery ist eine serverseitige, verkettbare, CSS3-selektorgesteuerte Document Object Model (DOM) -API, die auf der in PHP5 geschriebenen jQuery-JavaScript-Bibliothek basiert und eine zusätzliche Befehlszeilenschnittstelle (Command Line Interface, CLI) bietet.
Siehe auch: https://github.com/electrolinux/phpquery
Zend_Dom bietet Werkzeuge zum Arbeiten mit DOM Dokumenten und Strukturen. Derzeit bieten wir Zend_Dom_Query an, das eine einheitliche Schnittstelle zum Abfragen von DOM-Dokumenten unter Verwendung von XPath- und CSS-Selektoren bietet.
QueryPath ist eine PHP Bibliothek zur Bearbeitung von XML und HTML. Es kann nicht nur mit lokalen Dateien, sondern auch mit Webdiensten und Datenbankressourcen verwendet werden. Es implementiert einen Großteil der jQuery-Oberfläche (einschließlich CSS-artiger Selektoren), ist jedoch stark auf die serverseitige Verwendung abgestimmt. Kann über Composer installiert werden.
fDOMDocument erweitert das Standard-DOM so, dass Ausnahmen bei Fehlern anstelle von PHP Warnungen oder Hinweisen verwendet werden. Sie fügen außerdem verschiedene benutzerdefinierte Methoden und Verknüpfungen hinzu, um die Verwendung von DOM zu vereinfachen.
sabre/xml ist eine Bibliothek, die die Klassen XMLReader und XMLWriter umschließt und erweitert, um ein einfaches Zuordnungssystem und Entwurfsmuster "xml to object/array" zu erstellen. Das Schreiben und Lesen von XML erfolgt in einem Durchgang und kann daher schnell sein und bei großen XML-Dateien nur wenig Speicherplatz beanspruchen.
FluidXML ist eine PHP Bibliothek zum Bearbeiten von XML mit einer übersichtlichen und fließenden API. Es nutzt XPath und das flüssige Programmiermuster, um Spaß zu machen und effektiv zu sein.
Der Vorteil, auf DOM/libxml aufzubauen, besteht darin, dass Sie sofort eine gute Leistung erzielen, da Sie auf einer nativen Erweiterung basieren. Allerdings gehen nicht alle Bibliotheken von Drittanbietern diesen Weg. Einige von ihnen unten aufgeführt
- Mit einem in PHP5 + geschriebenen HTML-DOM-Parser können Sie HTML auf sehr einfache Weise bearbeiten!
- Benötige PHP 5+.
- Unterstützt ungültiges HTML.
- Suchen Sie Tags auf einer HTML-Seite mit Selektoren wie jQuery.
- Extrahieren Sie Inhalte aus HTML in einer einzigen Zeile.
Ich empfehle diesen Parser im Allgemeinen nicht. Die Codebasis ist schrecklich und der Parser selbst ist ziemlich langsam und speicherhungrig. Nicht alle jQuery-Selektoren (wie ntergeordnete Selektoren ) sind möglich. Jede der libxml-basierten Bibliotheken sollte dies problemlos übertreffen.
PHPHtmlParser ist ein einfacher, flexibler HTML-Parser, mit dem Sie Tags mithilfe eines beliebigen CSS-Selektors wie jQuery auswählen können. Ziel ist es, bei der Entwicklung von Tools behilflich zu sein, die eine schnelle und einfache Möglichkeit zum Verschrotten von HTML erfordern, unabhängig davon, ob sie gültig sind oder nicht! Dieses Projekt wurde ursprünglich von sunra/php-simple-html-dom-parser unterstützt, aber die Unterstützung scheint aufgehört zu haben, so dass dieses Projekt meine Adaption seiner früheren Arbeit ist.
Auch hier würde ich diesen Parser nicht empfehlen. Es ist ziemlich langsam mit hoher CPU-Auslastung. Es gibt auch keine Funktion zum Löschen des Speichers von erstellten DOM-Objekten. Diese Probleme lassen sich besonders bei verschachtelten Schleifen skalieren. Die Dokumentation selbst ist ungenau und falsch geschrieben. Seit dem 14. April 16 gibt es keine Antworten auf Fehlerbehebungen.
- Ein universeller Tokenizer und HTML/XML/RSS DOM Parser
- Fähigkeit, Elemente und deren Attribute zu manipulieren
- Unterstützt ungültiges HTML und UTF8
- Kann erweiterte CSS3-ähnliche Abfragen für Elemente ausführen (z. B. jQuery - Namespaces werden unterstützt)
- Ein HTML-Verschönerer (wie HTML Tidy)
- Reduzieren Sie CSS und Javascript
- Attribute sortieren, Groß- und Kleinschreibung ändern, Einrückung korrigieren usw.
- Erweiterbar
- Analysieren von Dokumenten mithilfe von Rückrufen basierend auf dem aktuellen Zeichen/Token
- Operationen sind in kleinere Funktionen unterteilt, um das Überschreiben zu vereinfachen
- Schnell und einfach
Ich habe es nie benutzt. Kann nicht sagen, ob es gut ist.
Sie können das Obige zum Parsen von HTML5 verwenden, aber es kann Macken geben aufgrund des Markups, das HTML5 zulässt. Daher möchten Sie für HTML5 die Verwendung eines dedizierten Parsers in Betracht ziehen, z
Eine Python und PHP Implementierung eines HTML-Parsers basierend auf der WHATWG HTML5-Spezifikation für maximale Kompatibilität mit den wichtigsten Desktop-Webbrowsern.
Möglicherweise werden nach Abschluss von HTML5 mehr dedizierte Parser angezeigt. Es gibt auch einen Blogpost des W3 mit dem Titel How-To for html 5 parsing , der einen Blick wert ist.
Wenn Sie keine Lust haben, PHP zu programmieren, können Sie auch Webdienste verwenden. Im Allgemeinen fand ich sehr wenig Nutzen für diese, aber das ist nur ich und meine Anwendungsfälle.
Über die externe Oberfläche von ScraperWiki können Sie Daten in der gewünschten Form für die Verwendung im Web oder in Ihren eigenen Anwendungen extrahieren. Sie können auch Informationen über den Zustand eines beliebigen Abstreifers extrahieren.
Last and least recommended , können Sie mit regulären Ausdrücken Daten aus HTML extrahieren. Im Allgemeinen wird davon abgeraten, reguläre Ausdrücke in HTML zu verwenden.
Die meisten Schnipsel, die Sie im Web finden, um mit Markups übereinzustimmen, sind spröde. In den meisten Fällen funktionieren sie nur für ein bestimmtes Stück HTML. Winzige Markup-Änderungen, wie das Hinzufügen von Leerzeichen oder das Hinzufügen oder Ändern von Attributen in einem Tag, können dazu führen, dass der RegEx fehlschlägt, wenn er nicht richtig geschrieben ist. Sie sollten wissen, was Sie tun, bevor Sie RegEx für HTML verwenden.
HTML-Parser kennen die syntaktischen Regeln von HTML bereits. Für jede neue RegEx, die Sie schreiben, müssen reguläre Ausdrücke gelernt werden. RegEx sind in einigen Fällen in Ordnung, aber es hängt wirklich von Ihrem Anwendungsfall ab.
Sie können zuverlässigere Parser schreiben , aber das Schreiben eines vollständigen und zuverlässigen benutzerdefinierten Parsers mit regulären Ausdrücken ist Zeitverschwendung, wenn die oben genannten Bibliotheken bereits existieren und existieren ein viel besserer Job auf diesem.
Siehe auch Parsing Html The Cthulhu Way
Wenn Sie etwas Geld ausgeben möchten, werfen Sie einen Blick auf
Ich bin nicht mit PHP Architect oder den Autoren verbunden.
Versuchen Sie Simple HTML DOM Parser
// Create DOM from URL or file
$html = file_get_html('http://www.example.com/');
// Find all images
foreach($html->find('img') as $element)
echo $element->src . '<br>';
// Find all links
foreach($html->find('a') as $element)
echo $element->href . '<br>';
// Create DOM from string
$html = str_get_html('<div id="hello">Hello</div><div id="world">World</div>');
$html->find('div', 1)->class = 'bar';
$html->find('div[id=hello]', 0)->innertext = 'foo';
echo $html;
// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;
// Create DOM from URL
$html = file_get_html('http://slashdot.org/');
// Find all article blocks
foreach($html->find('div.article') as $article) {
$item['title'] = $article->find('div.title', 0)->plaintext;
$item['intro'] = $article->find('div.intro', 0)->plaintext;
$item['details'] = $article->find('div.details', 0)->plaintext;
$articles[] = $item;
}
print_r($articles);
Verwenden Sie einfach DOMDocument-> loadHTML () und fertig. Der HTML-Parsing-Algorithmus von libxml ist recht gut und schnell und verschluckt im Gegensatz zur landläufigen Meinung kein fehlerhaftes HTML.
Warum sollten Sie nicht und wann sollten Sie reguläre Ausdrücke verwenden?
Erstens eine häufige Fehlbezeichnung: Regexps sind nicht für " Parsing " HTML. Regexe können jedoch "" Daten extrahieren. Extrahieren ist das, wofür sie gemacht sind. Der Hauptnachteil der regex-HTML-Extraktion gegenüber geeigneten SGML-Toolkits oder XML-Grundparsern ist ihr syntaktischer Aufwand und ihre unterschiedliche Zuverlässigkeit.
Beachten Sie, dass Sie einen etwas verlässlichen regulären HTML-Extraktions-Ausdruck erstellen:
<a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
ist weitaus weniger lesbar als ein einfaches phpQuery- oder QueryPath-Äquivalent:
$div->find(".stationcool a")->attr("title");
Es gibt jedoch spezielle Anwendungsfälle, bei denen sie helfen können.
<!--
an, die jedoch manchmal die nützlicheren Anker für die Extraktion sind. Insbesondere Pseudo-HTML-Variationen <$var>
oder SGML-Reste lassen sich leicht mit regulären Ausdrücken zähmen.Manchmal ist es sogar ratsam, ein HTML-Snippet mit regulären Ausdrücken /<!--CONTENT-->(.+?)<!--END-->/
vorab zu extrahieren und den Rest mit den einfacheren HTML-Parser-Frontends zu verarbeiten.
Hinweis: Ich habe tatsächlich diese App , bei der ich alternativ XML-Parsing und reguläre Ausdrücke verwende. Erst letzte Woche brach das PyQuery-Parsing ab und der reguläre Ausdruck funktionierte immer noch. Ja komisch, und ich kann es mir nicht erklären. Aber so ist es passiert.
Also bitte stimmen Sie die realen Überlegungen nicht ab, nur weil sie nicht mit dem Regex = böse Mem übereinstimmen. Aber lassen Sie uns auch nicht zu viel darüber abstimmen. Es ist nur eine Randnotiz für dieses Thema.
phpQuery und QueryPath sind sich beim Replizieren der flüssigen jQuery-API sehr ähnlich. Das ist auch der Grund, warum sie zwei der einfachsten Methoden sind, umrichtigHTML in PHP zu analysieren.
Beispiele für QueryPath
Grundsätzlich erstellen Sie zunächst einen abfragbaren DOM-Baum aus einer HTML-Zeichenfolge:
$qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL
Das resultierende Objekt enthält eine vollständige Baumdarstellung des HTML-Dokuments. Es kann mit DOM-Methoden durchlaufen werden. Der übliche Ansatz ist jedoch die Verwendung von CSS-Selektoren wie in jQuery:
$qp->find("div.classname")->children()->...;
foreach ($qp->find("p img") as $img) {
print qp($img)->attr("src");
}
Meistens möchten Sie einfache #id
und .class
oder DIV
Tag-Selektoren für ->find()
verwenden. Sie können aber auch XPath Anweisungen verwenden, die manchmal schneller sind. Auch typische jQuery-Methoden wie ->children()
und ->text()
und insbesondere ->attr()
vereinfachen das Extrahieren der richtigen HTML-Schnipsel. (Und haben bereits ihre SGML-Entitäten dekodiert.)
$qp->xpath("//div/p[1]"); // get first paragraph in a div
Mit QueryPath können Sie auch neue Tags in den Stream einfügen (->append
) und später ein aktualisiertes Dokument ausgeben und verschönern (->writeHTML
). Es kann nicht nur fehlerhaftes HTML, sondern auch verschiedene XML-Dialekte (mit Namespaces) analysieren und sogar Daten aus HTML-Mikroformaten (XFN, vCard) extrahieren.
$qp->find("a[target=_blank]")->toggleClass("usability-blunder");
.
phpQuery oder QueryPath?
Im Allgemeinen eignet sich QueryPath besser zur Bearbeitung von Dokumenten. Während phpQuery auch einige Pseudo-AJAX -Methoden implementiert (nur HTTP-Anforderungen), um jQuery näher zu kommen. Es wird gesagt, dass phpQuery oft schneller als QueryPath ist (wegen der geringeren Gesamtfeatures).
Weitere Informationen zu den Unterschieden finden Sie unter dieser Vergleich auf der Wayback-Maschine von tagbyte.org . (Die ursprüngliche Quelle ist verschwunden. Hier ist also ein Link zum Internetarchiv. Ja, Sie können immer noch fehlende Seiten und Personen finden.)
Und hier ist eine umfassende QueryPath-Einführung .
Vorteile
->find("a img, a object, div a")
Simple HTML DOM ist ein großartiger Open-Source-Parser:
DOM-Elemente werden objektorientiert behandelt, und die neue Iteration deckt häufig nicht kompatiblen Code ab. Es gibt auch einige großartige Funktionen, wie Sie sie in JavaScript sehen würden, wie zum Beispiel die "find" -Funktion, die alle Instanzen von Elementen dieses Tag-Namens zurückgibt.
Ich habe dies in einer Reihe von Tools verwendet und es auf vielen verschiedenen Arten von Webseiten getestet, und ich denke, es funktioniert großartig.
Ein allgemeiner Ansatz, den ich hier nicht gesehen habe, ist das Ausführen von HTML durch Tidy , das so eingestellt werden kann, dass garantiert gültiges XHTML ausgespuckt wird. Dann können Sie eine beliebige alte XML-Bibliothek verwenden.
Aber für Ihr spezielles Problem sollten Sie sich dieses Projekt ansehen: http://fivefilters.org/content-only/ - Es ist eine modifizierte Version von Readability Algorithmus, mit dem nur der Textinhalt (nicht Kopf- und Fußzeilen) einer Seite extrahiert wird.
Zu 1a und 2: Ich würde für die neue Symfony Componet-Klasse DOMCrawler stimmen ( DomCrawler ). Diese Klasse ermöglicht Abfragen, die CSS-Selektoren ähneln. Schauen Sie sich diese Präsentation an, um Beispiele aus der Praxis zu sehen: news-of-the-symfony2-world .
Die Komponente ist eigenständig und kann ohne Symfony verwendet werden.
Der einzige Nachteil ist, dass es nur mit PHP 5.3 oder neuer funktioniert.
Dies wird im Allgemeinen als Screen Scraping bezeichnet. Die Bibliothek, die ich dafür verwendet habe, ist Simple HTML Dom Parser .
Wir haben schon einige Crawler für unsere Bedürfnisse erstellt. Letztendlich sind es meist einfache reguläre Ausdrücke, die das Beste ausmachen. Die oben aufgelisteten Bibliotheken sind zwar gut für den Grund, warum sie erstellt wurden. Wenn Sie jedoch wissen, wonach Sie suchen, sind reguläre Ausdrücke ein sicherer Weg, da Sie auch ungültige HTML /verarbeiten können. XHTML Strukturen, die fehlschlagen würden, wenn sie über die meisten Parser geladen würden.
Ich empfehle PHP Simple HTML DOM Parser .
Es hat wirklich nette Funktionen, wie:
foreach($html->find('img') as $element)
echo $element->src . '<br>';
Dies klingt nach einer guten Aufgabenbeschreibung der W3C XPath -Technologie. Es ist einfach, Abfragen wie "Alle href
Attribute in img
Tags zurückgeben, die in <foo><bar><baz> elements
verschachtelt sind." Da ich kein PHP-Fan bin, kann ich Ihnen nicht sagen, in welcher Form XPath verfügbar ist. Wenn Sie ein externes Programm zum Verarbeiten der HTML-Datei aufrufen können, sollten Sie eine Befehlszeilenversion von XPath verwenden können. Eine kurze Einführung finden Sie unter http://en.wikipedia.org/wiki/XPath .
Ja, Sie können simple_html_dom für diesen Zweck verwenden. Ich habe jedoch ziemlich viel mit der simple_html_dom gearbeitet, insbesondere beim Web-Scrapping, und fand sie zu anfällig. Es macht die grundlegende Arbeit, aber ich werde es sowieso nicht empfehlen.
Ich habe Curl nie für diesen Zweck verwendet, aber was ich gelernt habe, ist, dass Curl die Arbeit viel effizienter erledigen kann und viel solider ist.
Bitte überprüfen Sie diesen Link: Scraping-Websites-with-Curl
QueryPath ist gut, aber achten Sie auf den "Verfolgungsstatus", denn wenn Sie nicht wissen, was dies bedeutet, können Sie viel Debugging verschwenden Zeit, um herauszufinden, was passiert ist und warum der Code nicht funktioniert.
Das bedeutet, dass jeder Aufruf der Ergebnismenge die Ergebnismenge im Objekt ändert. Es ist nicht verkettbar wie in jquery, wo jede Verknüpfung eine neue Menge ist. Sie haben eine einzige Menge, die das Ergebnis Ihrer Abfrage ist, und jeder Funktionsaufruf ändert sich dieser einzige Satz.
um ein jQuery-ähnliches Verhalten zu erhalten, müssen Sie verzweigen, bevor Sie eine Filter-/Änderungsoperation ausführen. Dies bedeutet, dass das, was in JQuery geschieht, viel genauer gespiegelt wird.
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$results
enthält jetzt die Ergebnismenge für input[name='forename']
NICHT die ursprüngliche Abfrage "div p"
dies hat mich sehr gestört, was ich fand war, dass QueryPath verfolgt die Filter und findet und alles, was Ihre Ergebnisse ändert und speichert sie im Objekt. Sie müssen dies stattdessen tun
$forename = $results->branch()->find("input[name='forname']")
dann wird $results
nicht geändert, und Sie können die Ergebnismenge immer wieder verwenden. Vielleicht kann jemand mit viel mehr Wissen dies ein wenig aufklären, aber es ist im Grunde so, wie ich es gefunden habe.
Advanced Html Dom ist eine einfache HTML DOM - Ersetzung, die dieselbe Schnittstelle bietet, jedoch DOM-basiert ist, was bedeutet, dass keines der damit verbundenen Speicherprobleme auftritt.
Es hat auch volle CSS-Unterstützung, einschließlich jQuery Erweiterungen.
Ich habe einen XML-Parser für allgemeine Zwecke geschrieben, der problemlos mit GB-Dateien umgehen kann. Es basiert auf XMLReader und ist sehr einfach zu bedienen:
$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
echo $tag->field1;
echo $tag->field2->subfield1;
}
Hier ist das Github-Repo: XmlExtractor
Ich habe eine Bibliothek mit dem Namen PHPPowertools/DOM-Query erstellt, mit der Sie HTML5- und XML-Dokumente wie gewohnt crawlen können jQuery.
Unter der Haube verwendet es symfony/DomCrawler für die Konvertierung von CSS-Selektoren in XPath Selektoren. Es wird immer dasselbe DomDocument verwendet, auch wenn ein Objekt an ein anderes übergeben wird, um eine angemessene Leistung sicherzustellen.
namespace PowerTools;
// Get file content
$htmlcode = file_get_contents('https://github.com');
// Define your DOMCrawler based on file string
$H = new DOM_Query($htmlcode);
// Define your DOMCrawler based on an existing DOM_Query instance
$H = new DOM_Query($H->select('body'));
// Passing a string (CSS selector)
$s = $H->select('div.foo');
// Passing an element object (DOM Element)
$s = $H->select($documentBody);
// Passing a DOM Query object
$s = $H->select( $H->select('p + p'));
// Select the body tag
$body = $H->select('body');
// Combine different classes as one selector to get all site blocks
$siteblocks = $body->select('.site-header, .masthead, .site-body, .site-footer');
// Nest your methods just like you would with jQuery
$siteblocks->select('button')->add('span')->addClass('icon icon-printer');
// Use a lambda function to set the text of all site blocks
$siteblocks->text(function( $i, $val) {
return $i . " - " . $val->attr('class');
});
// Append the following HTML to all site blocks
$siteblocks->append('<div class="site-center"></div>');
// Use a descendant selector to select the site's footer
$sitefooter = $body->select('.site-footer > .site-center');
// Set some attributes for the site's footer
$sitefooter->attr(array('id' => 'aweeesome', 'data-val' => 'see'));
// Use a lambda function to set the attributes of all site blocks
$siteblocks->attr('data-val', function( $i, $val) {
return $i . " - " . $val->attr('class') . " - photo by Kelly Clark";
});
// Select the parent of the site's footer
$sitefooterparent = $sitefooter->parent();
// Remove the class of all i-tags within the site's footer's parent
$sitefooterparent->select('i')->removeAttr('class');
// Wrap the site's footer within two nex selectors
$sitefooter->wrap('<section><div class="footer-wrapper"></div></section>');
[...]
Die Bibliothek enthält auch einen eigenen Autoloader mit Null-Konfiguration für PSR-0-kompatible Bibliotheken. Das mitgelieferte Beispiel sollte ohne zusätzliche Konfiguration funktionieren. Alternativ können Sie es auch mit dem Komponisten verwenden.
Sie könnten versuchen, etwas wie HTML Tidy zu verwenden, um "defektes" HTML zu bereinigen und das HTML in XHTML zu konvertieren, das Sie dann mit einem XML-Parser analysieren können.
XML_HTMLSax
ist ziemlich stabil - auch wenn es nicht mehr gepflegt wird. Eine andere Möglichkeit wäre, HTML durch Html Tidy zu leiten und es dann mit Standard-XML-Tools zu analysieren.
Es gibt viele Möglichkeiten, HTML/XML-DOM zu verarbeiten, von denen die meisten bereits erwähnt wurden. Daher werde ich nicht versuchen, diese selbst aufzulisten.
Ich möchte nur hinzufügen, dass ich persönlich die DOM-Erweiterung bevorzuge und warum:
Und obwohl ich die Möglichkeit vermisse, CSS-Selektoren für DOMDocument
zu verwenden, gibt es eine ziemlich einfache und bequeme Möglichkeit, diese Funktion hinzuzufügen: das DOMDocument
unterzuordnen und JS-ähnliche querySelectorAll
und querySelector
Methoden zu Ihrer Unterklasse.
Zum Parsen der Selektoren empfehle ich die Verwendung des sehr minimalistischen CssSelector-Komponente aus dem Symfony-Framework . Diese Komponente übersetzt nur CSS-Selektoren in XPath-Selektoren, die dann in ein DOMXpath
eingegeben werden können, um die entsprechende Knotenliste abzurufen.
Sie können diese (noch sehr niedrige) Unterklasse dann als Grundlage für höhere Klassen verwenden, um z. Analysieren Sie ganz bestimmte XML-Typen oder fügen Sie mehr jQuery-ähnliches Verhalten hinzu.
Der folgende Code kommt direkt aus meiner DOM-Query-Bibliothek und verwendet die von mir beschriebene Technik.
Für das HTML-Parsen:
namespace PowerTools;
use \Symfony\Component\CssSelector\CssSelector as CssSelector;
class DOM_Document extends \DOMDocument {
public function __construct($data = false, $doctype = 'html', $encoding = 'UTF-8', $version = '1.0') {
parent::__construct($version, $encoding);
if ($doctype && $doctype === 'html') {
@$this->loadHTML($data);
} else {
@$this->loadXML($data);
}
}
public function querySelectorAll($selector, $contextnode = null) {
if (isset($this->doctype->name) && $this->doctype->name == 'html') {
CssSelector::enableHtmlExtension();
} else {
CssSelector::disableHtmlExtension();
}
$xpath = new \DOMXpath($this);
return $xpath->query(CssSelector::toXPath($selector, 'descendant::'), $contextnode);
}
[...]
public function loadHTMLFile($filename, $options = 0) {
$this->loadHTML(file_get_contents($filename), $options);
}
public function loadHTML($source, $options = 0) {
if ($source && $source != '') {
$data = trim($source);
$html5 = new HTML5(array('targetDocument' => $this, 'disableHtmlNsInDom' => true));
$data_start = mb_substr($data, 0, 10);
if (strpos($data_start, '<!DOCTYPE ') === 0 || strpos($data_start, '<html>') === 0) {
$html5->loadHTML($data);
} else {
@$this->loadHTML('<!DOCTYPE html><html><head><meta charset="' . $encoding . '" /></head><body></body></html>');
$t = $html5->loadHTMLFragment($data);
$docbody = $this->getElementsByTagName('body')->item(0);
while ($t->hasChildNodes()) {
$docbody->appendChild($t->firstChild);
}
}
}
}
[...]
}
Siehe auch Analysieren von XML-Dokumenten mit CSS-Selektoren von Fabien Potencier, dem Schöpfer von Symfony, zu seiner Entscheidung, die CssSelector-Komponente für Symfony zu erstellen, und deren Verwendung.
Mit FluidXML können Sie XML mit XPath und CSS abfragen und iterieren Selektoren .
$doc = fluidxml('<html>...</html>');
$title = $doc->query('//head/title')[0]->nodeValue;
$doc->query('//body/p', 'div.active', '#bgId')
->each(function($i, $node) {
// $node is a DOMNode.
$tag = $node->nodeName;
$text = $node->nodeValue;
$class = $node->getAttribute('class');
});
JSON und Array aus XML in drei Zeilen:
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Ta da!
Es gibt mehrere Gründe, HTML nicht mit regulären Ausdrücken zu analysieren. Wenn Sie jedoch die vollständige Kontrolle darüber haben, welcher HTML-Code generiert wird, können Sie mit einfachen regulären Ausdrücken vorgehen.
Darüber befindet sich eine Funktion, die HTML mit regulären Ausdrücken analysiert. Beachten Sie, dass diese Funktion sehr empfindlich ist und erfordert, dass der HTML-Code bestimmte Regeln einhält, sie funktioniert jedoch in vielen Szenarien sehr gut. Wenn Sie einen einfachen Parser benötigen und keine Bibliotheken installieren möchten, versuchen Sie Folgendes:
function array_combine_($keys, $values) {
$result = array();
foreach ($keys as $i => $k) {
$result[$k][] = $values[$i];
}
array_walk($result, create_function('&$v', '$v = (count($v) == 1)? array_pop($v): $v;'));
return $result;
}
function extract_data($str) {
return (is_array($str))
? array_map('extract_data', $str)
: ((!preg_match_all('#<([A-Za-z0-9_]*)[^>]*>(.*?)</\1>#s', $str, $matches))
? $str
: array_map(('extract_data'), array_combine_($matches[1], $matches[2])));
}
print_r(extract_data(file_get_contents("http://www.google.com/")));
Ich habe eine Bibliothek namens HTML5DOMDocument erstellt, die unter https://github.com/ivopetkov/html5-dom-document-php frei verfügbar ist
Es unterstützt auch Abfrageselektoren, von denen ich denke, dass sie in Ihrem Fall äußerst hilfreich sind. Hier ist ein Beispielcode:
$dom = new IvoPetkov\HTML5DOMDocument();
$dom->loadHTML('<!DOCTYPE html><html><body><h1>Hello</h1><div class="content">This is some text</div></body></html>');
echo $dom->querySelector('h1')->innerHTML;
Wenn Sie mit jQuery Selector vertraut sind, können Sie ScarletsQuery für PHP verwenden
<pre><?php
include "ScarletsQuery.php";
// Load the HTML content and parse it
$html = file_get_contents('https://www.lipsum.com');
$dom = Scarlets\Library\MarkupLanguage::parseText($html);
// Select meta tag on the HTML header
$description = $dom->selector('head meta[name="description"]')[0];
// Get 'content' attribute value from meta tag
print_r($description->attr('content'));
$description = $dom->selector('#Content p');
// Get element array
print_r($description->view);
Diese Bibliothek benötigt normalerweise weniger als 1 Sekunde, um Offline-HTML zu verarbeiten.
Es akzeptiert auch ungültiges HTML oder fehlende Anführungszeichen für Tag-Attribute.
Die beste Methode zum Parsen von XML:
$xml='http://www.example.com/rss.xml';
$rss = simplexml_load_string($xml);
$i = 0;
foreach ($rss->channel->item as $feedItem) {
$i++;
echo $title=$feedItem->title;
echo '<br>';
echo $link=$feedItem->link;
echo '<br>';
if($feedItem->description !='') {$des=$feedItem->description;} else {$des='';}
echo $des;
echo '<br>';
if($i>5) break;
}