Perl Mechanize - 如何以更少的开销使脚本运行得更快

时间:2012-02-19 23:35:19

标签: perl parsing timeout image-resizing www-mechanize

问题:我有2500个网站的列表,需要获取它们的缩略图截图。我怎么做? 我可以尝试使用Perl解析网站.- Mechanize将是一件好事。 注意:我只需要将结果作为缩略图,在长维中最多240像素。目前我的解决方案速度很慢,并且没有回放缩略图:如何使脚本以更少的开销更快地运行 - 吐出缩略图

先决条件: 插件/ mozrepl / 模块WWW :: Mechanize :: Firefox; 模块成像器

第一种方法:这是第一个Perl解决方案:

 use WWW::Mechanize::Firefox;
 my $mech = WWW::Mechanize::Firefox->new();
 $mech->get('http://google.com');
 my $png = $mech->content_as_png();

大纲:这会返回给定标签或呈现为PNG图像的当前页面。 所有参数都是可选的。 $ tab默认为当前选项卡。如果给出坐标,则将剪切该矩形。坐标应该是一个带有四个常用条目的哈希值,左边,顶部,宽度,高度。这特定于WWW :: Mechanize :: Firefox。

正如我从perldoc中了解到该坐标的选项,它不是整个页面的大小调整它只是一个矩形切出它....好吧WWW :: Mechanize :: Firefox照顾如何保存截图。好吧,我忘了提到我只需要将图像作为小缩略图 - 所以我们不必拥有非常大的文件......我只需要抓取它们的缩略图截图。我已经在cpan上查找了一些缩小$ png的模块,我找到了Imager

机械模块不关心调整图像大小。在这里,我们在CPAN上有各种图像模块,比如Imager。 Imager - 用于生成24位图像的Perl扩展:Imager是用于创建和更改图像的模块。它可以读写各种图像格式,绘制线条和多边形等原始形状,以各种方式将多个图像混合在一起,缩放, 裁剪,渲染文本等。我安装了模块 - 但我没有扩展我的基本方法

我已经尝试过的东西;这是:

#!/usr/bin/perl

use strict;
use warnings;
use WWW::Mechanize::Firefox;

my $mech = new WWW::Mechanize::Firefox();

open(INPUT, "<urls.txt") or die $!;

while (<INPUT>) {
        chomp;
        print "$_\n";
        $mech->get($_);
        my $png = $mech->content_as_png();
        my $name = "$_";
        $name =~s/^www\.//;
        $name .= ".png";
        open(OUTPUT, ">$name");
        print OUTPUT $png;
        sleep (5);
}

这不关心大小:

请参阅输出命令行:

linux-vi17:/home/martin/perl # perl mecha_test_1.pl
   www.google.com
    www.cnn.com
    www.msnbc.com
command timed-out at /usr/lib/perl5/site_perl/5.12.3/MozRepl/Client.pm line 186
linux-vi17:/home/martin/perl # 

这是我的来源...查看我在网址列表中的网站的摘要[示例]。

urls.txt [来源清单]

www.google.com
www.cnn.com
www.msnbc.com
news.bbc.co.uk
www.bing.com
www.yahoo.com

问题:如何扩展解决方案以确保它不会在超时中停止。 - 它只存储小缩略图 注意:再次:我只需要将结果作为缩略图,在长维中最多240像素。作为先决条件,我已经安装了模块成像器

如何让脚本以更少的开销更快地运行 - 吐出缩略图

很高兴收到你的来信!问候 零

更新:除了Schwerms的想法非常非常有趣之外,我发现intersting Monkthread 会谈到相同的超时:

有没有办法用WWW :: Mechanize :: Firefox指定Net :: Telnet超时?目前我的互联网连接速度非常慢,有时我会收到错误

 $mech->get(): command timed-out at /usr/local/share/perl/5.10.1/MozRepl/Client.pm line 186

也许我必须在mozrepl-Timeout-configuration之后玩笑!?但毕竟:这很奇怪,我不知道超时的来源。也许它真的是Firefox超时,因为它正在忙着同步获取一些结果。正如您在跟踪中看到的那样,WWW :: Mechanize :: Firefox会每秒(或左右)轮询以查看Firefox是否已获取页面。

如果它真的是Net :: Telnet,那么你将不得不潜水:

$mech->repl->repl->client->{telnet}->timeout($new_timeout);

**更新** 所以问题:我使用** Net :: Telnet:**在Perl-Core中

@ Alexandr Ciornii:请注意提示!随后我会这样做  使用:Net :: Telnet; ,但如果它不在核心,那我就不能这样了。 @Daxim:$ corelist Net ::Telnet␤␤Net:: Telnet不在CORE中 - 这意味着我不能像上面那样

顺便说一下:就像ØyvindSkaar所说的那样:有了这么多网址,我们不得不期待有些人会失败并处理这个问题。例如,我们将失败的数据放入数组或散列中并重试X次。

1 个答案:

答案 0 :(得分:5)

查看Parallel::ForkManager这是在Perl中进行并行处理的更简单,更可靠的方法之一。你的大部分工作都是网络和I / O绑定,你的CPU将等待远程Web服务器返回,你可能会获得一些大的胜利。

至于超时,这是在MozRepl内的某个地方,默认为10秒。您要么必须创建一个具有不同超时的MozRepl :: Client对象,并以某种方式让WWW :: Mechanize :: Firefox使用它,或者您可以做一些未记录的事情。 This perlmonks thread显示了如何更改超时。还可以设置一个未记录的MOZREPL_TIMEOUT环境变量。