2012-07-04 10 views
6

Mantengo una base de datos de artículos con formato HTML. Por desgracia los editores que escribieron artículos no saber HTML adecuado, por lo que a menudo tienen cosas escritas como:Cómo analizar HTML no válido con Perl?

<div class="highlight"><html><head></head><body><p>Note that ...</p></html></div> 

Intenté usar HTML::TreeBuilder para analizar este código HTML pero después de analizarlo y volcar el árbol resultante, entre todos los elementos <div class="highlight">...</div> se han ido. Me quedé solo con <div class="highlight"></div>.

los editores a menudo, también lo han hecho cosas como:

<div class="article"><style>@font-face { font-family: "Cambria"; }</style>Article starts here</div> 

análisis sintáctico esto con HTML::TreeBuilder resultados en vacío <div class="article"></div> nuevo.

¿Alguna idea de cómo abordar este HTML roto y, de hecho, darle sentido?

+0

¿Has probado mirarlo como xml? Puede que no sea un html válido, pero es posible que puedas separarlo usando xpath. –

+4

@BartonChittenden Buena suerte con eso. –

Respuesta

11

yo primero ejecutarlo a través de HTML::Tidy:

#!/usr/bin/env perl 

use strict; use warnings; 
use HTML::Tidy; 

my $html = <<EO_HTML; 
<div class="highlight"><html><head></head> 
<body><p>Note that ...</p></html> 
</div> 
EO_HTML 

my $tidy = HTML::Tidy->new; 

print $tidy->clean($html); 

Salida:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> 
<html> 
<head> 
<meta name="generator" content="tidyp for Windows (v1.04), see www.w3.org"> 
<title></title> 
</head> 
<body> 
<div class="highlight"> 
<p>Note that ...</p> 
</div> 
</body> 
</html> 

Usted puede controlar la salida mediante el establecimiento de diversas opciones de configuración.

Luego, alimente el HTML limpio a través de un analizador.

De lo contrario, puede intentar construir un árbol de un paso a la vez con HTML::TokeParser::Simple o incluso solo HTML::Parser, pero creo que eso es una locura.

Tenga en cuenta que un analizador que intente construir una representación de árbol será más estricto que un analizador de flujo que solo reconoce varios elementos como los ve.

-1

Suena como Tag soup. Como otro enfoque, también puede usar el programa java "html-tagsoup" desde dentro de su programa perl (con patillas, por ejemplo). Se puede llamar como un programa independiente como este.

java -jar tagsoup-1.2.1 [option ...] [file ...] 

HTML :: Tidy solía ser mejor o más flexible, creo.

1

XML::LibXML es también, quizás sorprendentemente, bueno en este tipo de limpieza si se usa correctamente. También es extremadamente rápido; y profundo/flexible una vez que superas su curva de aprendizaje.

#!/usr/bin/env perl 
use strictures; 
use XML::LibXML; 

my @craptastic = ('<div class="article"><style>@font-face{ font-family: "Cambria" }</style>Article starts here</div>', 
        '<div class="highlight"><html><head></head><body><p>Note that ...</p></html></div>'); 

# The inline setting of recover_silently is broken/non-functional so 
# we do the method calls to set. 
my $parser = XML::LibXML->new(); 
$parser->recover_silently(1); 
$parser->keep_blanks(1); 

for my $crap (@craptastic) 
{ 
    my $doc = $parser->load_html(string => $crap); 

    # Optional example for killing style tags not in the <head/> 
    $_->parentNode->removeChild($_) for $doc->findnodes("//body//style"); 

    print $/, $crap, $/; 
    my ($body) = $doc->findnodes("//body"); 
    print "-" x 60, $/; 
    print $_->serialize(1) for $body->childNodes; 
    print $/, $/; 
} 

que –

<div class="article"><style>@font-face{ font-family: "Cambria" }</style>Article starts here</div> 
------------------------------------------------------------ 
<div class="article">Article starts here</div> 


<div class="highlight"><html><head></head><body><p>Note that ...</p></html></div> 
------------------------------------------------------------ 
<div class="highlight"> 
    <p>Note that ...</p> 
</div> 
+1

+1 Eso es realmente sorprendente. –

3

Usted puede tratar de utilizar Marpa::HTML, que es un analizador de HTML de alto nivel, lo que permite el análisis extremadamente liberal da. Puede analizar incluso HTML no válido utilizando la técnica llamada ruby ​​slippers por su autor; Marpa :: HTML agrega elementos que deberían estar ahí.

Vea un ejemplo de reformatear, embellecer y hacer válido el ejemplo de HTML no válido en How to Parse HTML publicación de blog por Jeffrey Kegler, autor de Marpa y Marpa :: HTML.

Cuestiones relacionadas