使用WWW::Mechanize透明处理GZip编码内容

5

我正在使用WWW::Mechanize,并且目前在我的代码中处理带有'Content-Encoding: gzip'头的HTTP响应,首先检查响应头,然后使用IO::Uncompress::Gunzip获取未压缩的内容。

但是,我希望能够透明地做到这一点,使得像form()、links()等WWW::Mechanize方法可以处理和解析未压缩的内容。由于WWW::Mechanize是LWP::UserAgent的子类,因此我更愿意使用LWP::UA::handlers来完成此操作。

虽然我部分成功了(例如,我可以打印未压缩的内容),但我无法以透明的方式调用它。

$mech->forms();

总之:我如何“替换”$mech对象内部的内容,以便从那时起,所有WWW::Mechanize方法都像Content-Encoding从未发生过一样工作?
我会非常感谢您的关注和帮助。 谢谢。
3个回答

8

谢谢!不知道我怎么错过了它 - 我确实搜索了 CPAN :) - Gurunandan Bhat

3

根据我看到的,你可以使用 $res->content( $bytes ) 成员来替换它。

顺便说一下,我是通过查看 LWP::UserAgent 的源代码,然后是 HTTP::Response,最后是 HTTP::Message 找到这个东西的。


是的-它可以工作。谢谢。当我想做更多的事情而不仅仅是解压缩内容时,我会使用它。目前我只会使用Fayland建议的模块。 - Gurunandan Bhat
请注意,WWW::Mechanize::GZip看起来相当有缺陷(请参见http://stackoverflow.com/questions/6874076/perl-how-to-avoid-diagnostic-messages-from-not-directly-included-modules)。很抱歉我不完全理解您所说的替换方法:您能给出一些示例代码吗? - MarcoS
@jettero:你是不是指"$res->decoded_content()"?无论如何,我投了你的答案,因为我甚至没有想到要检查这个。所以当我在perldoc HTTP::Response中搜索“编码”时,我找到了它。谢谢! - Michael Krebs

0

它内置了UserAgent和Mechanize。为了节省您的时间,有一个重要的警告

-在调试时,请确保在调用decoded_content后检查错误$@

$html = $r->decoded_content;
die $@ if $@;

更好的方法是查看HTTP :: Message的源代码,并确保所有支持包都在那里。
在我的情况下,decoded_content返回undef,而content是原始二进制数据,我进行了一次疯狂的追逐。UserAgent会在解码失败时设置错误标志,但Mechanize会忽略它(它不检查或记录该事件作为自己的错误/警告)。
在我的情况下,$@说:“找不到IO / HTML.pm ..它被eval'ed”
在不得不深入源代码之后,我发现内置的解码过程很长、细致、艰苦,涵盖了几乎每种情况并进行了大量的猜测(感谢Gisle!)。
如果你很谨慎,可以在new()中显式设置要与每个请求一起使用的默认标头。
    $browser = new WWW::Mechanize('default_headers' => HTTP::Headers->new('Accept-Encoding' 
                            => scalar HTTP::Message::decodable()));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接