Script pour construire une page HTML à partir d'extraits DIV extraits d'autres pages HTML

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

  •  06-07-2019
  •  | 
  •  

Question

J'ai un ensemble de rapports HTML contenant chacun deux éléments DIV avec des identifiants spécifiques que je dois supprimer et compiler dans un rapport de synthèse global (à nouveau, un fichier HTML).

Mes premières idées sont qu’il s’agit d’un travail idéal pour un script Perl. Cependant, nous n’avons aucune compétence Perl interne à jour (nous sommes un magasin .NET C #).

Des idées et suggestions sur les approches recommandées seraient les bienvenues ...

Était-ce utile?

La solution

Utilisez un analyseur HTML approprié. HTML :: Parser pour Perl et je suis sûr qu'il en existe plusieurs pour C # en tant que bien.

Autres conseils

Utilisation de Perl, HTML :: TokeParser et HTML :: Template peut vous aider. Voici un exemple rapide:

#!/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;
}

Les expressions rationnelles directes peuvent ne pas suffire si votre div contient des div imbriquées. Cela est dû au fait que l'élément div de fermeture ne contient pas l'ID, il est donc difficile pour une expression rationnelle de correspondre à la balise de fermeture.

Si votre div est:

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

Ensuite, vous pouvez utiliser une expression régulière (faites attention à la gourmandise), une version plus élégante de ceci:

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

note: je suis à peu près sûr que l'expression rationnelle ne fonctionnera pas, cela fait longtemps!

Je voudrais utiliser une bibliothèque d'analyse HTML pour analyser la structure et obtenir des décalages de caractères pour l'intérieur du div, puis utiliser cette plage dans la mémoire tampon. Utiliser une bibliothèque HTML vous permettra d’analyser et de trouver où se termine la div que vous voulez.

Quelque chose comme ce tutoriel pourrait être utile. Ces analyseurs vous permettront probablement d'extraire les données contenues dans une balise telle que votre div avec précision.

Vous pouvez également utiliser un analyseur syntaxique C # HTML . , ils font tous le même travail. Il suffit de parcourir la documentation pour s'assurer qu'ils ne construisent pas uniquement des arborescences et vous permettre d'obtenir des décalages de caractères pour les données div jointes (afin de pouvoir les extraire) ou de permettre l'accès ces données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top