it-swarm.com.de

Wie analysiert und verarbeitet man HTML / XML in PHP?

Wie kann man HTML/XML analysieren und daraus Informationen extrahieren?

2051
RobertPitt

Native XML-Erweiterungen

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.

DOM

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.

XMLReader

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

XML-Parser

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.

SimpleXml

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 =.


Bibliotheken von Drittanbietern (libxml-basiert)

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 - Repo

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.

HtmlPageDom

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 (seit Jahren nicht aktualisiert)

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

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

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

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

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

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.


3rd-Party (nicht libxml-basiert)

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

PHP Simple HTML DOM Parser

  • 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.

PHP Html Parser

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.

Ganon

  • 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.


HTML 5

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

html5lib

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.


Internetdienste

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.

ScraperWiki .

Ü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.


Reguläre Ausdrücke

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


Bücher

Wenn Sie etwas Geld ausgeben möchten, werfen Sie einen Blick auf

Ich bin nicht mit PHP Architect oder den Autoren verbunden.

1845
Gordon

Versuchen Sie Simple HTML DOM Parser

  • Ein in PHP 5+ geschriebener HTML-DOM-Parser, mit dem Sie HTML auf sehr einfache Weise bearbeiten können!
  • 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.
  • Download


Beispiele:

So erhalten Sie HTML-Elemente:

// 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>';


So ändern Sie HTML-Elemente:

// 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;


Inhalte aus HTML extrahieren:

// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;


Slashdot schaben:

// 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);
319
Naveed

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.

232
Edward Z. Yang

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.

  • Viele DOM-Traversal-Frontends zeigen keine HTML-Kommentare <!-- 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.
  • Häufig sparen reguläre Ausdrücke die Nachbearbeitung. HTML-Entitäten erfordern jedoch häufig eine manuelle Pflege.
  • Und schließlich sind e extrem einfache Aufgaben wie das Extrahieren von <img src = urls ein wahrscheinliches Werkzeug. Der Geschwindigkeitsvorteil gegenüber SGML/XML-Parsern kommt meist nur bei diesen sehr einfachen Extraktionsverfahren zum Tragen.

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.

145
mario

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

  • Einfachheit und Zuverlässigkeit
  • Einfach zu verwendende Alternativen ->find("a img, a object, div a")
  • Ordnungsgemäße Datenentnahme (im Vergleich zum Greppen mit regulären Ausdrücken)
130
mario

Simple HTML DOM ist ein großartiger Open-Source-Parser:

simplehtmldom.sourceforge

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.

88
Robert Elwell

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.

59
Eli

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.

55
Timo

Dies wird im Allgemeinen als Screen Scraping bezeichnet. Die Bibliothek, die ich dafür verwendet habe, ist Simple HTML Dom Parser .

52
Joel Verhagen

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.

41
jancha

Ich empfehle PHP Simple HTML DOM Parser .

Es hat wirklich nette Funktionen, wie:

foreach($html->find('img') as $element)
       echo $element->src . '<br>';
38
Greg

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 .

36
Jens

Alternativen von Drittanbietern zu SimpleHtmlDom, die DOM anstelle von String Parsing verwenden: phpQuery , Zend_Dom , QueryPath und FluentDom .

29
danidacar

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

24
Rafay

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.

23

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.

19
pguardiario

Für HTML5 wurde die HTML5-Bibliothek seit Jahren aufgegeben. Die einzige HTML5-Bibliothek, die ich mit den neuesten Aktualisierungs- und Wartungsaufzeichnungen finden kann, ist html5-php , die erst vor etwas mehr als einer Woche auf Beta 1.0 gebracht wurde.

18
Reid Johnson

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

17
Paul Warelis

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.


Beispiel Verwendung:

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>');

[...]

Unterstützte Methoden:


  1. Aus offensichtlichen Gründen umbenannt in 'select'
  2. Umbenannt in 'void', da 'empty' in PHP ein reserviertes Wort ist

HINWEIS :

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.

17
John Slegers

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.

15
CesarB

Eine andere Option, die Sie ausprobieren können, ist QueryPath . Es ist von jQuery inspiriert, wird jedoch auf dem Server in PHP und in Drupal verwendet.

15

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.

12
troelskn

Das Symfony -Framework verfügt über Bundles, die den HTML-Code analysieren können, und Sie können den CSS-Stil verwenden, um DOMs auszuwählen, anstatt XPath zu verwenden.

11
Tuong Le

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:

  • iit nutzt den Leistungsvorteil des zugrunde liegenden C-Codes optimal aus
  • es ist OO PHP (und erlaubt mir, es zu unterklassifizieren)
  • es ist ziemlich niedrig (was mir erlaubt, es als nicht aufgeblähte Grundlage für fortgeschritteneres Verhalten zu verwenden)
  • es bietet Zugriff auf jeden Teil des DOM (im Gegensatz zu zB SimpleXml, das einige der weniger bekannten XML-Funktionen ignoriert).
  • es hat eine Syntax für das DOM-Crawlen, die der in nativem Javascript verwendeten Syntax ähnelt.

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.

11
John Slegers

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');
        });

https://github.com/servo-php/fluidxml

9
Daniele Orlando

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!

7
Antonio Max

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/")));
7
Daniel Loureiro

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;
2
Ivo Petkov

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.

0
StefansArya

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;
}
0
user8031209