Скрипт для построения HTML-страницы из извлеченных DIV из других HTML-страниц
-
06-07-2019 - |
Вопрос
У меня есть набор отчетов в формате HTML, каждый из которых содержит два элемента DIV с определенными идентификаторами, которые мне нужно вырезать и скомпилировать в общий сводный отчет (опять же, файл HTML).
Вначале я думал, что это идеальная работа для скрипта Perl, однако у нас нет современных внутренних навыков Perl (мы - магазин .NET C #).
Мысли и предложения о рекомендуемых подходах приветствуются ...
Решение
Используйте подходящий анализатор HTML; есть HTML :: Parser для Perl, и я уверен, что есть несколько для C #, так как хорошо.
Другие советы
Используя Perl, HTML :: TokeParser и HTML :: Template может помочь. Вот быстрый пример:
#!/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;
}
Прямых регулярных выражений может быть недостаточно , если ваш div содержит вложенные div. Это потому, что закрывающий элемент div не содержит идентификатора, поэтому регулярному выражению трудно сопоставить закрывающий тег.
Если ваш div это
<div id="findme">
<!-- No other divs here! -->
</div>
Тогда вы можете использовать регулярное выражение (просто будьте осторожны с жадностью), более элегантную версию этого:
<div id="findme">(.*?)</div>
примечание: я почти уверен, что регулярное выражение не запустится, это было давно!
Я хотел бы изучить использование библиотеки синтаксического анализатора HTML для анализа структуры и получения смещений символов для внутренней части div, а затем взять этот диапазон из буфера. Использование библиотеки HTML позволит вам проанализировать и найти, где заканчивается Div, который вы хотите.
Что-то вроде этого учебника Может быть полезно. Эти парсеры, вероятно, позволят вам точно извлечь данные, заключенные в тег, такой как ваш div. Р>
Вы также можете использовать синтаксический анализатор C # HTML , все они выполняют одинаковую работу. Просто просмотрите документацию, чтобы убедиться, что они не просто строят деревья, и позволяют получать смещения символов для вложенных данных div (чтобы вы могли извлечь их), или разрешите доступ к эти данные.