2 votes

Optimisation des moteurs de recherche

Je suis en train de construire un moteur de recherche de base en utilisant le modèle d'espace vectoriel et c'est le crawler qui retourne 500 URLs et enlève les balises SGML du contenu. Cependant, il est très lent (il prend plus de 30 minutes pour récupérer les URLs seulement). Comment puis-je optimiser le code ? J'ai inséré wikipedia.org comme exemple d'URL de départ.

use warnings;

use LWP::Simple;
use LWP::UserAgent;
use HTTP::Request;
use HTTP::Response;
use HTML::LinkExtor;

my $starting_url = 'http://en.wikipedia.org/wiki/Main_Page';
my @urls = $starting_url;
my %alreadyvisited;
my $browser = LWP::UserAgent->new();
$browser->timeout(5);
my $url_count = 0;

while (@urls) 
{ 
     my $url = shift @urls;
     next if $alreadyvisited{$url}; ## check if already visited

     my $request = HTTP::Request->new(GET => $url);
     my $response = $browser->request($request);

     if ($response->is_error())
     {
         print $response->status_line, "\n"; ## check for bad URL
     }
     my $contents = $response->content(); ## get contents from URL
     push @c, $contents;
     my @text = &RemoveSGMLtags(\@c);
     #print "@text\n";

     $alreadyvisited{$url} = 1; ## store URL in hash for future reference
     $url_count++;
     print "$url\n";

     if ($url_count == 500) ## exit if number of crawled pages exceed limit
     {
         exit 0; 
     } 

     my ($page_parser) = HTML::LinkExtor->new(undef, $url); 
     $page_parser->parse($contents)->eof; ## parse page contents
     my @links = $page_parser->links; 

     foreach my $link (@links) 
     {
             $test = $$link[2];
             $test =~ s!^https?://(?:www\.)?!!i;
             $test =~ s!/.*!!;
             $test =~ s/[\?\#\:].*//;
             if ($test eq "en.wikipedia.org")  ## check if URL belongs to unt domain
             {
                 next if ($$link[2] =~ m/^mailto/); 
                 next if ($$link[2] =~ m/s?html?|xml|asp|pl|css|jpg|gif|pdf|png|jpeg/);
                 push @urls, $$link[2];
             }
     }
     sleep 1;
}

sub RemoveSGMLtags 
{
    my ($input) = @_;
    my @INPUTFILEcontent = @$input;
    my $j;my @raw_text;
    for ($j=0; $j<$#INPUTFILEcontent; $j++)
    {
        my $INPUTFILEvalue = $INPUTFILEcontent[$j];
        use HTML::Parse;
        use HTML::FormatText;
        my $plain_text = HTML::FormatText->new->format(parse_html($INPUTFILEvalue));
        push @raw_text, ($plain_text);
    }
    return @raw_text;
}

5voto

Borodin Points 52478
  • Toujours use strict

  • Jamais utiliser l'esperluette & sur les appels de sous-routines

  • Utilice URI pour manipuler les URLs

Vous avez un sleep 1 Je suppose que c'est pour éviter de trop solliciter le site, ce qui est une bonne chose. Mais le goulot d'étranglement de presque toutes les applications web est l'internet lui-même, et vous ne pourrez pas rendre votre programme plus rapide sans en demander plus au site. Cela signifie que vous devez supprimer votre sleep et peut-être faire des demandes parallèles au serveur en utilisant, par exemple, LWP::Parallel::RobotUA . Est-ce que c'est une voie que vous devriez suivre ?

3voto

Andy Lester Points 34051

Utilisez WWW::Mechanize qui se charge de l'analyse et de l'extraction des URL pour vous. C'est tellement plus simple que le parsing des liens que vous avez à faire. Il a été créé spécifiquement pour le genre de choses que vous faites, et c'est une sous-classe de LWP::UserAgent, donc vous devriez pouvoir changer tous vos LWP::UserAgent en WWW::Mechanize sans avoir à changer aucun code, sauf pour l'extraction des liens, donc vous pouvez le faire :

my $mech = WWW::Mechanize->new();
$mech->get( 'someurl.com' );
my @links = $mech->links;

et ensuite @links est un tableau d'objets WWW::Mechanize::Link.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X