使用Perl从html解析特定文本

时间:2011-07-06 14:56:09

标签: html database perl extract

我有一个html页面,其中包含我想使用Perl脚本解析为数据库的特定文本。

我希望能够剥离所有我不想要的东西,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. 姓名:John Smith。
  2. 住在:英格兰。
  3. 评论:C#比Visula Basic更好吗?
  4. 我已经开始创建一个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 个答案:

答案 0 :(得分:6)

请不要使用正则表达式来解析HTML,因为 HTML不是常规语言正则表达式描述常规语言。

使用HTML::TreeBuilder(及其模块系列)解析HTML很容易:

#!/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 查看answered已为ADW

答案 1 :(得分:4)

使用HTML解析器(如HTML::TreeBuilder)来解析HTML - 不要自己动手。

此外,不要使用带有全局句柄的双arg打开,不要使用chop - 使用chomp(阅读perldoc to understand why)。找一个更新的教程。你正在使用大量旧OLD OLD Perl。和该死的,使用STRICT和使用警告。我 知道 您被告知要这样做。做吧。离开它只会给你带来痛苦。

Go. Read. Modern Perl. It is free.

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或数据库或您真正想要做的任何事情。你似乎试图做到这两点。

答案 2 :(得分:1)

使用CPAN中的HTML::Parser模块会更好。