Wie kann man HTML / XML analysieren und Informationen daraus extrahieren?
Wie kann man HTML / XML analysieren und Informationen daraus extrahieren?
Antworten:
Ich bevorzuge die Verwendung einer der nativen XML-Erweiterungen, da diese mit PHP gebündelt sind, normalerweise schneller als alle Bibliotheken von Drittanbietern sind und mir die Kontrolle geben, die ich über das Markup benötige.
Mit der DOM-Erweiterung können Sie XML-Dokumente über die DOM-API mit PHP 5 bearbeiten. Sie ist eine Implementierung des Document Object Model Core Level 3 des W3C, einer plattform- und sprachneutralen Schnittstelle, über die Programme und Skripte dynamisch zugreifen und aktualisieren können Inhalt, Struktur und Stil der Dokumente.
DOM ist in der Lage, (kaputtes) HTML aus der realen Welt zu analysieren und zu ändern und XPath-Abfragen durchzuführen . Es basiert auf libxml .
Es dauert einige Zeit, um mit DOM produktiv zu werden, aber diese Zeit lohnt sich IMO. Da DOM eine sprachunabhängige Schnittstelle ist, finden Sie Implementierungen in vielen Sprachen. Wenn Sie also Ihre Programmiersprache ändern müssen, wissen Sie wahrscheinlich bereits, wie die DOM-API dieser Sprache verwendet wird.
Ein grundlegendes Anwendungsbeispiel finden Sie unter Abrufen des href-Attributs eines A-Elements. 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 des Stapelüberlaufs gelöst werden können.
Die XMLReader-Erweiterung ist ein XML-Pull-Parser. Der Leser fungiert als Cursor, der im Dokumentstrom vorwärts geht und an jedem Knoten auf dem Weg anhält.
XMLReader basiert wie DOM auf libxml. Ich weiß nicht, 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, bei dem Sie explizit anweisen können, das HTML-Parser-Modul von libxml zu verwenden.
Ein grundlegendes Anwendungsbeispiel finden Sie unter Abrufen aller Werte von h1-Tags mithilfe von PHP
Mit dieser Erweiterung können Sie XML-Parser erstellen und dann 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 SAX- Stil. Es ist möglicherweise eine bessere Wahl für die Speicherverwaltung als DOM oder SimpleXML, aber es ist schwieriger, damit zu arbeiten als mit dem von XMLReader implementierten Pull-Parser.
Die SimpleXML-Erweiterung bietet ein sehr einfaches und leicht zu verwendendes Toolset zum Konvertieren von XML in ein Objekt, das mit normalen Eigenschaftswählern und Array-Iteratoren verarbeitet werden kann.
SimpleXML ist eine Option, wenn Sie wissen, dass HTML XHTML ist. Wenn Sie fehlerhaftes HTML analysieren müssen, sollten Sie SimpleXml nicht einmal in Betracht ziehen, da es erstickt.
Ein grundlegendes Anwendungsbeispiel findet Sie unter Einem einfachen Programm , um CRUD Knoten und Knotenwerte von XML - Datei , und es gibt viele weitere Beispiele in der PHP Manual .
Wenn Sie eine Bibliothek eines Drittanbieters bevorzugen, würde ich vorschlagen, eine Bibliothek zu verwenden, die tatsächlich DOM / libxml darunter verwendet, anstatt Zeichenfolgen zu analysieren.
FluentDOM bietet eine jQuery-ähnliche fließende XML-Schnittstelle für das DOMDocument in PHP. Selektoren werden in XPath oder CSS geschrieben (unter Verwendung eines CSS-zu-XPath-Konverters). Aktuelle Versionen erweitern das DOM, indem sie Standardschnittstellen implementieren und Funktionen aus dem DOM Living Standard hinzufügen. 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 DomCrawler von Symfony2-Komponenten zum Durchlaufen des DOM-Baums und erweitert sie um Methoden zum Bearbeiten des DOM-Baums von HTML-Dokumenten.
phpQuery ist eine serverseitige, verkettbare, CSS3-selektorgesteuerte DOM-API (Document Object Model), 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 Tools zum Arbeiten mit DOM-Dokumenten und -Strukturen. Derzeit bieten wir Zend_Dom_Query an, das eine einheitliche Schnittstelle zum Abfragen von DOM-Dokumenten mit XPath- und CSS-Selektoren bietet.
QueryPath ist eine PHP-Bibliothek zum Bearbeiten von XML und HTML. Es funktioniert nicht nur mit lokalen Dateien, sondern auch mit Webdiensten und Datenbankressourcen. Es implementiert einen Großteil der jQuery-Schnittstelle (einschließlich CSS-Selektoren), ist jedoch stark auf die serverseitige Verwendung abgestimmt. Kann über Composer installiert werden.
fDOMDocument erweitert das Standard-DOM, um bei allen Fehlerausnahmen Ausnahmen anstelle von PHP-Warnungen oder Hinweisen zu verwenden. Sie fügen auch verschiedene benutzerdefinierte Methoden und Verknüpfungen hinzu, um die Verwendung von DOM zu vereinfachen und zu vereinfachen.
saber / xml ist eine Bibliothek, die die Klassen XMLReader und XMLWriter umschließt und erweitert, um ein einfaches Zuordnungssystem und Entwurfsmuster für "XML zu Objekt / Array" zu erstellen. Das Schreiben und Lesen von XML erfolgt in einem Durchgang und kann daher schnell sein und wenig Speicher für große XML-Dateien erfordern.
FluidXML ist eine PHP-Bibliothek zum Bearbeiten von XML mit einer übersichtlichen und fließenden API. Es nutzt XPath und das fließende Programmiermuster, um Spaß zu haben und effektiv zu sein.
Der Vorteil des Aufbaus auf DOM / libxml 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 sind unten aufgeführt
- Mit einem in PHP5 + geschriebenen HTML-DOM-Parser können Sie HTML auf sehr einfache Weise bearbeiten!
- Benötigen Sie 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 (z. B. untergeordnete Selektoren ) sind möglich. Jede der libxml-basierten Bibliotheken sollte dies leicht übertreffen.
PHPHtmlParser ist ein einfacher, flexibler HTML-Parser, mit dem Sie Tags mit einem beliebigen CSS-Selektor wie jQuery auswählen können. Das Ziel ist es, bei der Entwicklung von Tools zu helfen, die eine schnelle und einfache Möglichkeit zum Verschrotten von HTML erfordern, unabhängig davon, ob es gültig ist 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 Anpassung seiner vorherigen 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 für erstellte DOM-Objekte. Diese Probleme lassen sich insbesondere bei verschachtelten Schleifen skalieren. Die Dokumentation selbst ist ungenau und falsch geschrieben. Seit dem 14. April 16 gibt es keine Antworten auf Korrekturen.
- Ein universeller Tokenizer und HTML / XML / RSS-DOM-Parser
- Fähigkeit, Elemente und ihre Attribute zu manipulieren
- Unterstützt ungültiges HTML und UTF8
- Kann erweiterte CSS3-ähnliche Abfragen für Elemente ausführen (z. B. jQuery - Namespaces unterstützt)
- Ein HTML-Verschönerer (wie HTML Tidy)
- Minimieren 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, die in kleinere Funktionen unterteilt sind, erleichtern das Überschreiben
- Schnell und einfach
Ich habe es nie benutzt. Ich kann nicht sagen, ob es etwas Gutes ist.
Sie können das oben Gesagte zum Parsen von HTML5 verwenden, es kann jedoch aufgrund des von HTML5 zugelassenen Markups zu Macken kommen . Für HTML5 möchten Sie also einen dedizierten Parser verwenden, 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.
Nach der Fertigstellung von HTML5 werden möglicherweise mehr dedizierte Parser angezeigt. Es gibt auch einen Blogpost des W3 mit dem Titel " How-To for HTML 5 Parsing" , der einen Besuch 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 sind nur ich und meine Anwendungsfälle.
Über die externe Oberfläche von ScraperWiki können Sie Daten in der Form extrahieren, die Sie für die Verwendung im Web oder in Ihren eigenen Anwendungen benötigen. Sie können auch Informationen über den Zustand eines Schabers extrahieren.
Als letztes und am wenigsten empfohlen können Sie Daten mit regulären Ausdrücken 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 Markups abzugleichen, sind spröde. In den meisten Fällen arbeiten sie nur für ein bestimmtes Stück HTML. Winzige Markup-Änderungen, wie das Hinzufügen von Leerzeichen irgendwo oder das Hinzufügen oder Ändern von Attributen in einem Tag, können dazu führen, dass RegEx fehlschlägt, wenn es nicht richtig geschrieben ist. Sie sollten wissen, was Sie tun, bevor Sie RegEx in HTML verwenden.
HTML-Parser kennen bereits die syntaktischen Regeln von HTML. Für jeden neuen RegEx, den Sie schreiben, müssen reguläre Ausdrücke unterrichtet 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 vorhanden sind und diesbezüglich viel bessere Arbeit leisten.
Siehe auch Parsing Html The Cthulhu Way
Wenn Sie etwas Geld ausgeben möchten, schauen Sie sich an
Ich bin nicht mit PHP Architect oder den Autoren verbunden.
Probieren Sie Simple HTML DOM Parser aus
// 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 erstickt entgegen der landläufigen Meinung nicht an fehlerhaftem HTML.
Warum sollten Sie nicht und wann sollten Sie reguläre Ausdrücke verwenden?
Zunächst einmal eine häufige Fehlbezeichnung: Regexps sind nicht zum " Parsen " von HTML gedacht . Regexes 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-Basisparsern ist ihr syntaktischer Aufwand und ihre unterschiedliche Zuverlässigkeit.
Bedenken Sie, dass Sie einen etwas zuverlässigen HTML-Extraktions-Regex erstellen:
<a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
ist viel weniger lesbar als ein einfaches phpQuery- oder QueryPath-Äquivalent:
$div->find(".stationcool a")->attr("title");
Es gibt jedoch spezielle Anwendungsfälle, in denen sie helfen können.
<!--
, die jedoch manchmal die nützlicheren Anker für die Extraktion sind. Insbesondere Pseudo-HTML-Variationen <$var>
oder SGML-Reste lassen sich mit regulären Ausdrücken leicht zähmen.Manchmal ist es sogar ratsam, einen HTML-Ausschnitt mit regulären Ausdrücken vorab zu extrahieren /<!--CONTENT-->(.+?)<!--END-->/
und den Rest mit den einfacheren HTML-Parser-Frontends zu verarbeiten.
Hinweis: Ich habe tatsächlich diese App , in der ich alternativ XML-Parsing und reguläre Ausdrücke verwende. Erst letzte Woche war die PyQuery-Analyse unterbrochen, und der reguläre Ausdruck funktionierte immer noch. Ja komisch, und ich kann es nicht selbst erklären. Aber so ist es passiert.
Bitte stimmen Sie nicht über reale Überlegungen ab, nur weil sie nicht mit dem regulären Ausdruck = böses Mem übereinstimmen. Aber lasst uns das auch nicht zu sehr abstimmen. Es ist nur eine Nebenbemerkung zu diesem Thema.
DOMComment
kann Kommentare lesen, daher kein Grund, Regex dafür zu verwenden.
DOM
verwendet libxml und libxml verfügt über ein separates HTML-Parser- Modul, das beim Laden von HTML verwendet wird, loadHTML()
damit es sehr viel "reales" (defektes) HTML laden kann.
phpQuery und QueryPath sind sich beim Replizieren der fließenden jQuery-API sehr ähnlich. Das ist auch der Grund, warum sie zwei der einfachsten Ansätze sind, um HTML in PHP richtig 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 besteht jedoch darin, CSS-Selektoren wie in jQuery zu verwenden:
$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 verwenden ->find()
. Sie können aber auch XPath- Anweisungen verwenden, die manchmal schneller sind. Auch typische jQuery-Methoden wie ->children()
und und ->text()
und ->attr()
vereinfachen insbesondere das Extrahieren der richtigen HTML-Snippets. (Und haben bereits ihre SGML-Entitäten dekodiert.)
$qp->xpath("//div/p[1]"); // get first paragraph in a div
QueryPath ermöglicht auch das Einfügen neuer Tags in den Stream ( ->append
) und das spätere Ausgeben und Verschönern eines aktualisierten Dokuments ( ->writeHTML
). Es kann nicht nur fehlerhaftes HTML analysieren, sondern auch verschiedene XML-Dialekte (mit Namespaces) 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 für die Bearbeitung von Dokumenten. Während phpQuery auch einige Pseudo-AJAX-Methoden (nur HTTP-Anforderungen) implementiert, um jQuery ähnlicher zu werden. Es wird gesagt, dass phpQuery oft schneller als QueryPath ist (wegen weniger Gesamtfunktionen).
Weitere Informationen zu den Unterschieden finden Sie in diesem Vergleich auf der Wayback-Maschine von tagbyte.org . (Die ursprüngliche Quelle ist verschwunden, daher hier ein Link zum Internetarchiv. Ja, Sie können immer noch fehlende Seiten und Personen finden.)
Und hier ist eine umfassende Einführung in QueryPath .
Vorteile
->find("a img, a object, div a")
Simple HTML DOM ist ein großartiger Open-Source-Parser:
Es behandelt DOM-Elemente objektorientiert, und die neue Iteration bietet eine umfassende Abdeckung für nicht konformen Code. Es gibt auch einige großartige Funktionen, wie Sie sie in JavaScript sehen würden, wie beispielsweise die Funktion "find", 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 erwähnt habe, ist das Ausführen von HTML über Tidy , das so eingestellt werden kann, dass es garantiert gültiges XHTML ausspuckt. Dann können Sie jede alte XML-Bibliothek darauf verwenden.
Um Ihr spezifisches Problem zu lösen, sollten Sie sich dieses Projekt ansehen: http://fivefilters.org/content-only/ - Es handelt sich um eine modifizierte Version des Lesbarkeitsalgorithmus , mit der nur der Textinhalt (keine Überschriften) extrahiert werden soll und Fußzeilen) von einer Seite.
Für 1a und 2: Ich würde für die neue Symfony Componet-Klasse DOMCrawler ( DomCrawler ) stimmen . Diese Klasse ermöglicht Abfragen ähnlich wie CSS-Selektoren. Schauen Sie sich diese Präsentation für Beispiele aus der Praxis an : News-of-the-Symfony2-World .
Die Komponente ist eigenständig konzipiert und kann ohne Symfony verwendet werden.
Der einzige Nachteil ist, dass es nur mit PHP 5.3 oder neuer funktioniert.
Dies wird übrigens allgemein 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. Am Ende des Tages sind es normalerweise einfache reguläre Ausdrücke, die das Beste tun. Während die oben aufgeführten Bibliotheken aus dem Grund, aus dem sie erstellt wurden, gut sind, sind reguläre Ausdrücke ein sicherer Weg, wenn Sie wissen, wonach Sie suchen, da Sie auch ungültige HTML / XHTML- Strukturen verarbeiten können, die beim Laden fehlschlagen würden über die meisten Parser.
Ich empfehle PHP Simple HTML DOM Parser .
Es hat wirklich schöne 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
verschachtelten Tags zurückgeben " auszudrücken <foo><bar><baz> elements
. Da ich kein PHP-Fan bin, kann ich Ihnen nicht sagen, in welcher Form XPath verfügbar sein könnte. Wenn Sie ein externes Programm aufrufen können, um die HTML-Datei zu verarbeiten, sollten Sie eine Befehlszeilenversion von XPath verwenden können. Eine kurze Einführung finden Sie unter http://en.wikipedia.org/wiki/XPath .
Alternativen von Drittanbietern zu SimpleHtmlDom, die DOM anstelle von String Parsing verwenden: phpQuery , Zend_Dom , QueryPath und FluentDom .
Ja, Sie können simple_html_dom für diesen Zweck verwenden. Ich habe jedoch ziemlich viel mit simple_html_dom gearbeitet, insbesondere beim Verschrotten von Webinhalten, und festgestellt, dass es zu anfällig ist. Es macht den grundlegenden Job, aber ich werde es sowieso nicht empfehlen.
Ich habe Curl nie für diesen Zweck verwendet, aber ich habe gelernt, dass Curl die Arbeit viel effizienter erledigen kann und viel solider ist.
Bitte überprüfen Sie diesen Link: Scraping-Websites-mit-Curl
QueryPath ist gut, aber achten Sie auf den "Tracking-Status", denn wenn Sie nicht wissen , was dies bedeutet, können Sie viel Debugging-Zeit damit verschwenden, herauszufinden, was passiert ist und warum der Code nicht funktioniert.
Dies bedeutet, dass jeder Aufruf der Ergebnismenge die Ergebnismenge im Objekt ändert. Sie ist nicht verkettbar wie in jquery, wo jeder Link eine neue Menge ist. Sie haben eine einzelne Menge, die die Ergebnisse Ihrer Abfrage sind, und jeder Funktionsaufruf ändert sich dieser einzelne Satz.
Um ein jquery-ähnliches Verhalten zu erzielen, müssen Sie verzweigen, bevor Sie eine Filter- / Änderungsoperation ausführen. Dies bedeutet, dass das, was in jquery geschieht, viel genauer wiedergegeben 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"
, die mich sehr gestolpert hat. Ich habe festgestellt, dass QueryPath die Filter und Funde sowie alles, was Ihre Ergebnisse ändert und im Objekt speichert, verfolgt. Sie müssen dies stattdessen tun
$forename = $results->branch()->find("input[name='forname']")
Dann $results
wird es nicht geändert und Sie können die Ergebnismenge immer wieder verwenden. Vielleicht kann jemand mit viel mehr Wissen dies ein wenig klären, aber es ist im Grunde so, wie ich es gefunden habe.
Advanced Html Dom ist ein einfacher HTML- DOM- Ersatz, der dieselbe Schnittstelle bietet, jedoch DOM-basiert ist, was bedeutet, dass keines der damit verbundenen Speicherprobleme auftritt.
Es bietet außerdem vollständige CSS-Unterstützung, einschließlich jQuery- Erweiterungen.
Für HTML5 wurde html5 lib seit Jahren aufgegeben. Die einzige HTML5-Bibliothek, die ich mit einem aktuellen Update und Wartungsprotokollen finden kann, ist HTML5-PHP, das vor etwas mehr als einer Woche auf Beta 1.0 gebracht wurde.
Ich habe einen Allzweck-XML-Parser 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 genau wie mit jQuery crawlen können.
Unter der Haube wird Symfony / DomCrawler zum Konvertieren von CSS-Selektoren in XPath- Selektoren verwendet. 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 ohne Konfiguration für PSR-0-kompatible Bibliotheken. Das enthaltene Beispiel sollte ohne zusätzliche Konfiguration sofort funktionieren. Alternativ können Sie es mit Composer verwenden.
Eine weitere Option, die Sie ausprobieren können, ist QueryPath . Es ist von jQuery inspiriert, aber auf dem Server in PHP und in Drupal verwendet .
XML_HTMLSax
ist ziemlich stabil - auch wenn es nicht mehr gepflegt wird. Eine andere Möglichkeit könnte darin bestehen, 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 zu verwenden DOMDocument
, gibt es eine ziemlich einfache und bequeme Möglichkeit, diese Funktion hinzuzufügen: Unterklassen DOMDocument
und Hinzufügen von JS-ähnlichen Methoden querySelectorAll
und querySelector
Methoden zu Ihrer Unterklasse.
Zum Parsen der Selektoren empfehle ich die Verwendung der sehr minimalistischen CssSelector-Komponente aus dem Symfony-Framework . Diese Komponente übersetzt nur CSS-Selektoren in XPath-Selektoren, die dann in a eingespeist werden könnenDOMXpath
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, die z. Analysieren Sie ganz bestimmte XML-Typen oder fügen Sie mehr jQuery-ähnliches Verhalten hinzu.
Der folgende Code stammt 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 Parsen von XML-Dokumenten mit CSS-Selektoren von Fabien Potencier, dem Erfinder von Symfony, zu seiner Entscheidung, die CssSelector-Komponente für Symfony zu erstellen, und zu deren Verwendung.
Mit FluidXML können Sie XML mit XPath- und CSS-Selektoren abfragen und iterieren .
$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 durch reguläre Ausdrücke zu analysieren. Wenn Sie jedoch die vollständige Kontrolle darüber haben, welcher HTML-Code generiert wird, können Sie einen einfachen regulären Ausdruck verwenden.
Oben ist es eine Funktion, die HTML nach regulären Ausdrücken analysiert. Beachten Sie, dass diese Funktion sehr sensibel ist und erfordert, dass der HTML-Code bestimmte Regeln einhält, aber in vielen Szenarien sehr gut funktioniert. Wenn Sie einen einfachen Parser möchten und keine Bibliotheken installieren möchten, probieren Sie Folgendes aus:
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;
}