Script per creare una pagina HTML da DIV estratti da altre pagine HTML
-
06-07-2019 - |
Domanda
Ho una serie di report HTML che contengono ciascuno due elementi DIV con ID specifici che devo rimuovere e compilare in un report di riepilogo generale (di nuovo, un file HTML).
Il mio pensiero iniziale è che questo è un lavoro ideale per uno script Perl, tuttavia non abbiamo competenze Perl interne aggiornate (siamo un negozio .NET C #).
Pensieri e suggerimenti sugli approcci raccomandati sarebbero i benvenuti ...
Soluzione
Utilizza un parser HTML adatto; c'è HTML :: Parser per Perl e sono sicuro che ce ne sono molti per C # as bene.
Altri suggerimenti
Utilizzo di Perl, HTML :: TokeParser e HTML :: Template può aiutarti. Ecco un breve esempio:
#!/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;
}
Le espressioni regolari semplici potrebbero non essere sufficienti se il div contiene div nidificati. Questo perché l'elemento div di chiusura non contiene l'ID, quindi è difficile che un regexp corrisponda al tag di chiusura.
Se il tuo div è:
<div id="findme">
<!-- No other divs here! -->
</div>
Quindi potresti usare un'espressione regolare (fai solo attenzione all'avidità), una versione più elegante di questo:
<div id="findme">(.*?)</div>
nota: sono abbastanza sicuro che regexp non funzionerà, è passato del tempo!
Vorrei esaminare l'uso di una libreria di parser HTML per analizzare la struttura e ottenere offset dei caratteri per l'interno del div, quindi prendere quell'intervallo dal buffer. L'uso di una libreria HTML ti permetterà di analizzare e trovare dove finisce il div che desideri.
Qualcosa come questo tutorial potrebbe essere utile. Questi parser probabilmente ti permetteranno di estrarre accuratamente i dati racchiusi in un tag come il tuo div.
Puoi anche utilizzare un parser HTML C # , fanno tutti un lavoro simile, basta guardare attraverso la documentazione per assicurarsi che non si limitino a costruire alberi e permettervi di ottenere offset dei caratteri per i dati div racchiusi (in modo da poterli estrarre) o consentire l'accesso a tali dati.