我有一个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>
因此我想导入数据库
我已经开始创建一个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;
非常感谢任何输入。
答案 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
模块会更好。