henka has asked for the wisdom of the Perl Monks concerning the following question:

Any pointers on the following would be appreciated. The code below correctly displays the links for a given HTML file. However, (between the #####s) I would like to add callbacks for (eg) the <title> tag, and display it's text as well. The $attr->{href}; line will obviously not display the text for a <title> tag, but what will? The print Dumper($attr); line shows no argument coming through for the title tag... Thanks henka
#!/usr/bin/perl -w # This program will print out all <a href=".."> links in a # document together with the text that goes with it. use HTML::Parser; use Data::Dumper; my $p = HTML::Parser->new(api_version => 3, start_h => [\&a_start_handler, "self,tagname,attr"], ##### report_tags => [qw(a img mailto title)], ##### ); $p->parse_file(shift || die) || die $!; sub a_start_handler { my($self, $tag, $attr) = @_; return unless $tag eq "a" || $tag eq "img" || $tag eq "mailto" || ##### $tag eq "title"; ##### print Dumper($attr); # display args return unless exists $attr->{href}; print "A $attr->{href}\n"; $self->handler(text => [], '@{dtext}' ); $self->handler(start => \&img_handler); $self->handler(start => \&mailto_handler); ##### $self->handler(start => \&title_handler); ##### $self->handler(end => \&a_end_handler, "self,tagname"); } ##### sub title_handler { my($self, $tag, $attr) = @_; return unless $tag eq "title"; push(@{$self->handler("text")}, $attr->{alt} || "[TITLE]"); } ##### sub img_handler { my($self, $tag, $attr) = @_; return unless $tag eq "img"; push(@{$self->handler("text")}, $attr->{alt} || "[IMG]"); } sub mailto_handler { my($self, $tag, $attr) = @_; return unless $tag eq "mailto"; push(@{$self->handler("text")}, $attr->{alt} || "[MAILTO]"); } sub a_end_handler { my($self, $tag) = @_; my $text = join("", @{$self->handler("text")}); $text =~ s/^\s+//; $text =~ s/\s+$//; $text =~ s/\s+/ /g; print "T $text\n"; $self->handler("text", undef); $self->handler("start", \&a_start_handler); $self->handler("end", undef); }

Replies are listed 'Best First'.
Re: HTML::Parser help
by wfsp (Abbot) on Jul 10, 2006 at 13:29 UTC
    This prints out the title, anchor hrefs and link text.

    As was pointed out in the CB you can only have one start handler at a time.

    Hopefully this is enough to get you started.

    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; use HTML::Parser; my $p = HTML::Parser->new( api_version => 3, start_h => [\&title_start, "self, tagname"], ); $p->unbroken_text(1); $p->parse_file('home.html'); sub title_start { my ($p, $tag) = @_; return unless $tag eq 'title'; $p->handler('text' => \&title_text, "self, text") } sub title_text { my ($p, $txt) = @_; print "title: $txt\n"; $p->handler('start' => \&link_start, "self, tag, attr"); $p->handler('text' => ''); } sub link_start { my ($p, $tag, $attr) = @_; return unless $tag eq 'a'; print "link: $attr->{href}\n"; $p->handler('text' => \&link_text, "self, text") } sub link_text { my ($p, $text) = @_; print "link text: $text\n"; # switch off text handler $p->handler('text' => ""); }

    Update:
    And I still maintain you'll have a hard time finding mailto tags. ;-)

      Thank you very much - I'll give it a swing.