Разбор конкретного текста из HTML, используя Perl - PullRequest
1 голос
/ 06 июля 2011

У меня есть HTML-страница с определенным текстом, который я хочу проанализировать в базе данных, используя Perl Script.

Я хочу иметь возможность отбросить все, что мне не нужно, пример html--

<div class="postbody">
        <h3><a href "foo">Re: John Smith <span class="posthilit">England</span></a></h3>
        <div class="content">Is C# better than Visula Basic?</div>
    </div>

Поэтому я бы хотел импортировать в базу данных

  1. Имя: Джон Смит.
  2. Живет в: Англии.
  3. Комментарий: C # лучше, чем Visula Basic?

Я начал создавать сценарий Perl, но его нужно изменить, чтобы он работал для того, что я хочу;

    use DBI;

    open (FILE, "list") || die "couldn't open the file!";

    open (F1, ">list.csv") || die "couldn't open the file!";

    print F1 "Name\|Lives In\|Commented\n";

    while ($line=<FILE>)

    {

    chop($line);
    $text = "";
    $add = 0;
    open (DATA, $line) || die "couldn't open the data!";
    while ($data=<DATA>)

    {
    if ($data =~ /ds\-div/)
    {
    $data =~ s/\,//g;
    $data =~ s/\"//g;
    $data =~ s/\'//g;
    $text = $text . $data;
    }

    }

    @p = split(/\\/, $line);
    print F1 $p[2];
    print F1 ",";
    print F1 $p[1];
    print F1 ",";
    print F1 $p[1];
    print F1 ",";  

    print F1 "\n";
    $a = $a + 1;

Любая информация будет принята с благодарностью.

Ответы [ 3 ]

6 голосов
/ 06 июля 2011

Пожалуйста, не используйте регулярные выражения для разбора HTML, так как HTML не является регулярным языком . Регулярные выражения описывают обычные языки.

Анализировать HTML с помощью HTML::TreeBuilder (и его семейства модулей) легко:

#!/usr/bin/env perl

use warnings;
use strict;

use HTML::TreeBuilder;

my $tree = HTML::TreeBuilder->new_from_content(
    do { local $/; <DATA> }
);

for ( $tree->look_down( 'class' => 'postbody' ) ) {
    my $location = $_->look_down( 'class' => 'posthilit' )->as_trimmed_text;
    my $comment  = $_->look_down( 'class' => 'content' )->as_trimmed_text;
    my $name     = $_->look_down( '_tag'  => 'h3' )->as_trimmed_text;
    $name =~ s/^Re:\s*//;
    $name =~ s/\s*$location\s*$//;

    print "Name: $name\nLives in: $location\nCommented: $comment\n";
}

__DATA__
<div class="postbody">
    <h3><a href="foo">Re: John Smith <span class="posthilit">England</span></a></h3>
    <div class="content">Is C# better than Visual Basic?</div>
</div>

Вывод

Name: John Smith
Lives in: England
Commented: Is C# better than Visual Basic?

Однако, если вам требуется гораздо больше контроля, взгляните на HTML::Parser, как уже было ответ от ADW .

4 голосов
/ 06 июля 2011

Используйте синтаксический анализатор HTML, например HTML :: TreeBuilder , чтобы анализировать HTML - не делайте этого сами.

Кроме того, не используйте открытое двух аргументов с глобальнымручки, не используйте chop - используйте chomp (прочитайте perldoc, чтобы понять, почему ).Найдите себе новый учебник.Вы используете тонну старых старых Perl.И блин, ИСПОЛЬЗУЙТЕ СТРОГО и ИСПОЛЬЗУЙТЕ ПРЕДУПРЕЖДЕНИЯ.Я знаю вам сказали сделать это.Сделай это.Отказ от этого ничего не даст, но принесет вам боль.

Go.Читать.Современный Perl.Это бесплатно.

my $page = HTML::TreeBuilder->new_from_file( $file_name );
$page->elementify;

my @posts;
for my $post ( $page->look_down( class => 'postbody' ) ) {

    my %post = (
        name    => get_name($post),
        loc     => get_loc($post),
        comment => get_comment($post),
    );

    push @posts, \%post;
}

# Persist @posts however you want to.

sub get_name {
    my $post = shift;
    my $name = $post->look_down( _tag => 'h3' );
    return unless defined $name;

    $name->look_down->(_tag=>'a');
    return unless defined $name;        

    $name = ($name->content_list)[0];
    return unless defined $name;        

    $name =~ s/^Re:\s*//;
    $name =~ /\s*$//;

    return $name;
}

sub get_loc {
    my $post = shift;
    my $loc = $post->look_down( _tag => 'span', class => 'posthilit' );

    return unless defined $loc;

    return $loc->as_text;
}

sub get_comment {
    my $post = shift;
    my $com = $post->look_down( _tag => 'div', class => 'content' );

    return unless defined $com;

    return $com->as_text;
}

Теперь у вас есть хорошая структура данных со всеми вашими почтовыми данными.Вы можете записать это в CSV или базу данных, или что угодно, что вы действительно хотите сделать.Вы, кажется, пытаетесь сделать и то и другое.

1 голос
/ 06 июля 2011

Было бы намного лучше, если бы вы использовали модуль HTML::Parser из CPAN.

...