1

現在、 WWW::Mechanize を使用して Perl webspider を作成しようとしています。

私がやろうとしているのは、(ユーザーが入力した) URL のサイト全体をクロールし、サイトのすべてのページからすべてのリンクを抽出する webspider を作成することです。

しかし、重複することなく、すべてのリンクを取得するためにサイト全体をスパイダーする方法に問題があります

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 

上記をどのように行うことができますか?

私はこれを行って、サイト全体をスパイダーして、サイト上のすべての URL の包括的なリストを重複なしで取得しようとしています。

これが同じ結果を達成する最良/最も簡単な方法ではないと思われる場合は、私はアイデアを受け入れます.

あなたの助けは大歓迎です、ありがとう。

4

2 に答える 2

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);
于 2012-10-31T21:21:04.327 に答える
0
use List::MoreUtils qw/uniq/;
...

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

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

@unique_urlsからの一意の URL が含まれるようになりました@list

于 2012-10-31T21:11:52.470 に答える