如何使用Perl访问JavaScript驱动的网页内容

How can I access the contents of a JavaScript driven web page with Perl?

本文关键字:网页内容 JavaScript 何使用 Perl 访问      更新时间:2023-09-26

我试图用Perl制作一个小应用程序,从LolKing那里获取英雄联盟的召唤师名称。

HTML代码有类似的行

<tr data-summonername="MatLife TriHard" class="lb_row_rank_4">

所以我只是用之类的东西

use strict;
use warnings;
use LWP::Simple;
use HTML::Parser;
my $find_links = HTML::Parser->new(
  start_h => [
    sub {
      my ($tag, $attr) = @_;
      if ($tag eq 'tr' and exists $attr->{'data-summonername'}) {
        print "$attr->{'data-summonername'}'n";
      }
    },
    "tag, attr"
  ]
);
my $html = get('http://www.lolking.net/leaderboards/#/na/1') or die 'nope';
$find_links->parse($html);

但这并没有给我什么。即使有attr=class,它也不会给我任何东西。由于某种原因,我无法获取tr元素的类。

使用不带单引号的$attr->{data-summonername}会给我带来一些错误,我想这是因为使用了连字符。如果我获取$attr->{href},它就可以正常工作。

有人能帮我吗?

问题是,该页面的HTML大多是在下载页面后由浏览器使用JavaScript构建的。使用LWP::Simple::get将只检索骨架HTML和JavaScript代码。你可以看到,如果你print $html而不是解析它

通常的解决方案是使用WWW::Mechanize::Firefox,它可以让安装的Firefox下载并构建页面,然后您可以查询该页面。不过,它比简单的get要复杂得多,因为如果你还没有Firefox,你必须安装它,以及支持远程控制的Mozilla MozRepl插件。即便如此,在浏览器完成构建之前,你仍然可能在访问页面内容时遇到问题,所以这不适合胆小的人。


更新

为了您的兴趣,这里有一个使用WWW::Mechanize::Firefox的解决方案。

use strict;
use warnings;
use WWW::Mechanize::Firefox;
use HTML::TreeBuilder::XPath;
my $url = 'http://www.lolking.net/leaderboards/#/na/1';
my $mech = WWW::Mechanize::Firefox->new;
my $resp = $mech->get($url);
die $resp->status_line unless $resp->is_success;
my $tree = HTML::TreeBuilder::XPath->new_from_content($resp->content);
for my $node ( $tree->findnodes('//tr[starts-with(@class, "lb_row_rank")]') ) {
  printf "Rank %2d: %s'n",
      $node->attr('class') =~ /('d+)/,
      $node->attr('data-summonername');
}

输出

Rank  1: Doublelift
Rank  2: F5 Veritas
Rank  3: Life Love Live 
Rank  4: MatLife TriHard
Rank  5: TDK Kyle
Rank  6: Liquid FeniX
Rank  7: Liquid Inori TV
Rank  8: dawoofsclaw
Rank  9: who is he
Rank 10: Ohhhq