QUOTE(Cbeppe @ 31 Oct, 2009 - 06:12 PM)

Ok, I suddenly got this beautiful idea to disregard your tip and use an array instead. Mostly because I have no clue how to do it with a hash.
The problem with using an array here (aside from your implementation of it not working

) is that checking an array to see whether it contains a value requires you to check the first value in the array to see if it matches, then check the second for a match, then the third, and so on. You can use the "grep" command to automate this, but, if you've got more than a handful of items in the array, it gets a bit slow. With a hash, you can determine whether a value is there or not just as quickly, no matter how many or how few values it contains.
The main advantage of arrays over hashes is that arrays maintain the order of their contents, while hashes will rearrange them into a random order. (Not really random, actually, but unpredictable enough that you may as well treat it as random for most purposes.) So use arrays when you care about the order of things and hashes when you only care whether it's there or not.
QUOTE(Cbeppe @ 31 Oct, 2009 - 06:12 PM)

As you can see, the point of it is to push the link it just visited to the new array called "@visited". Then when it comes back around, it checks to see if "$url" and "@visited" matches, and if they do, it is supposed to skip to the next part.
...except that's not what it checks.
CODE
if ($url = @visited){
has two problems:
1) "Context" is a big deal in Perl and, because $url is a scalar, that expression is evaluated in "scalar context" - basically, $url only holds a single value, so @visited gets turned into a single value so they can interact with each other. When you evaluate an array in scalar context like that, you get the number of items in the array. e.g., If @visited contains ('foo', 'bar', 'baz'), then @visited will become the value 3 in scalar context.
2) "=" is the assignment operator, so it's not comparing $url and @visited at all, it's getting the number of items in @visited and assigning that value to $url. With the sample array from the last paragraph, this would be equivalent to "if ($url = 3)". The end result is that this expression will be true (causing the program to die) if there's anything in @visited and false (causing $url to be set to 0, which leads to your "error 400") if @visited is empty. You need to use "eq" to compare strings with each other: "if ($url eq $other_url)"
So... First, here's a working way to determine whether $url is in @visited:
CODE
if (grep { $_ eq $url } @visited) {
The grep function will assign each element of the target list (@visited) to $_ in turn and return those elements where "$_ eq $url" is true. But, like I mentioned above, this will get slower and slower as @visited grows, since it needs to check each value in the array individually.
Now that you know how to do that, here's how I would do the duplicate check using a hash:
CODE
my @urls = ('http://computersecrets.eu.pn/');
my %visited; # The % sigil indicates it's a hash
my $browser = LWP::UserAgent->new();
$browser->timeout(5);
while (@urls) {
my $url = shift @urls;
# Skip this URL and go on to the next one if we've
# seen it before
next if $visited{$url};
my $request = HTTP::Request->new(GET => $url);
my $response = $browser->request($request);
# No real need to invoke printf if we're not doing
# any formatting
if ($response->is_error()) {print $response->status_line, "\n";}
my $contents = $response->content();
# Now that we've got the url's content, mark it as
# visited
$visited{$url} = 1;
my ($page_parser) = HTML::LinkExtor->new(undef, $url);
$page_parser->parse($contents)->eof;
my @links = $page_parser->links;
foreach my $link (@links) {
print "$$link[2]\n";
push @urls, $$link[2];
}
sleep 60;
}