2012-10-31 37 views
1

我目前正在尝试使用WWW :: Mechanize创建一个Perl webspider。Perl机械化查找所有链接数组循环问题

我所试图做的是创建一个webspider将抓取URL(由用户输入)的整个网站,并提取所有的链接从网站上的每一页。

但是我有一个如何蜘蛛整个网站获得的每一个环节出了问题,没有重复 我迄今所做的(遇到问题的部分IM反正):

foreach (@nonduplicates) { #array contain urls like www.tree.com/contact-us, www.tree.com/varieties.... 
$mech->get($_); 
my @list = $mech->find_all_links(url_abs_regex => qr/^\Q$urlToSpider\E/); #find all links on this page that starts with http://www.tree.com 

#NOW THIS IS WHAT I WANT IT TO DO AFTER THE ABOVE (IN PSEUDOCODE), BUT CANT GET WORKING 
#foreach (@list) { 
#if $_ is already in @nonduplicates 
#then do nothing because that link has already been found 
#} else { 
#append the link to the end of @nonduplicates so that if it has not been crawled for links already, it will be 

我将如何能够做到以上?

我这样做是为了尝试和蜘蛛整个网站获取网站上的每个网址的全面列表,没有重复。

如果您认为这不是实现相同结果的最佳/最简单的方法,我愿意接受您的想法。

您的帮助非常感谢,谢谢。

+1

>>每个返回的链接是WWW ::机械化::链接对象。 –

+0

更好地使nonduplicates哈希,循环与它使用密钥,使url是一个关键 –

+0

你能告诉我一些示例代码来解释你的意思,感谢您的帮助 –

回答

1

创建一个哈希来跟踪链接,您以前见过,把任何看不见的人到@nonduplicates处理:

$| = 1; 
my $scanned = 0; 

my @nonduplicates = ($urlToSpider); # Add the first link to the queue. 
my %link_tracker = map { $_ => 1 } @nonduplicates; # Keep track of what links we've found already. 

while (my $queued_link = pop @nonduplicates) { 
    $mech->get($queued_link); 
    my @list = $mech->find_all_links(url_abs_regex => qr/^\Q$urlToSpider\E/); 

    for my $new_link (@list) { 
     # Add the link to the queue unless we already encountered it. 
     # Increment so we don't add it again. 
     push @nonduplicates, $new_link->url_abs() unless $link_tracker{$new_link->url_abs()}++; 
    } 
    printf "\rPages scanned: [%d] Unique Links: [%s] Queued: [%s]", ++$scanned, scalar keys %link_tracker, scalar @nonduplicates; 
} 
use Data::Dumper; 
print Dumper(\%link_tracker); 
+1

oops,这是一个错误。我已编辑修复它。您还需要使用某些东西来填充'@ nonduplicates',这可能只是开始的URL(请参阅编辑)。 – RobEarl

+0

非常感谢,这是一种享受。如果我只想打印出找到的每一个链接,或者将它们保存到一个文件中,那么最好的方法是什么? –

+0

此外,我发现一个问题,如果有一个错误获取网址失败,并退出它在做什么,例如http:/www.prodirectsoccer.com,谢谢 –

0
use List::MoreUtils qw/uniq/; 
... 

my @list = $mech->find_all_links(...); 

my @unique_urls = uniq(map { $_->url } @list); 

现在@unique_urls包含@list的唯一URL。