WebSite Scraper:如何使我的Parallel Thread打印到单独的输出位置

时间:2015-03-06 06:47:25

标签: multithreading perl file-io

我正在整理一个程序,可以将数据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;
  };
}

1 个答案:

答案 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中的随机人员提供完整的刮擦解决方案。