如何在Perl中轻松地解析<div class ="foo">和</ div>

fro*_*hli 6 html perl parsing

我想将网站解析为Perl数据结构.首先我加载页面

use LWP::Simple;
my $html = get("http://f.oo");
Run Code Online (Sandbox Code Playgroud)

现在我知道两种方法来处理它.首先是正则表达式并对模块进行限制.

我开始阅读HTML :: Parser,并找到了一些例子.但我对Perl的知识并不确定.

我的代码示例继续

my @links;

my $p = HTML::Parser->new();
$p->handler(start => \&start_handler,"tagname,attr,self");
$p->parse($html);

foreach my $link(@links){
  print "Linktext: ",$link->[1],"\tURL: ",$link->[0],"\n";
}

sub start_handler{
  return if(shift ne 'a');
  my ($class) = shift->{href};
  my $self = shift;
  my $text;
  $self->handler(text => sub{$text = shift;},"dtext");
  $self->handler(end => sub{push(@links,[$class,$text]) if(shift eq 'a')},"tagname");
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么有两次换班.secound应该是自我指针.但第一个让我觉得自我引用已经全部变为shiftet,用作Hash并且href的值存储在其中$class.有人可以解释这一行(my ($class) = shift->{href};吗?

除了这种缺乏,我不想来解析所有的URL,我想把之间的所有代码<div class ="foo"></div>成一个字符串,其中大量的代码之间,特别是其他<div></div>标签.所以我或模块必须找到正确的结束.之后,我计划再次扫描字符串,找到特殊的类,比如<h1>,<h2>, <p class ="foo2"></p>等.

我希望这些信息可以帮助你给我一些有用的建议,请记住,首先我想要一个简单的理解方式,这在第一级不是一个很好的表现!

Sin*_*nür 5

使用HTML :: TokeParser :: Simple.

未经测试的代码基于您的描述:

#!/usr/bin/env perl

use strict; use warnings;

use HTML::TokeParser::Simple;

my $p = HTML::TokeParser::Simple->new(url => 'http://example.com/example.html');

my $level;

while (my $tag = $p->get_tag('div')) {
    my $class = $tag->get_attr('class');
    next unless defined($class) and $class eq 'foo';

    $level += 1;

    while (my $token = $p->get_token) {
        $level += 1 if $token->is_start_tag('div');
        $level -= 1 if $token->is_end_tag('div');
        print $token->as_is;
        unless ($level) {
            last;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


ike*_*ami 5

HTML :: Parser更像是一个tokenizer而不是一个解析器.这给你留下了很多艰苦的工作.您是否考虑过使用HTML :: TreeBuilder(使用HTML :: Parser)或XML :: LibXML(一个支持HTML的优秀库)?


Ama*_*dan 1

根据文档,处理程序的签名是(\%attr, \@attr_seq, $text). 共有三班,每个论点轮班一次。

my ($class) = shift->{href};
Run Code Online (Sandbox Code Playgroud)

相当于:

my $class;
my %attr_seq;
my $attr_seq_ref;

$attr_seq_ref = shift;
%attr_seq = %$attr_seq_ref;
$class = $attr_seq{'href'};
Run Code Online (Sandbox Code Playgroud)