Multithreading 网站刮刀:如何使我的平行线打印到不同的输出位置

Multithreading 网站刮刀:如何使我的平行线打印到不同的输出位置,multithreading,perl,file-io,Multithreading,Perl,File Io,我正在编写一个程序,可以将5或6个网页的数据存储到一个数组中,然后从每个网页中提取“标题”。到目前为止,它检索页面内容,但我尝试打印提取的“标题”时除外。我只能打印到一个输出文件 当我在谷歌上搜索一个解决方案时,它把我带到了每一条路上,除了我的问题。有人能建议一些方法,我可以打印每一页的“标题”以分离输出文件吗 这是我的代码: #!/usr/bin/perl -w use warnings; use threads; use LWP::UserAgent qw(); use WWW::Mech

我正在编写一个程序,可以将5或6个网页的数据存储到一个数组中,然后从每个网页中提取“标题”。到目前为止,它检索页面内容,但我尝试打印提取的“标题”时除外。我只能打印到一个输出文件

当我在谷歌上搜索一个解决方案时,它把我带到了每一条路上,除了我的问题。有人能建议一些方法,我可以打印每一页的“标题”以分离输出文件吗

这是我的代码:

#!/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;
  };
}
首先,让我们看看您的:

您正在使用裸字句柄,
数据
。这样的句柄是包全局的,这意味着如果您在代码中的不同点打开了不同的文件,则每个新的
open
都会导致以前打开的文件被关闭

最重要的是,
数据
文件句柄是特殊的,您可能不应该践踏它

因此,首先,使用词法文件句柄:

open my $data, ...
接下来,如果发生错误,则不显示文件名或错误消息,可通过
$访问。这意味着您只考虑单个全局文件句柄

open my $data, '>', $data_file
   or die "Cannot open '$data_file' for writing: $!";
现在,
$data\u文件
来自哪里?如果我理解正确,您希望每个URL有一个数据文件。因此,根据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中的随机人员提供完整的刮擦解决方案。

您不应该使用警告以及shebang行
-w
开关。您应该选择一个或另一个,您的选择应该是
使用警告
。此外,您必须始终在编写的每个Perl程序的顶部使用严格的
。上面说“官方不鼓励在Perl中使用基于解释器的线程。”您应该改为使用。“我不会给intarwebs中的随机人员提供完整的刮片解决方案”好极了!
 push @threads, threads->create(
      \&extract_and_write_title,
      $url,
 );