1

我正在尝试抓取http://www.imdb.com/find?q=Yek+mard%2C+yek+khers&s=all的 HTML 。结果集在类中包含一个结果result_text。所以我输入链接,获取该链接中的文本,在这种情况下,如 Firebug 所示,是A Man, a Bear. 但奇怪的是,下面的代码打印出来了Yek mard, yek khers。谁能帮助我如何获取我在浏览器中看到的文本?

$name = "Yek mard, yek khers";
$uri = URI->new("http://www.imdb.com/find?q=".uri_escape($name)."&s=all");
my $response = $ua->get( $uri );

my $root = HTML::TreeBuilder->new_from_content($response->decoded_content);
@results = $root->find_by_attribute("class","result_text");
$link = $results[0]->find_by_tag_name("a");
say $link->as_HTML();
# This should print <a href="/title/tt0122857/?ref_=fn_al_tt_1">A Man, a Bear</a>
# but prints <a href="/title/tt0122857/?ref_=fn_al_tt_1">Yek mard, yek khers</a>
4

1 回答 1

4

更新

我很抱歉。进一步查看后,我发现 IMDb 使用Accept-LanguageHTTP 请求的标头来确定如何呈现页面。默认情况下,LWP 根本不发送此标头,但 Firefox 会发送,这就是我上面的解决方案正常工作的原因。

因此,仅使用的解决方案LWP是可能的。必须首先使用对象构建定制请求,然后使用该方法HTTP::Request将其传递给对象。LWP::UserAgentrequest

此代码演示。

use strict;
use warnings;

use feature 'say';

use LWP;
use HTML::TreeBuilder::XPath;

my $url = 'http://www.imdb.com/find?q=Yek+mard%2C+yek+khers&s=all';

my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => $url, ['Accept-Language' => 'en-gb,en']);
my $resp = $ua->request($req);

my $tree = HTML::TreeBuilder::XPath->new_from_content($resp->decoded_content);
my @results = $tree->findnodes_as_strings('//td[@class="result_text"]/a/text()');

say $results[0];

输出和以前一样。


原始答案

问题是您在浏览器中看到的内容是在页面加载后由 JavaScript 代码生成的。LWP和的简单组合HTML::TreeBuilder不能处理除站点返回的原始 HTML 之外的任何内容。

为此推荐的常用解决方案是使用该WWW::Mechanize::Firefox模块,该模块使用实时 Firefox 进程来获取 HTML 和 JavaScript 并呈现页面。请注意,它需要在您的计算机上安装 Firefox 浏览器,并且MozRepl必须安装并运行 Firefox 插件。

该程序显示返回您期望的结果的工作代码。请注意,我还使用HTML::TreeBuilder::XPath了而不是 bare HTML::TreeBuilder,它允许更简单地表达您感兴趣的 HTML 部分。

use strict;
use warnings;

use feature 'say';

use WWW::Mechanize::Firefox;
use HTML::TreeBuilder::XPath;

my $url = 'http://www.imdb.com/find?q=Yek+mard%2C+yek+khers&s=all';

my $mech = WWW::Mechanize::Firefox->new;
$mech->get($url);

my $tree = HTML::TreeBuilder::XPath->new_from_content($mech->response->content);
my @results = $tree->findnodes_as_strings('//td[@class="result_text"]/a/text()');

say $results[0];

输出

A Man, a Bear
于 2013-06-01T11:44:27.003 回答