我正在尝试从HTML文档中提取所有图像(从网上下载并转换为字符串(标量)),我正在使用HTML :: LinkExtractor cpan lib。
我传递了相同的HTML,但提取了不同的链接。
问题:为什么会这样,我该如何解决?
代码:
my $LX = new HTML::LinkExtractor();
# print($_[0] . "\n\n"); <--- Prints the same HTML document every time
$LX->parse(\$_[0]);
for my $p ( @{$LX->links()} ){
# Need to iterate though all the
# values, since images can be hidden
# in _TEXT w/o any img tag, etc.
foreach (my( $key, $val ) = each $p) {
print($key . "--->" . $val . "\n"); <--- Prints different values
首先输出:
$ ./HTMLPictureScraper.pl http://dustyfeet.com/
/--->/
/--->/
href--->http://dustyfeetonline.com
href--->http://dustyfeetonline.com
target--->_top
target--->_top
href--->http://www.nytimes.com/2006/08/28/technology/28link.html?scp=6&sq=%22stuart%20frankel%22&st=cse
href--->http://www.nytimes.com/2006/08/28/technology/28link.html?scp=6&sq=%22stuart%20frankel%22&st=cse
target--->_top
target--->_top
tag--->a
tag--->a
href--->./evil/evil.html
href--->./evil/evil.html
_TEXT---><a
href="./pangan/index.html">Warung Seniman</a>
_TEXT---><a
href="./pangan/index.html">Warung Seniman</a>
href--->./santanyi_registration.html
href--->./santanyi_registration.html
href--->mailto:gecko@dustyfeet.com
href--->mailto:gecko@dustyfeet.com
第二次输出:
$ ./HTMLPictureScraper.pl http://dustyfeet.com/
content--->1vLCRPR1SHmiCICnhWfD7jtpOOSHe79iILqzDkGBUg0=
content--->1vLCRPR1SHmiCICnhWfD7jtpOOSHe79iILqzDkGBUg0=
tag--->a
tag--->a
href--->notuncnj.html
href--->notuncnj.html
tag--->a
tag--->a
tag--->a
tag--->a
tag--->a
tag--->a
tag--->a
tag--->a
tag--->a
tag--->a
tag--->a
tag--->a
href--->mailto:gecko@dustyfeet.com
href--->mailto:gecko@dustyfeet.com
答案 0 :(得分:3)
在这一行中,您试图将each
- 迭代器与for-each循环组合在一起。尽管它们的名字相似,但它们是不相容的:
foreach (my( $key, $val ) = each $p) {
print($key . "--->" . $val . "\n");
}
这将从%$p
的迭代器中获取下一个键值项,并指定两项列表($key, $val)
。然后,foreach
遍历这两个项目。这就是为什么你总是两次看到相同的两个值的原因。由于each
的迭代顺序未定义,因此您只能看到%$p
哈希中的随机条目。
解决此问题:
要么使用while循环来使用each
- 迭代器:
while (my ($key, $val) = each %$p) {
print "$key--->$val\n";
}
或者,在键上使用foreach循环:
for my $key (keys %$p) {
my $val = $p->{$key};
print "$key--->$val\n";
}
我更喜欢for / foreach循环,因为这允许我们以稳定的顺序对键进行排序,而不是依赖于散列的未定义的迭代顺序:
for my $key (sort keys %$p) {
my $val = $p->{$key};
print "$key--->$val\n";
}
然后,应该始终为相同的输入文档生成相同的输出。
正如zdim在回答中指出的那样,您不应将$p
之类的标量传递给keys
或each
之类的运算符,而应将其取消引用为each %$p
之类的哈希值。否则,您的代码将无法在最新版本的Perl上运行。