【问题标题】:HTML::TreeBuilder extract title tag failing on some sitesHTML::TreeBuilder 提取标题标签在某些网站上失败
【发布时间】:2021-02-13 14:30:37
【问题描述】:

我正在尝试找出为什么此代码在某些极端情况下会失败:

use HTML::TreeBuilder;
use Data::Dumper;

my $page = `curl -H "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" -L -A "Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9; PageThing http://pagething.com) Gecko/2008052906 Firefox/3.0" --compressed --silent --max-time 10 --location --connect-timeout 10 'weboost.com'`;

my $root = HTML::TreeBuilder->new_from_content($page);
my $title = $root->look_down( '_tag', 'title' );

print Dumper($title); # comes back as undef
my $page_title =  $title->as_text;
print "BLA: $page_title\n";

我明白了:

Can't call method "as_text" on an undefined value at test.cgi line 28.

我已经确认<title> 存在:

<title>weBoost</title>

那为什么找不到呢?

【问题讨论】:

  • 选择有此类问题的小页面并转储解析树 - 它可能会给您一个提示。 $root-&gt;dump(); # prints dump to STDOUT
  • 面对这个问题,我首先会转储 curl 检索到的文本并手动查看它。如果你已经这样做了,我很抱歉!

标签: perl


【解决方案1】:

这个网站的 HTML 是错误的。它使用自关闭 iframe,根据 HTML 规范,这是无效的:

<iframe src="..." height="0" width="0" style="display:none;visibility:hidden" />
                                                                             ^^^^

由于无效,自动关闭将被忽略,即 iframe 标记之后的所有内容都将被视为 iframe 的一部分,直到找到明确的 &lt;/iframe&gt;。这在执行$root-&gt;dump 时也可以看到:

<html> @0
  ...
    <iframe height="0" src="https://www.googletagmanager.com/ns.html?id=GTM-TQ5LT9K" style="display:none;visibility:hidden" width="0"> @0.1.0
      "</noscript><meta name="description" content="weBoost cell phone s..."

有关更多信息,另请参阅Why is a self-closing iframe tag preventing further DOM elements to be displayed?

【讨论】:

  • 谢谢@Steffen。心想可能是这样的。那我就忽略一个。它发生在一些网站上,但看看人们在他们网站上的 HTML 质量 - 我很惊讶它不会发生更多!
【解决方案2】:

Mojo::DOM 没有这种效果,因为它不太关心“正确”(或者,正如它所说,它是一个“宽松”的解析器)。不仅如此,您还可以轻松地在 Perl 中完成所有操作:

use v5.10;
use Mojo::UserAgent;

my $ua = Mojo::UserAgent->new->max_redirects(3);
$ua->transactor->name( "Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9; PageThing http://pagething.com) Gecko/2008052906 Firefox/3.0" );

my $url = 'weboost.com';
my $tx = $ua->get(
    $url =>
    { 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7' }
    );

say $tx->result->dom->at( 'title' )->text;

这会输出title中的文本:

weBoost

Mojo Web Clients 中有更多 Mojo Web 客户端技巧的示例。您可以在 curl 中执行的许多操作都可以在 Mojo 中轻松输入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 2022-10-25
    • 2010-10-17
    • 2013-05-17
    相关资源
    最近更新 更多