2010-09-13 166 views
1

我是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); 
     } 
    } 

    } 
} 

回答

2

使用WWW ::找到鏈接前,Mechanize的update_html方法刪除該表。這種方法允許你在$mech->content中做任何你想要的源代碼。

+0

謝謝!但事實證明,刪除維基頁面上的表格並不是一個非常準確的,更不用說有效的方式來實現我打算做的事情,因爲每個化學元素的維基頁面上的表格在它們的標籤中有不同的東西。所以很難概括所有頁面的表格刪除功能。我實際上最終使用HTML :: TreeBuilder查找

標籤內的鏈接(因爲我正在尋找的鏈接類型很可能出現在段落中)。它產生了更準確的結果並且運行速度非常快。 – 2010-09-15 02:46:39