3

问题:我有一个包含 2500 个网站的列表,需要获取它们的缩略图。我怎么做?我可以尝试使用 Perl 解析网站。- 机械化将是一件好事。注意:我只需要长尺寸最大为 240 像素的缩略图的结果。目前我有一个缓慢且不返回缩略图的解决方案:如何以更少的开销使脚本运行得更快 - 吐出缩略图

先决条件: addon/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 默认为当前选项卡。如果给定坐标,则该矩形将被切掉。坐标应该是包含四个常用条目的散列,left,top,width,height。这是特定于 WWW::Mechanize::Firefox 的。

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

mecha-module 不关心调整图像大小。这里我们有 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 # 

这是我的来源...查看我在 url 列表中拥有的网站的片段 [示例]。

urls.txt [来源列表]

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

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

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

期待您的来信!问候零

更新:除了非常有趣的 Schwerms 想法之外,我还发现了一个有趣的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);

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

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

顺便说一句:就像 Øyvind Skaar 提到的那样:有了这么多的 url,我们不得不期望有些会失败并处理它。例如,我们将失败的那些放在一个数组或哈希中,然后重试 X 次。

4

1 回答 1

5

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

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

于 2012-02-20T02:29:37.383 回答