Script para construir una página HTML a partir de DIV extraídos de otras páginas HTML

StackOverflow https://stackoverflow.com/questions/1211718

  •  06-07-2019
  •  | 
  •  

Pregunta

Tengo un conjunto de informes HTML que contienen cada uno dos elementos DIV con ID específicos que necesito eliminar y compilar en un informe resumen general (nuevamente, un archivo HTML).

Mis pensamientos iniciales son que este es un trabajo ideal para un script de Perl, sin embargo, no tenemos habilidades internas de Perl actualizadas (somos una tienda .NET C #).

Pensamientos y sugerencias sobre los enfoques recomendados serían bienvenidos ...

¿Fue útil?

Solución

Use un analizador HTML adecuado; hay HTML :: Parser para Perl y estoy seguro de que hay varios para C # como bien.

Otros consejos

Usando Perl, HTML :: TokeParser y HTML :: Template puede ayudar. Aquí hay un ejemplo rápido:

#!/usr/bin/perl

use strict;
use warnings;

use HTML::TokeParser;
use HTML::Template;

use Data::Dumper;

my ($html_file) = @ARGV;

open my $html_handle, '<:utf8', $html_file
    or die "Cannot open '$html_file': $!";

my $parser = HTML::TokeParser->new( $html_handle );

my @divs;

while ( my $tag = $parser->get_tag('div') ) {
    my $attr = $tag->[1];
    next unless ref $attr eq 'HASH';
    next unless defined( my $id = $attr->{id} );
    next unless $id eq 'div1' or $id eq 'div2';

    my $div = $tag->[-1];
    my $in_wanted = 1;

    while ( $in_wanted ) {
        my $token = $parser->get_token;
        if ( $token->[0] eq 'T' ) {
            $div .= $token->[1];
        }
        else {
            $div .= $token->[-1];
        }
        my ($type, $name) = @$token[0, 1];
        if ( $name eq 'div' ) {
            $in_wanted += $type eq 'S' ?  1
                        : $type eq 'E' ? -1
                        : 0;
            next;
        }
        if ( $type eq 'E' and $name eq 'html' ) {
            warn "Warning: Reached the end of '$html_file'\n";
            last;
        }
    }

    push @divs, {DIV => $div};
}

print output( @divs );

sub output {
    my $tmpl_html = <<EO_TMPL;
<html>
<body>
<TMPL_LOOP DIVS>
    <TMPL_VAR DIV>
</TMPL_LOOP>
</body>
</html>
EO_TMPL
    my $tmpl = HTML::Template->new(
        scalarref => \$tmpl_html,
    );
    $tmpl->param( DIVS => \@_ );
    return $tmpl->output;
}

Las expresiones regulares directas pueden no ser suficientes si su div contiene div anidados. Esto se debe a que el elemento div de cierre no contiene la ID, por lo que es difícil que una expresión regular coincida con la etiqueta de cierre.

Si su div es:

<div id="findme">
    <!-- No other divs here! -->
</div>

Entonces podrías usar una expresión regular (solo ten cuidado con la codicia), una versión más elegante de esto:

<div id="findme">(.*?)</div>

nota: estoy bastante seguro de que regexp no se ejecutará, ¡ha pasado un tiempo!

Buscaría usar una biblioteca de analizador HTML para analizar la estructura y obtener compensaciones de caracteres para el interior del div, y luego tomar ese rango del búfer. El uso de una biblioteca HTML le permitirá analizar y encontrar dónde termina el div que desea.

Algo así como este tutorial podría ser útil. Estos analizadores probablemente le permitirán extraer con precisión los datos incluidos en una etiqueta, como su div.

También puede utilizar un analizador HTML C # , todos hacen un trabajo similar, solo revise la documentación para asegurarse de que no solo construyan árboles y le permitan obtener compensaciones de caracteres para los datos div adjuntos (para que pueda extraerlos) o permitir el acceso a esos datos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top