perl - HTML::TreeBuilder 提取标题标签在某些网站上失败
问题描述
我试图弄清楚为什么这段代码在某些极端情况下会失败:
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>
那为什么找不到呢?
解决方案
这个网站的 HTML 是错误的。它使用自关闭 iframe,根据 HTML 规范,这是无效的:
<iframe src="..." height="0" width="0" style="display:none;visibility:hidden" />
^^^^
由于它是无效的,自动关闭将被忽略,即 iframe 标记之后的所有内容都将被视为 iframe 的一部分,直到</iframe>
找到显式。这也可以在执行以下操作时看到$root->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..."
有关更多信息,另请参阅为什么自关闭 iframe 标记会阻止显示更多 DOM 元素?.
推荐阅读
- c# - 发布多个 Azure 函数而不覆盖彼此的 dll
- python - 在 Python 中有效地将数据过滤到多个变量中
- c# - 第二次运行迁移时出错。看来需要处理通用回购,我不知道如何
- python - 每次外部 for 循环迭代时,如何让我的内部 for 循环进行迭代?
- keycloak - 如何在idea中运行keycloak?
- python-3.x - macOS Catalina 更新后 Python 模块无法正常工作
- if-statement - 基于其他变量创建新变量
- jenkins - 使用 perforce 时如何更改 jenkins 工作区路径?
- node.js - 如何从 cwp 服务器运行 node.js?
- javascript - 如何从另一个数组返回数组数据?