【问题标题】:Why can't LWP::UserAgent get this site entirely?为什么 LWP::UserAgent 不能完全获取这个站点?
【发布时间】:2013-02-06 22:47:32
【问题描述】:

它只从开头输出几行。

#!/usr/bin/perl

use strict;
use warnings;
use LWP::UserAgent;

my $ua = LWP::UserAgent->new;
my $response = $ua->get('http://www.eurogamer.net/articles/df-hardware-wii-u-graphics-power-finally-revealed');
print $response->decoded_content;

【问题讨论】:

  • 我得到了完整的 html 页面,完全按照您在上面键入的内容运行。你的输出是什么?它是否包含任何类型的错误消息?
  • 这是我得到的输出:pastebin.com/wVcNBJeg

标签: perl lwp lwp-useragent


【解决方案1】:

我运行了以下修改:

my $response = $ua->get( 'http://www.eurogamer.net/articles/df-hardware-wii-u-graphics-power-finally-revealed' );
say $response->headers->as_string;

看到了这个:

Cache-Control: max-age=60s
Connection: close
Date: Wed, 06 Feb 2013 23:51:15 GMT
Via: 1.1 varnish
Age: 0
Server: Apache
Vary: Accept-Encoding
Content-Length: 50519
Content-Type: text/html; charset=ISO-8859-1
Client-Aborted: die
Client-Date: Wed, 06 Feb 2013 23:50:50 GMT
Client-Peer: 94.198.83.18:80
Client-Response-Num: 1
X-Died: Illegal field name 'X-Meta-Twitter:card' at .../HTML/HeadParser.pm line 207.
X-Varnish: 630361704

它似乎不喜欢第 27 行的<meta name="twitter:card" content="summary" /> 标签。它说它死了。

它似乎将任何带有name 属性的meta 标记转换为"X-Meta-\u$attr->{name}"“标题”。然后它会尝试将content 属性的值存储为X-meta“标头”值。像这样(从第 194 行开始):

if ($tag eq 'meta') {
    my $key = $attr->{'http-equiv'};
    if (!defined($key) || !length($key)) {
        if ($attr->{name}) {
            $key = "X-Meta-\u$attr->{name}"; # <-- Here's the little trick
        } elsif ($attr->{charset}) { # HTML 5 <meta charset="...">
            $key = "X-Meta-Charset";
            $self->{header}->push_header($key => $attr->{charset});
            return;
        } else {
            return;
        }
    }
    $self->{'header'}->push_header($key => $attr->{content});
}

我将此模块的修改副本推送到 PERL5LIB 目录中。我将push_header 步骤包装在eval 块中并完全下载了该页面。

【讨论】:

  • 升级 HTML::Parser 可能会有所帮助,请参阅:rt.cpan.org/Ticket/Display.html?id=85119
  • @Borodin,你删除的不是“部落主义”,而是一个简单的确认,即当 Perl 程序满足它们无法处理的条件时 @987654332 @——这就是他们所做的。 “死”这个词适用于 Perl 程序。如果它在 eval 块中被捕获,那么识别它的 Perlish 方法可能X-Died 标头。
  • @SlavenRezic,确实,他们确实处理了它。我的破解只是为了证明主要是无法处理回答的 http-equiv 标签:“为什么LWP::UserAgent 不能完全获取这个站点?”如果它仍然无法获得该站点,我的更改将毫无意义。
  • @Axeman:其他语言在遇到未处理的异常时会怎么做?
  • @Borodin,他们“死”了。但是,您不会从未处理的异常中获得 X- header。此外,“未处理的异常”和“条件 [程序] 无法处理”可以是两个不同的东西。可以在程序员意识到他无法从这里做任何事情并专门调用die "Error from subsystem: $@";的地方
【解决方案2】:

我也遇到了同样的问题……

我修复了它禁用启用 HTML::HeadParser 的选项“parse_head”。

    $self->{ua}->parse_head(0);

我知道禁用此功能不是一个好主意,但我更喜欢可用性而不是正确解码的文档。

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 2019-01-20
    • 2010-12-20
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    相关资源
    最近更新 更多