Come si può analizzare HTML / XML ed estrarre informazioni da esso?
Come si può analizzare HTML / XML ed estrarre informazioni da esso?
Risposte:
Preferisco usare una delle estensioni XML native poiché vengono fornite in bundle con PHP, di solito sono più veloci di tutte le librerie di terze parti e mi danno tutto il controllo di cui ho bisogno sul markup.
L'estensione DOM consente di operare su documenti XML tramite l'API DOM con PHP 5. È un'implementazione del Document Object Model Core Level 3 del W3C, un'interfaccia indipendente dalla piattaforma e dal linguaggio che consente a programmi e script di accedere e aggiornare dinamicamente il contenuto, la struttura e lo stile dei documenti.
DOM è in grado di analizzare e modificare HTML del mondo reale (non funzionante) e può eseguire query XPath . Si basa su libxml .
Ci vuole un po 'di tempo per diventare produttivi con DOM, ma quel tempo vale la pena IMO. Poiché DOM è un'interfaccia indipendente dalla lingua, troverai implementazioni in molte lingue, quindi se hai bisogno di cambiare il tuo linguaggio di programmazione, è probabile che tu sappia già come usare l'API DOM di quella lingua.
Un esempio di utilizzo di base può essere trovato in Afferrare l'attributo href di un elemento A e una panoramica concettuale generale è disponibile su DOMDocument in php
Come utilizzare l'estensione DOM è stato ampiamente trattato su StackOverflow , quindi se si sceglie di utilizzarlo, si può essere certi che la maggior parte dei problemi riscontrati possano essere risolti cercando / sfogliando Stack Overflow.
L'estensione XMLReader è un parser pull XML. Il lettore agisce come un cursore andando avanti nel flusso di documenti e fermandosi su ciascun nodo lungo la strada.
XMLReader, come DOM, si basa su libxml. Non sono a conoscenza di come attivare il modulo parser HTML, quindi è probabile che l'utilizzo di XMLReader per l'analisi del codice HTML non funzionante sia meno efficace rispetto all'utilizzo del DOM in cui è possibile dirgli esplicitamente di utilizzare il modulo parser HTML di libxml.
Un esempio di utilizzo di base si trova nell'ottenere tutti i valori dai tag h1 usando php
Questa estensione consente di creare parser XML e quindi definire gestori per diversi eventi XML. Ogni parser XML ha anche alcuni parametri che è possibile regolare.
La libreria XML Parser si basa anche su libxml e implementa un parser push XML in stile SAX . Potrebbe essere una scelta migliore per la gestione della memoria rispetto a DOM o SimpleXML, ma sarà più difficile da lavorare rispetto al pull parser implementato da XMLReader.
L'estensione SimpleXML fornisce un set di strumenti molto semplice e facilmente utilizzabile per convertire XML in un oggetto che può essere elaborato con normali selettori di proprietà e iteratori di array.
SimpleXML è un'opzione quando sai che l'HTML è XHTML valido. Se hai bisogno di analizzare il codice HTML non funzionante, non prendere nemmeno in considerazione SimpleXml perché si strozzerà.
Un esempio di utilizzo di base è disponibile in Un semplice programma per il nodo CRUD e i valori dei nodi del file XML e ci sono molti altri esempi nel Manuale PHP .
Se preferisci usare una lib di terze parti, suggerirei di usare una lib che in realtà usa DOM / libxml al di sotto invece dell'analisi delle stringhe.
FluentDOM fornisce un'interfaccia XML fluida simile a jQuery per DOMDocument in PHP. I selettori sono scritti in XPath o CSS (usando un convertitore da CSS a XPath). Le versioni attuali estendono il DOM implementando interfacce standard e aggiungono funzionalità dal DOM Living Standard. FluentDOM può caricare formati come JSON, CSV, JsonML, RabbitFish e altri. Può essere installato tramite Composer.
Wa72 \ HtmlPageDom` è una libreria PHP per una facile manipolazione di documenti HTML che utilizzano DomCrawler dai componenti di Symfony2 per attraversare l'albero DOM e lo estende aggiungendo metodi per manipolare l'albero DOM dei documenti HTML.
phpQuery è un'API Document Object Model (DOM) basata sul selettore CSS3 lato server, concatenabile, basata sulla libreria JavaScript jQuery scritta in PHP5 e fornisce CLI (Command Line Interface) aggiuntiva.
Vedi anche: https://github.com/electrolinux/phpquery
Zend_Dom fornisce strumenti per lavorare con documenti e strutture DOM. Al momento, offriamo Zend_Dom_Query, che fornisce un'interfaccia unificata per l'interrogazione di documenti DOM utilizzando selettori XPath e CSS.
QueryPath è una libreria PHP per manipolare XML e HTML. È progettato per funzionare non solo con file locali, ma anche con servizi Web e risorse di database. Implementa gran parte dell'interfaccia jQuery (inclusi i selettori in stile CSS), ma è fortemente ottimizzata per l'uso sul lato server. Può essere installato tramite Composer.
fDOMDocument estende il DOM standard per utilizzare le eccezioni in tutte le occasioni di errori anziché avvisi o avvisi PHP. Aggiungono inoltre vari metodi personalizzati e scorciatoie per comodità e per semplificare l'utilizzo di DOM.
sabre / xml è una libreria che avvolge ed estende le classi XMLReader e XMLWriter per creare un sistema di mappatura e un modello di progettazione semplici da "xml a object / array". Scrivere e leggere XML è single-pass e può quindi essere veloce e richiedere poca memoria su file XML di grandi dimensioni.
FluidXML è una libreria PHP per manipolare XML con un'API concisa e fluida. Sfrutta XPath e il modello di programmazione fluente per essere divertente ed efficace.
Il vantaggio di basarsi su DOM / libxml è che si ottengono buone prestazioni immediatamente perché si è basati su un'estensione nativa. Tuttavia, non tutte le librerie di terze parti seguono questa strada. Alcuni di essi elencati di seguito
- Un parser DOM HTML scritto in PHP5 + ti consente di manipolare HTML in modo molto semplice!
- Richiedi PHP 5+.
- Supporta HTML non valido.
- Trova i tag in una pagina HTML con selettori proprio come jQuery.
- Estrai i contenuti dall'HTML in un'unica riga.
In genere non consiglio questo parser. La base di codice è orribile e lo stesso parser è piuttosto lento e la memoria ha fame. Non tutti i selettori jQuery (come i selettori figlio ) sono possibili. Qualsiasi libreria basata su libxml dovrebbe superare facilmente questo valore.
PHPHtmlParser è un parser html semplice, flessibile che ti permette di selezionare i tag usando qualsiasi selettore css, come jQuery. L'obiettivo è quello di assistere allo sviluppo di strumenti che richiedono un modo rapido e semplice per eliminare l'html, che sia valido o no! Questo progetto è stato originale supportato da sunra / php-simple-html-dom-parser ma il supporto sembra essersi fermato, quindi questo progetto è il mio adattamento del suo lavoro precedente.
Ancora una volta, non consiglierei questo parser. È piuttosto lento con un elevato utilizzo della CPU. Non esiste inoltre alcuna funzione per cancellare la memoria degli oggetti DOM creati. Questi problemi si adattano in particolare ai loop nidificati. La documentazione stessa è inesatta e errata, senza risposte alle correzioni dal 14 aprile 16.
- Un tokenizer universale e parser DOM HTML / XML / RSS
- Capacità di manipolare elementi e loro attributi
- Supporta HTML e UTF8 non validi
- Può eseguire query avanzate simili a CSS3 su elementi (come jQuery - spazi dei nomi supportati)
- Un estetista HTML (come HTML Tidy)
- Minimizza CSS e Javascript
- Ordina gli attributi, cambia il carattere, il rientro corretto, ecc.
- Estensibile
- Analisi dei documenti utilizzando callback basati sul carattere / token corrente
- Operazioni separate in funzioni più piccole per una facile sostituzione
- Facile e veloce
Non l'ho mai usato. Non so dire se va bene.
Puoi utilizzare quanto sopra per analizzare HTML5, ma possono esserci delle stranezze a causa del markup che HTML5 consente. Quindi per HTML5 vuoi prendere in considerazione l'uso di un parser dedicato, come
Implementazioni Python e PHP di un parser HTML basato sulla specifica HTML5 WHATWG per la massima compatibilità con i principali browser Web desktop.
Potremmo vedere più parser dedicati una volta finalizzato HTML5. C'è anche un post sul blog di W3 intitolato How-To per l'analisi HTML 5 che vale la pena dare un'occhiata.
Se non hai voglia di programmare PHP, puoi anche utilizzare i servizi Web. In generale, ho trovato pochissima utilità per questi, ma sono solo io e i miei casi d'uso.
L'interfaccia esterna di ScraperWiki ti consente di estrarre i dati nella forma che desideri utilizzare sul Web o nelle tue applicazioni. Puoi anche estrarre informazioni sullo stato di qualsiasi raschietto.
Ultimo e meno consigliato , è possibile estrarre dati da HTML con espressioni regolari . In generale l'uso delle espressioni regolari su HTML è scoraggiato.
La maggior parte dei frammenti che troverai sul Web per abbinare il markup sono fragili. Nella maggior parte dei casi funzionano solo per un pezzo HTML molto particolare. Piccole modifiche al markup, come l'aggiunta di spazi bianchi da qualche parte, o l'aggiunta o la modifica di attributi in un tag, possono far fallire RegEx quando non è scritto correttamente. Dovresti sapere cosa stai facendo prima di utilizzare RegEx su HTML.
I parser HTML conoscono già le regole sintattiche dell'HTML. Le espressioni regolari devono essere insegnate per ogni nuovo RegEx che scrivi. RegEx va bene in alcuni casi, ma dipende davvero dal tuo caso d'uso.
È possibile scrivere parser più affidabili , ma scrivere un parser personalizzato completo e affidabile con espressioni regolari è una perdita di tempo quando le librerie di cui sopra esistono già e fanno un lavoro molto migliore su questo.
Vedi anche Parsing Html The Cthulhu Way
Se vuoi spendere dei soldi, dai un'occhiata
Non sono affiliato con PHP Architect o gli autori.
Prova il parser DOM HTML semplice
// 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);
Basta usare DOMDocument-> loadHTML () e finirlo . L'algoritmo di analisi HTML di libxml è abbastanza buono e veloce, e contrariamente alla credenza popolare, non soffoca sull'HTML malformato.
Perché non dovresti e quando dovresti usare le espressioni regolari?
Prima di tutto, un nome improprio comune: Regexps non serve per " analizzare " l' HTML. Regexes può tuttavia " estrarre " i dati. L'estrazione è ciò per cui sono fatti. Il principale svantaggio dell'estrazione di regex HTML su corretti toolkit SGML o parser XML di base è il loro sforzo sintattico e la loro affidabilità variabile.
Considera che creare una regex di estrazione HTML in qualche modo affidabile:
<a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
è molto meno leggibile di un semplice phpQuery o equivalente di QueryPath:
$div->find(".stationcool a")->attr("title");
Vi sono tuttavia casi d'uso specifici in cui possono aiutare.
<!--
, che tuttavia a volte sono gli ancoraggi più utili per l'estrazione. In particolare, le variazioni pseudo-HTML <$var>
o i residui SGML sono facili da domare con regexps.A volte è anche consigliabile pre-estrarre uno snippet di HTML usando espressioni regolari /<!--CONTENT-->(.+?)<!--END-->/
ed elaborare il resto usando i frontend del parser HTML più semplici.
Nota: in realtà ho questa app , in cui utilizzo alternativamente analisi XML ed espressioni regolari. Proprio la scorsa settimana il parsing di PyQuery si è rotto e il regex ha funzionato ancora. Sì strano, e non posso spiegarlo da solo. Ma così è successo.
Quindi per favore non votare verso il basso le considerazioni del mondo reale, solo perché non corrisponde al meme regex = evil. Ma non votiamo troppo. È solo un sidenote per questo argomento.
DOMComment
può leggere commenti, quindi nessun motivo per usare Regex per questo.
DOM
usi libxml e libxml ha un parser HTML separato modulo che sarà utilizzato durante il caricamento HTML con loadHTML()
in modo che possa molto carico "del mondo reale" (leggi rotto) HTML.
phpQuery e QueryPath sono estremamente simili nel replicare l'API jQuery fluente. Questo è anche il motivo per cui sono due degli approcci più semplici per analizzare correttamente HTML in PHP.
Esempi per QueryPath
Fondamentalmente devi prima creare un albero DOM interrogabile da una stringa HTML:
$qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL
L'oggetto risultante contiene una rappresentazione ad albero completa del documento HTML. Può essere attraversato usando i metodi DOM. Ma l'approccio comune è usare selettori CSS come in jQuery:
$qp->find("div.classname")->children()->...;
foreach ($qp->find("p img") as $img) {
print qp($img)->attr("src");
}
Principalmente si desidera utilizzare selettori semplici #id
e .class
o DIV
tag per ->find()
. Ma puoi anche usare le istruzioni XPath , che a volte sono più veloci. Anche i tipici metodi jQuery come ->children()
e ->text()
soprattutto ->attr()
semplificano l'estrazione dei giusti frammenti HTML. (E hanno già decodificato le loro entità SGML.)
$qp->xpath("//div/p[1]"); // get first paragraph in a div
QueryPath consente inoltre di iniettare nuovi tag nello stream ( ->append
), quindi di generare e preimpostare un documento aggiornato ( ->writeHTML
). Non solo può analizzare HTML non valido, ma anche vari dialetti XML (con spazi dei nomi) e persino estrarre dati da microformati HTML (XFN, vCard).
$qp->find("a[target=_blank]")->toggleClass("usability-blunder");
.
phpQuery o QueryPath?
Generalmente QueryPath è più adatto alla manipolazione di documenti. Mentre phpQuery implementa anche alcuni metodi pseudo AJAX (solo richieste HTTP) per assomigliare più da vicino a jQuery. Si dice che phpQuery sia spesso più veloce di QueryPath (a causa di un minor numero di funzionalità complessive).
Per ulteriori informazioni sulle differenze, consultare questo confronto sulla macchina di ritorno da tagbyte.org . (La fonte originale è scomparsa, quindi ecco un link all'archivio Internet. Sì, è ancora possibile individuare pagine mancanti, persone.)
Ed ecco un'introduzione completa a QueryPath .
vantaggi
->find("a img, a object, div a")
Simple HTML DOM è un ottimo parser open-source:
Tratta gli elementi DOM in modo orientato agli oggetti e la nuova iterazione ha molta copertura per il codice non conforme. Ci sono anche alcune fantastiche funzioni come quelle che vedresti in JavaScript, come la funzione "trova", che restituirà tutte le istanze di elementi con quel nome di tag.
Ho usato questo in una serie di strumenti, testandolo su molti diversi tipi di pagine Web e penso che funzioni alla grande.
Un approccio generale che non ho visto menzionato qui è quello di eseguire HTML attraverso Tidy , che può essere impostato per sputare XHTML valido garantito. Quindi è possibile utilizzare qualsiasi vecchia libreria XML su di essa.
Ma per il tuo problema specifico, dovresti dare un'occhiata a questo progetto: http://fivefilters.org/content-only/ - è una versione modificata dell'algoritmo di leggibilità , che è progettata per estrarre solo il contenuto testuale (non le intestazioni e piè di pagina) da una pagina.
Per 1a e 2: voterei per la nuova classe del componente Symfony DOMCrawler ( DomCrawler ). Questa classe consente query simili ai selettori CSS. Dai un'occhiata a questa presentazione per esempi reali: news-of-the-symfony2-world .
Il componente è progettato per funzionare autonomamente e può essere utilizzato senza Symfony.
L'unico inconveniente è che funzionerà solo con PHP 5.3 o versioni successive.
Questo è comunemente indicato come raschiatura dello schermo , tra l'altro. La libreria che ho usato per questo è Simple HTML Dom Parser .
Abbiamo già creato alcuni crawler per le nostre esigenze. Alla fine della giornata, sono le semplici espressioni regolari a fare la cosa migliore. Mentre le librerie elencate sopra sono buone per il motivo per cui sono state create, se sai cosa stai cercando, le espressioni regolari sono un modo più sicuro di procedere, poiché puoi gestire anche strutture HTML / XHTML non valide , che fallirebbero se caricate tramite la maggior parte dei parser.
Raccomando PHP Simple HTML DOM Parser .
Ha davvero delle belle funzionalità, come:
foreach($html->find('img') as $element)
echo $element->src . '<br>';
Sembra una buona descrizione dell'attività della tecnologia XPath W3C . È facile esprimere query come "restituisce tutti gli href
attributi nei img
tag nidificati <foo><bar><baz> elements
". Non essendo un appassionato di PHP, non posso dirti in quale forma XPath potrebbe essere disponibile. Se è possibile chiamare un programma esterno per elaborare il file HTML, è possibile utilizzare una versione della riga di comando di XPath. Per una rapida introduzione, consultare http://en.wikipedia.org/wiki/XPath .
Sì, puoi utilizzare simple_html_dom allo scopo. Tuttavia ho lavorato parecchio con simple_html_dom, in particolare per la demolizione del web e l'ho trovato troppo vulnerabile. Fa il lavoro di base ma non lo consiglio comunque.
Non ho mai usato il ricciolo per lo scopo, ma quello che ho imparato è che il ricciolo può fare il lavoro in modo molto più efficiente ed è molto più solido.
Si prega di dare un'occhiata a questo link: scraping-website-with-curl
QueryPath è buono, ma fai attenzione allo "stato di tracciamento" perché se non ti rendi conto di cosa significhi, può significare che perdi molto tempo nel debug cercando di scoprire cosa è successo e perché il codice non funziona.
Ciò significa che ogni chiamata sul set di risultati modifica il set di risultati nell'oggetto, non è concatenabile come in jquery in cui ogni collegamento è un nuovo set, hai un singolo set che è i risultati della tua query e ogni chiamata di funzione modifica quel singolo set.
al fine di ottenere un comportamento simile a jquery, è necessario ramificarsi prima di eseguire un'operazione di filtro / modifica simile, ciò significa che rispecchierà molto più da vicino ciò che accade in jquery.
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$results
ora contiene il set di risultati per input[name='forename']
NON la query originale "div p"
che mi ha fatto innescare molto, quello che ho scoperto è che QueryPath tiene traccia dei filtri e trova e tutto ciò che modifica i risultati e li memorizza nell'oggetto. devi invece farlo
$forename = $results->branch()->find("input[name='forname']")
quindi $results
non verrà modificato e puoi riutilizzare il set di risultati ancora e ancora, forse qualcuno con molta più conoscenza può chiarire un po 'questo, ma fondamentalmente è così da quello che ho trovato.
Advanced Html Dom è una semplice sostituzione DOM HTML che offre la stessa interfaccia, ma è basata su DOM, il che significa che non si verificano problemi di memoria associati.
Ha anche il pieno supporto CSS, comprese le estensioni jQuery .
Ho scritto un parser XML generico che può facilmente gestire file GB. È basato su XMLReader ed è molto facile da usare:
$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
echo $tag->field1;
echo $tag->field2->subfield1;
}
Ecco il repository github: XmlExtractor
Ho creato una libreria chiamata PHPPowertools / DOM-Query , che ti permette di scansionare documenti HTML5 e XML proprio come fai con jQuery.
Sotto il cofano, utilizza symfony / DomCrawler per la conversione dei selettori CSS in selettori XPath . Utilizza sempre lo stesso DomDocument, anche quando passa un oggetto a un altro, per garantire prestazioni decenti.
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>');
[...]
La libreria include anche un proprio caricatore automatico a configurazione zero per librerie compatibili con PSR-0. L'esempio incluso dovrebbe funzionare immediatamente senza alcuna configurazione aggiuntiva. In alternativa, puoi usarlo con il compositore.
XML_HTMLSax
è piuttosto stabile, anche se non è più mantenuto. Un'altra opzione potrebbe essere quella di reindirizzare l'HTML tramite Html Tidy e quindi analizzarlo con strumenti XML standard.
Esistono molti modi per elaborare DOM HTML / XML di cui la maggior parte è già stata menzionata. Quindi, non tenterò di elencarli da solo.
Voglio semplicemente aggiungere che personalmente preferisco usare l'estensione DOM e perché:
E mentre mi manca la possibilità di utilizzare i selettori CSS per DOMDocument
, esiste un modo piuttosto semplice e conveniente per aggiungere questa funzione: sottoclasse DOMDocument
e aggiunta di JS querySelectorAll
e querySelector
metodi alla sottoclasse.
Per l'analisi dei selettori, consiglio di usare il componente CssSelector molto minimalista dal framework Symfony . Questo componente traduce semplicemente i selettori CSS in selettori XPath, che possono quindi essere inseriti in a DOMXpath
per recuperare la lista dei nomi corrispondente.
È quindi possibile utilizzare questa sottoclasse (di livello ancora molto basso) come base per classi di livello superiore, destinate ad es. analizzare tipi di XML molto specifici o aggiungere un comportamento più simile a jQuery.
Il codice qui sotto esce direttamente dalla mia libreria DOM-Query e usa la tecnica che ho descritto.
Per l'analisi HTML:
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);
}
}
}
}
[...]
}
Vedi anche Analisi di documenti XML con selettori CSS da parte del creatore di Symfony Fabien Potencier sulla sua decisione di creare il componente CssSelector per Symfony e su come usarlo.
Con FluidXML è possibile eseguire query e iterare XML utilizzando i selettori XPath e CSS .
$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 e array da XML in tre righe:
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
Ta da!
Esistono diversi motivi per non analizzare HTML mediante l'espressione regolare. Ma se hai il controllo totale su ciò che verrà generato HTML, puoi farlo con una semplice espressione regolare.
Sopra è una funzione che analizza HTML mediante espressione regolare. Nota che questa funzione è molto sensibile e richiede che l'HTML rispetti determinate regole, ma funziona molto bene in molti scenari. Se vuoi un parser semplice e non vuoi installare librerie, prova questo:
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/")));
Ho creato una libreria chiamata HTML5DOMDocument che è disponibile gratuitamente su https://github.com/ivopetkov/html5-dom-document-php
Supporta anche i selettori di query che ritengo estremamente utili nel tuo caso. Ecco un esempio di codice:
$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;
Se hai familiarità con il selettore jQuery, puoi utilizzare ScarletsQuery per PHP
<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);
Questa libreria richiede in genere meno di 1 secondo per elaborare l'html offline.
Accetta anche HTML non valido o citazione mancante sugli attributi dei tag.
Il metodo migliore per analizzare 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;
}