从HTML页面提取所有链接,排除特定表格中的链接

问题描述:

我是Perl/HTML的新手。这里就是我想用WWW::MechanizeHTML::TreeBuilder做:从HTML页面提取所有链接,排除特定表格中的链接

为维基百科的每个化学元素的一页,我需要提取指向其他化学元素页面上的wiki的所有超链接并打印出每个独特的对这个格式:

Atomic_Number1 (Chemical Element Title1) -> Atomic_Number2 (Chemical Element Title2) 

唯一的问题是每个化学元素的页面(页面的右上角)都有一个迷你的元素周期表。所以这个小小的元素周期表就会使每个元素的结果都一样。我无法从表格中提取页面中的所有链接。

[注:我只能看着$elem == 6(碳)(@line 42)为便于调试。]


这里是我的代码:

#!/usr/bin/perl -w 

use strict; 
use warnings; 
use WWW::Mechanize; 
use HTML::TreeBuilder; 
my $mech = WWW::Mechanize->new(autocheck => 1); 

$mech = WWW::Mechanize->new(); 

my $table_url = "http://en.wikipedia.org/wiki/Periodic_table"; 

$mech->agent('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-us)/
       AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 /
       Safari/533.17.8'); 

$mech->get($table_url); 

my $tree = HTML::TreeBuilder->new_from_content($mech->content); 
my %elem_set; 
my $atomic_num; 

## obtain a hash array of elements and corresponding titles and links 
foreach my $td ($tree->look_down(_tag => 'td')) { 

    # If there's no <a> in this <td>, then skip it: 
    my $a = $td->look_down(_tag => 'a') or next; 

    my $tdText = $td->as_text; 
    my $aText = $a->as_text; 

    if($tdText =~ m/^(\d+)\S+$/){ 
    if($1 <= 114){ #only investigate up to 114th element 
     $atomic_num = $1; 
    } 
    $elem_set{$atomic_num} = [$a->attr('title'), $a->attr('href')]; 
    } 
} 

## In each element's page. look for links to other elements in the set 
foreach my $elem (keys %elem_set) { 
    if($elem == 6){ 
    # reconstruct element url to ensure only fetch pages in English 
    my $elem_url = "http://en.wikipedia.org" . $elem_set{$elem}[1]; 
    $mech->get($elem_url); 

    ##################################################################### 
    ### need help here to exclude links from that mini periodic table ### 
    ##################################################################### 

    my @target_links = $mech->links(); 
    for my $link (@target_links) { 
     if($link->url =~ m/^\/(wiki)\/.+$/ && $link->text =~ m/^\w+$/){ 
     printf("%s, %s\n", $link->text, $link->url); 
     } 
    } 

    } 
} 

使用WWW ::找到链接前,Mechanize的update_html方法删除该表。这种方法允许你在$mech->content中做任何你想要的源代码。

+0

谢谢!但事实证明,删除维基页面上的表格并不是一个非常准确的,更不用说有效的方式来实现我打算做的事情,因为每个化学元素的维基页面上的表格在它们的标签中有不同的东西。所以很难概括所有页面的表格删除功能。我实际上最终使用HTML :: TreeBuilder查找

标签内的链接(因为我正在寻找的链接类型很可能出现在段落中)。它产生了更准确的结果并且运行速度非常快。 – 2010-09-15 02:46:39