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 ...

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top