我将不得不通过简单地在网址上发布并获取XML作为回报来下载大量数据集。我可以通过一次执行多个请求来加快速度,但这里有钩子:
它需要在Windows和Linux上运行,因此线程和分支都是。 (由于这纯粹是IO限制的,我认为它们也不需要。)
此外,我的同事并没有达到非常高的perl理解水平,但需要能够掌握如何使用它(不一定是正在发生的事情,使用情况很好)。因此,如果 API有点简单,我会很高兴。
现在我正在考虑IO::Lambda。
还有其他建议吗?
死后事件:根据draegtun的建议,我现在把它拼凑在一起,完美地完成了这项工作:https://gist.github.com/661386你很快就会在CPAN上看到它。
答案 0 :(得分:6)
看看AnyEvent::HTTP
。根据{{3}}它确实编译&在Windows上工作。
以下是异步POST(http_post
)的简单示例。
use 5.012;
use warnings;
use AnyEvent::HTTP;
my $cv = AnyEvent->condvar;
my @urls = (
[google => 'http://google.com', 'some body'],
[yahoo => 'http://yahoo.com' , 'any body' ],
);
for my $site (@urls) {
my ($name, $url, $body) = @$site;
$cv->begin;
http_post $url, $body => sub {
my $xml = shift;
do_something_with_this( $name, $xml );
$cv->end;
}
}
# wait till all finished
$cv->recv;
say "Finished";
sub do_something_with_this { say @_ }
NB。请记住,do_something_with_this
尝试避免任何阻止的任何内容。请参阅其他非阻止CPAN testers platform matrix
/ I3az /
答案 1 :(得分:5)
您可以尝试使用LWP::Parallel。
我只是尝试使用ActiveState的5.10.1在Windows XP上构建它并遇到一些测试失败,其中一些是由于TEST
脚本盲目地将..
添加到{{1}中的所有条目和其他人似乎是由于版本与@INC
类不匹配。
这是一个问题。我可以将Parallel::ForkManager与LWP一起使用。
LWP::Protocol::*
以下是配置文件示例:
url = http://one.example.com/search url = http://two.example.com/query url = http://three.example.com/question [http://one.example.com/search] keyword = Perl limit = 20 [http://two.example.com/query] type = Who is limit = 10 [http://three.example.com/question] use = Perl result = profit
如果您需要说服自己执行不是连续的,请尝试以下简短脚本:
#!/usr/bin/perl
use strict; use warnings;
use Config::Std { def_sep => '=' };
use File::Slurp;
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use Parallel::ForkManager;
die "No config file specified\n" unless @ARGV;
my ($ini) = @ARGV;
read_config $ini, my %config;
my $pm = Parallel::ForkManager->new(10);
my @urls = @{ $config{''}{url} };
for my $url ( @urls ) {
$pm->start and next;
my $param = [ %{ $config{$url} } ];
my $request = POST $url, $param;
my $ua = LWP::UserAgent->new;
my $fn = sprintf '%s-%s-%s.xml',
map $request->$_, qw( method uri content);
$fn =~ s/\W+/_/g;
my $response = $ua->request( $request );
if ( $response->code == 200 ) {
write_file $fn, \ $response->as_string;
}
else {
warn $response->message, "\n";
}
$pm->finish;
}
$pm->wait_all_children;
输出:
[1]: a [1]: b [2]: a [1]: c [1]: d [2]: b [3]: a [3]: b [3]: c [2]: c [3]: d [2]: d [4]: a [4]: b [4]: c [4]: d
关于你对“可靠性”的评论,我认为这是错误的。您正在做的是通过以下脚本模拟的:
#!/usr/bin/perl
use strict; use warnings;
use Parallel::ForkManager;
my $pm = Parallel::ForkManager->new(2);
for my $sub (1 .. 4) {
$pm->start and next;
for my $i ('a' .. 'd') {
sleep rand 3;
print "[$sub]: $i\n";
}
$pm->finish;
}
$pm->wait_all_children;
您从中获得的输出将是:
--- []
由您决定原因。这就是#!/usr/bin/perl
use strict; use warnings;
use Parallel::ForkManager;
use YAML;
my @responses = parallel_run();
print Dump \@responses;
sub parallel_run {
my $pm = Parallel::ForkManager->new(2);
my @responses;
for my $sub (1 .. 4) {
$pm->start and next;
for my $i ('a' .. 'd') {
sleep rand 3;
push @responses, "[$sub]: $i";
}
$pm->finish;
}
$pm->wait_all_children;
return @responses;
}
允许您注册回调的原因。就像您使用Parallel::ForkManager
时那样。
您使用的模块是您自己的业务。只是不要继续公然虚假陈述。
答案 2 :(得分:1)
Mojo::UserAgent也可以做async paralell http。对于非perl人来说,它的API可能比其他一些模块更容易理解。
不确定它是否符合“可靠”的要求..