到目前为止,我使用 perl 从使用 HTML::TreeBuilder
的网页获取数据。当数据包含在 meta
或 div
标签中时,这是可以的;但现在我偶然发现了一个我不知道如何爬行的新结构,尽管它看起来很微不足道。
<html lang="en">
<body>
<script type="text/javascript">
panel.web.bootstrapData = {
"data": {
"units": "kW",
"horsePower": 100.00
}
};
</script>
</body>
</html>
该示例显示了我从网络上获取的内容的相关部分。我想获取 units
和 horsePower
的值。
到目前为止我使用的代码片段:
use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
use HTML::TreeBuilder;
[...]
$reply = $ua->get($url, @ns_headers);
# printing the reply would get us the first code snippet.
print $reply->content;
unless ($reply->is_success) {
[...]
}
my $tree = HTML::TreeBuilder->new_from_content($reply->content);
my @unit_array = $tree -> look_down(_tag=>'meta','itemprop'=>'unit');
my $unit = $unit_array[0]->attr('content');
[...]
有谁知道如何获取相关数据以及我是否应该为此使用 HTML::TreeBuilder
以外的东西?我通过stackoverflow和网络搜索都没有发现任何类似的案例。
最佳答案
你基本上是在正确的道路上。但是HTML::TreeBuilder对 JavaScript 一无所知。
方法:
- 找到
<script>
节点 - 从这些节点中提取 JSON 内容
- 注意:这对于给定的示例来说很容易,但对于更复杂的
<script>
则需要更多的技巧。内容 - 越狱
\;
在正则表达式中并不是真正需要的,但是没有它 SO 语法高亮器会变得困惑
- 注意:这对于给定的示例来说很容易,但对于更复杂的
- 使用JSON将字符串解码为 Perl 数据结构
- 在脚本中访问这些数据结构
第一个没有错误检查的粗略解决方案。我在代码中留下了一些调试行,注释掉了,以便您可以跟踪每个步骤在做什么:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use HTML::TreeBuilder;
use JSON;
my $decoder = new JSON;
my $tree = HTML::TreeBuilder->new_from_file(\*DATA);
#$tree->dump;
my @scripts = $tree->look_down(_tag => 'script');
#$scripts[0]->dump;
# NOTE 1: ->as_text() *DOES NOT* return <script> content!
# NOTE 2: ->as_HTML() probably doesn't work for all cases, i.e. escaping
my $javascript = ($scripts[0]->content_list())[0];
#print "${javascript}\n";
my($json) = $javascript =~ /(\{.+\})\;/s;
#print "${json}\n";
my $object = $decoder->decode($json);
print Dumper($object);
print "FOUND: units: ", $object->{data}->{units},
" horsepower: ", $object->{data}->{horsePower}, "\n";
# IMPORTANT: $tree needs to be destroyed by hand when you're done with it!
$tree->delete;
exit 0;
__DATA__
<html lang="en">
<body>
<script type="text/javascript">
panel.web.bootstrapData = {
"data": {
"units": "kW",
"horsePower": 100.00
}
};
</script>
</body>
</html>
测试运行:
$ perl dummy.pl
$VAR1 = {
'data' => {
'horsePower' => '100',
'units' => 'kW'
}
};
FOUND: units: kW horsepower: 100
关于html - Perl 网络抓取工具,从脚本标签内的文本中检索数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54840931/