我正在整理一个程序,可以将数据5或6个网页存储到一个数组中,然后从每个页面中提取“标题”。到目前为止,它检索页面内容,除非我尝试打印提取的“标题”。我只能打印到一个输出文件。
当我用Google搜索解决方案时,除了我的问题之外,我把它带到了每条路上。有人可以建议一些方法我可以打印每个页面的“标题”来分隔输出文件吗?
这是我的代码:
#!/usr/bin/perl -w
use warnings;
use threads;
use LWP::UserAgent qw();
use WWW::Mechanize;
my @threads = ();
my @urls = qw(http://site1.com http://site2.com);
foreach my $url ( @urls ) {
push @threads, async {
my $mech = WWW::Mechanize->new();
printf( "Loaded: %s \n", $url );
my $res = $mech->get( $url );
my $ducktales = $mech->title;
$_->join for @threads;
open( DATA, ">C:/Users/User/Desktop/11.txt" ) or die "cant";
print DATA $ducktales;
};
}
答案 0 :(得分:2)
首先,让我们看一下你的open:
open(DATA,">C:/Users/User/Desktop/11.txt")
您正在使用一个匿名句柄DATA
。这样的句柄是全局包的意思,如果你在代码中的不同点打开了不同的文件,每个新的open
都会导致先前打开的文件被关闭。
最重要的是,DATA
文件句柄很特殊,你可能不应该践踏它。
首先,使用词法文件句柄:
open my $data, ...
接下来,如果发生错误,您不会显示可通过$!
访问的文件名或错误消息。这意味着您只考虑单个全局文件句柄。
open my $data, '>', $data_file
or die "Cannot open '$data_file' for writing: $!";
现在,$data_file
来自哪里?如果我理解正确,您需要每个URL一个数据文件。因此,根据URL命名数据文件是有意义的,将名称限制为由一些安全的字符子集组成。
现在,忘记线程,编写将获取URL的子例程,获取它,提取标题,并根据URL将其写入文件:
sub extract_and_write_title {
my $url = shift;
# fetch document
# extract title
# if success, open file named based on URL
# write title, close file
return;
}
现在,在主循环中,您可以基于此例程创建线程:
push @threads, threads->create(
\&extract_and_write_title,
$url,
);
你可以填空。作为一项规则,我不会给intarwebs中的随机人员提供完整的刮擦解决方案。