我正在建立一个使用矢量空间模型的基本搜索引擎,这是返回500个URL的爬虫,并从内容中删除SGML标签。然而,它非常慢(仅检索URL就需要30分钟以上)。如何优化代码?我已经插入了wikipedia.org作为开始网址的示例。
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;
}
发布于 2013-04-08 00:37:56
Always use strict
&
on子例程调用时始终使用与号URI
to URL
你有一个sleep 1
在里面,我认为这是为了避免对网站进行太多的攻击,这是很好的。但是,几乎所有基于web的应用程序的瓶颈都是互联网本身,如果不从站点请求更多内容,您将无法让程序运行得更快。这意味着删除您的sleep
,并可能使用例如LWP::Parallel::RobotUA
向服务器发出并行请求。这是你应该走的路吗?
发布于 2013-04-08 00:54:51
使用WWW::Mechanize,它为您处理所有的URL解析和提取。比你正在处理的所有链接解析要容易得多。它是专门为您正在做的事情创建的,它是LWP::UserAgent的子类,因此您应该能够将所有的LWP::UserAgent更改为WWW::Mechanize,而不必更改任何代码,除了所有的链接提取,因此您可以这样做:
my $mech = WWW::Mechanize->new();
$mech->get( 'someurl.com' );
my @links = $mech->links;
然后@links
是WWW::Mechanize::Link对象的数组。
https://stackoverflow.com/questions/15864277
复制相似问题