Perl HTML::LinkExtractor returns 不同调用的不同链接
Perl HTML::LinkExtractor returns different links on different calls
我正在尝试从 HTML 文档中提取所有图像(从网上下载并转换为字符串(标量)),并且我正在使用 HTML::LinkExtractor cpan 库。
我传递相同的 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
在这一行中,您尝试将 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
之类的运算符,而应该将其取消引用到 [=24= 这样的哈希].否则,您的代码将无法在最新版本的 Perl 上运行。
我正在尝试从 HTML 文档中提取所有图像(从网上下载并转换为字符串(标量)),并且我正在使用 HTML::LinkExtractor cpan 库。
我传递相同的 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
在这一行中,您尝试将 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
之类的运算符,而应该将其取消引用到 [=24= 这样的哈希].否则,您的代码将无法在最新版本的 Perl 上运行。