1

我正在使用 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 .= '

有什么办法可以提高速度吗?

4

2 回答 2

4

也许你可以看看HTML::TreeBuilder::LibXML。模块文档谈到HTML::TreeBuilder::XPath大型文档的速度很慢,那就是实现“足够的方法......所以像 Web::Scraper 这样的模块可以工作”。文档页面上的基准测试显示 libxml 变体比 pure-perl 变体快约 1600%。

于 2013-09-27T13:40:21.520 回答
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
于 2013-09-27T11:11:26.500 回答