¿Cómo se analiza y procesa HTML / XML en PHP?


Answers

Pruebe Simple HTML DOM Parser

  • ¡Un analizador HTML DOM escrito en PHP 5+ que te permite manipular HTML de una manera muy fácil!
  • Requiere PHP 5+.
  • Admite HTML no válido.
  • Encuentra etiquetas en una página HTML con selectores al igual que jQuery.
  • Extrae contenido de HTML en una sola línea.
  • Descargar


Ejemplos:

Cómo obtener elementos HTML:

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


Cómo modificar elementos HTML:

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


Extrae contenido de HTML:

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


Scraping Slashdot:

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

¿Cómo se puede analizar HTML / XML y extraer información de él?




Simple HTML DOM es un gran analizador de código abierto:

simplehtmldom.sourceforge

Trata los elementos DOM de forma orientada a objetos, y la nueva iteración tiene una gran cobertura para el código no conforme. También hay algunas funciones geniales como las que vería en JavaScript, como la función "buscar", que devolverá todas las instancias de los elementos de ese nombre de etiqueta.

Lo he usado en varias herramientas, probándolo en muchos tipos diferentes de páginas web, y creo que funciona muy bien.




XML_HTMLSax es bastante estable, incluso si ya no se mantiene. Otra opción podría ser canalizar HTML a través de Html Tidy y luego analizarlo con herramientas XML estándar.




Advanced Html Dom es una simple sustitución HTML DOM que ofrece la misma interfaz, pero está basada en DOM, lo que significa que no se producen ninguno de los problemas de memoria asociados.

También tiene soporte completo de CSS, incluidas las extensiones de jQuery .




¿Por qué no deberías y cuándo deberías usar expresiones regulares?

En primer lugar, un nombre incorrecto común: Regexps no son para " analizar " HTML. Regexes sin embargo puede " extraer " datos. La extracción es para lo que están hechos. La principal desventaja de la extracción de HTML regex sobre los juegos de herramientas SGML adecuados o los analizadores sintácticos de línea de base es su esfuerzo sintáctico y fiabilidad variable.

Considere la posibilidad de hacer una expresión regular de extracción de HTML bastante fiable:

<a\s+class="?playbutton\d?[^>]+id="(\d+)".+?    <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?

es mucho menos legible que un simple equivalente phpQuery o QueryPath:

$div->find(".stationcool a")->attr("title");

Sin embargo, hay casos de uso específicos donde pueden ayudar.

  • Muchas interfaces frontales de DOM no revelan comentarios de HTML <!-- , que sin embargo son a veces los anclajes más útiles para la extracción. En particular, las variaciones pseudo-HTML <$var> o los residuos SGML son fáciles de dominar con expresiones regulares.
  • A menudo, las expresiones regulares pueden guardar el procesamiento posterior. Sin embargo, las entidades HTML a menudo requieren cuidado manual.
  • Y, por último, para tareas extremadamente simples como extraer <img src = urls, de hecho son una herramienta probable. La ventaja de la velocidad con respecto a los analizadores SGML / XML principalmente viene a jugar para estos procedimientos de extracción muy básicos.

A veces, incluso es aconsejable /<!--CONTENT-->(.+?)<!--END-->/ un fragmento de HTML con las expresiones regulares /<!--CONTENT-->(.+?)<!--END-->/ y procesar el resto utilizando las /<!--CONTENT-->(.+?)<!--END-->/ más sencillas del analizador de HTML.

Nota: De hecho, tengo esta aplicación , donde empleo el análisis XML y las expresiones regulares de forma alternativa. La semana pasada, el análisis de PyQuery se rompió y la expresión regular aún funcionaba. Sí raro, y no puedo explicarlo yo mismo. Pero así sucedió.
Así que, por favor, no voten por consideraciones del mundo real, simplemente porque no coinciden con el regex = evil meme. Pero tampoco votemos esto demasiado. Es solo una nota al margen de este tema.




Otra opción que puedes probar es QueryPath . Está inspirado en jQuery, pero en el servidor en PHP y se usa en Drupal .




Hemos creado bastantes rastreadores para nuestras necesidades antes. Al final del día, usualmente son simples expresiones regulares las que hacen mejor las cosas. Si bien las bibliotecas enumeradas arriba son buenas por la razón por la que se crearon, si usted sabe lo que está buscando, las expresiones regulares son una forma más segura de hacerlo, ya que también puede manejar estructuras HTML / XHTML no válidas, que fallarían, si se cargaran a través de la mayoría de los analizadores.




Sí, puedes usar simple_html_dom para este propósito. Sin embargo, he trabajado bastante con el simple_html_dom, particularmente para el web scrapping y he descubierto que es demasiado vulnerable. Hace el trabajo básico pero no lo recomendaré de todos modos.

Nunca utilicé curl para este propósito, pero lo que aprendí es que curl puede hacer el trabajo mucho más eficientemente y es mucho más sólido.

Por favor revisa este enlace: scraping-websites-with-curl




Esto suena como una buena descripción de la tarea de la tecnología W3C XPath . Es fácil expresar consultas como "devolver todos los atributos href en etiquetas img que están anidadas en elementos <foo><bar><baz> elements ". Como no soy un experto en PHP, no puedo decirte en qué forma puede estar disponible XPath. Si puede llamar a un programa externo para procesar el archivo HTML, debería poder usar una versión de línea de comando de XPath. Para una introducción rápida, vea http://en.wikipedia.org/wiki/XPath .




Hay varias razones para no analizar HTML por expresiones regulares. Pero, si tiene control total de qué HTML se generará, entonces puede hacerlo con expresiones regulares simples.

Arriba, es una función que analiza HTML por expresión regular. Tenga en cuenta que esta función es muy sensible y exige que el HTML obedezca ciertas reglas, pero funciona muy bien en muchos escenarios. Si desea un analizador simple y no desea instalar bibliotecas, pruebe esto:

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



He escrito un analizador XML de propósito general que puede manejar fácilmente archivos GB. Está basado en XMLReader y es muy fácil de usar:

$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
    echo $tag->field1;
    echo $tag->field2->subfield1;
}

Aquí está el repositorio github : XmlExtractor




Podría intentar usar algo como HTML Tidy para limpiar cualquier HTML "roto" y convertir el HTML a XHTML, que luego puede analizar con un analizador XML.




Para 1a y 2: votaría por la nueva clase Symfony Componet DOMCrawler ( DomCrawler ). Esta clase permite consultas similares a los selectores de CSS. Echa un vistazo a esta presentación para ver ejemplos del mundo real: news-of-the-symfony2-world .

El componente está diseñado para funcionar de forma independiente y se puede usar sin Symfony.

El único inconveniente es que solo funcionará con PHP 5.3 o posterior.