为什么Web :: Scraper这么慢?

时间:2013-09-27 04:03:35

标签: perl

我正在使用Web :: Scraper从一个非常简单的表中抽取一些数据并将其转换为我的需求。我也在使用WWW :: Mechanize来进行表单提交,这根本不是很慢。

一旦我开始使用Web :: Scraper,我注意到需要很长时间才能从页面返回数据。分析显示以下内容:

6299228 13.7s   line    XML/XPathEngine/Step.pm
7335    10.9s   line    Net/HTTP/Methods.pm
3990690 10.4s   line    XML/XPathEngine/NodeSet.pm
2690467 7.72s   line    HTML/TreeBuilder/XPath.pm
2047085 5.70s   line    XML/XPathEngine/Function.pm
978212  3.37s   line    XML/XPathEngine/Literal.pm
1791592 3.29s   line    HTML/Element.pm
661985  3.15s   line    XML/XPathEngine.pm
1997421 2.52s   line    XML/XPathEngine/Expr.pm

在控制台上运行它会产生以下结果:

real    0m28.042s
user    0m11.312s
sys     0m0.121s

使用Web浏览器表单构造(调试)我只看到自定义查询3.5秒,所以我把它缩小到Web :: Scraper花费时间。

这是一些网络刮刀代码,即:

$offers = scraper {
        process 'table> tr' => 'td[]' => scraper {
        process 'td.tdCallNumber > strong ' => 'tdCallNumber' => 'TEXT';
        process 'td.tdDateReceived >strong ' => 'tdDateReceived' => 'TEXT';
        process 'td.tdTimeReceived >strong' => 'tdTimeReceived' => 'TEXT';
        process 'td.tdLocation>strong'      => 'tdLocation'     => 'TEXT';
        process 'td.tdDesc>strong'          => 'tdDesc'         => 'TEXT';
        process 'td > table '               => 'table'          => 'TEXT';
        process 'td>table>tr' => 'data[]' => scraper {
            process 'td.tdUnit'    => 'tdUnit' => 'TEXT',
                process 'td.tdDIS' => 'tdDIS'  => 'TEXT',
                process 'td.tdENR' => 'tdENR'  => 'TEXT',
                process 'td.tdONS' => 'tdONS'  => 'TEXT',
                process 'td.tdLEF' => 'tdLEF'  => 'TEXT',
                process 'td.tdARR' => 'tdARR'  => 'TEXT',
                process 'td.tdBUS' => 'tdBUS'  => 'TEXT',
                process 'td.tdREM' => 'tdREM'  => 'TEXT',
                process 'td.tdCOM' => 'tdCOM'  => 'TEXT',
                ;
        };

    }
};
my $D;
my $print_header = 1;

$D = $offers->scrape($text);

...

其中一些将它转换为基于html的输出(几乎相同的表格形式)。

my $r;
for $r ( @{ $D->{td} || [] } ) {
    if ( $r->{tdCallNumber} ) {
        if ($print_header) {
            $npage .= "

$r->{tdCallNumber}, $r->{tdDateReceived}, $r->{tdTimeReceived},
            $r->{tdLocation}, $r->{tdDesc};
    }
    if ( $r->{data} ) {
        $npage .= '

我能做些什么来提高速度吗?

2 个答案:

答案 0 :(得分:4)

也许你可以看看HTML::TreeBuilder::LibXML。模块文档讨论了HTML::TreeBuilder::XPath对于大型文档来说速度慢的问题,并且实现了“足够的方法......所以像Web :: Scraper这样的模块工作”。文档页面上的基准测试显示libxml变体比pure-perl变体快约1600%。

答案 1 :(得分:1)

您可以使用NYTProf来查找程序或库中确切的缓慢位置。一旦你看到什么是缓慢的,你就可以改进它。

http://www.slideshare.net/Tim.Bunce/develnytprof-200907

# profile code and write database to ./nytprof.out
perl -d:NYTProf some_perl.pl

# convert database into a set of html files, e.g., ./nytprof/index.html
# and open a web browser on the nytprof/index.html file
nytprofhtml --open