Skript HTML-Seite aus von extrahierten DIVs aus anderen HTML-Seiten erstellen
-
06-07-2019 - |
Frage
Ich habe eine Reihe von HTML-Berichte, dass enthalten jeweils zwei DIV-Elemente mit bestimmten IDs, die ich brauche in einen Gesamtbericht strippen und kompilieren (wiederum eine HTML-Datei).
Meine erste Gedanken sind, dass dies ein idealer Job für einen Perl-Skript ist, aber wir haben nicht up-to-date in-house Perl Fähigkeiten (wir sind ein .NET C # Shop).
Die Gedanken und Vorschläge zu empfohlenen Ansätzen begrüßt werden würden ...
Lösung
Mit einem geeigneten HTML-Parser; gibt es HTML :: Parser für Perl und ich bin sicher, es gibt mehr für C # als gut.
Andere Tipps
Mit Perl, HTML :: TokeParser und HTML :: Template helfen können. Hier ist ein kleines Beispiel:
#!/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;
}
Unkomplizierte reguläre Ausdrücke können nicht genug sein , wenn Ihr div verschachtelten divs enthält. Dies liegt daran, das Schließen div-Element nicht die ID enthält, so ist es schwer für einen regulären Ausdruck des Schließschild entsprechen.
Wenn Ihr div ist:
<div id="findme">
<!-- No other divs here! -->
</div>
Dann könnten Sie einen regulären Ausdruck verwenden (nur vorsichtig sein, etwa greediness), eine elegantere Version davon:
<div id="findme">(.*?)</div>
Hinweis: Im ziemlich sicher, dass regexp wird nicht ausgeführt, es ist eine Weile gewesen
!Ich würde schauen in einer HTML-Parser-Bibliothek mit der Struktur zu analysieren und Zeichen-Offsets für das Innere des div zu erhalten, und dann aus dem Puffer diesen Bereich übernehmen. eine HTML-Bibliothek ermöglicht es Ihnen, wo die div Sie Ende wollen zu analysieren und finden.
So etwas wie dieses Tutorial könnte nützlich sein. Diese Parser wird wahrscheinlich können Sie die Daten in einem Tag wie Ihre div genau eingeschlossen extrahieren.
Sie können auch einen C # HTML-Parser , sie alle einen ähnlichen Job machen, schauen Sie einfach durch die Dokumentation, um sicherzustellen, dass sie nicht nur Bäume gebaut, und ermöglicht es Ihnen, Zeichen-Offsets für die eingeschlossenen div Daten zu erhalten (so können Sie es extrahieren) oder erlauben den Zugriff auf dass Daten.