开发者

How can I extract HTML img tags wrapped in anchors in Perl?

I am working on parsing HTML obtain all the hrefs that match a particular url (let's call it "target url") and then get the anchor text. I have tried LinkExtractor, TokenParser, Mechanize, TreeBuilder modules. For below HTML:

 <a href="target_url">
 <img src=somepath/nw.gf alt="Open this result in new window"> 
 </a>

all of them give "Open this result in new window" as the anc开发者_JS百科hor text. Ideally I would like to see blank value or a string like "image" returned so that I know there was no anchor text but the href still matched the target url (http://www.yahoo.com in this case). Is there a way to get the desired result using other module or Perl regex?

Thanks,


You should post some examples that you tried with "LinkExtractor, TokenParser, Mechanize & TreeBuilder" so that we can help you.

Here is something which works for me in pQuery:

use pQuery;

my $data = '
  <html>
    <a href="http://www.something.com">Not yahoo anchor text</a>
    <a href="http://www.yahoo.com"><img src="somepath/nw.gif" alt="Open this result in new window"></img></a>
    <a href="http://www.yahoo.com">just text for yahoo</a>
    <a href="http://www.yahoo.com">anchor text only<img src="blah" alt="alt text"/></a>
  </html>
';

pQuery( $data )->find( 'a' )->each(
    sub {
        say $_->innerHTML 
            if $_->getAttribute( 'href' ) eq 'http://www.yahoo.com';
    }
);

# produces:
#
# => <img alt="Open this result in new window" src="somepath/nw.gif"></img>
# => just text for yahoo
# => anchor text only<img /="/" alt="alt text" src="blah"></img>
#

And if you just want the text:

pQuery( $data )->find( 'a' )->each(
    sub {
        return unless $_->getAttribute( 'href' ) eq 'http://www.yahoo.com';

        if ( my $text = pQuery($_)->text ) { say $text }
    }
);

# produces:
#
# => just text for yahoo
# => anchor text only
#

/I3az/


Use a proper parser (like HTML::Parser or HTML::TreeBuilder). Using regular expressions to parse SGML (HTML/XML included) isn't really all that effective because of funny multiline tags and attributes like the one you've run into.


If the HTML you are working with is fairly close to well formed you can usually load it into an XML module that supports HTML and use it to find and extract data from the parts of the document you are interested in. My method of choice is XML::LibXML and XPath.

use XML::LibXML;

my $parser = XML::LibXML->new();
my $html = ...;
my $doc = $parser->parse_html_string($html);

my @links = $doc->findnodes('//a[@href = "http://example.com"]');
for my $node (@links) {
    say $node->textContent();
}

The string passed to findnodes is an XPath expression that looks for all 'a' element descendants of $doc that have an href attribute equal to "http://example.com".

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜