感谢所有帮助我实现这一目标的人.
现在我的新问题.我正在使用2003年编写的一本书,该教程试图抓住一个已经改变的页面.
原始地址是:" http://www.oreilly.com/catalog/prdindex.html "此页面不再存在,但会重定向到新页面:" http://oreilly.com/store/complete.html "
问题"我认为"是html代码在7年内发生了变化.代码曾经是这样的:
<tr bgcolor="#ffffff">
<td valign="top">
<a href="http://oreilly.com/catalog/googlehks">Google Hacks</a><br />
</td>
<td valign="top" nowrap="nowrap">0-596-00447-8</td>
<td valign="top" align="right">$24.95</td>
<td valign="top" nowrap="nowrap" align="center">
<a href="http://safari.oreilly.com/0596004478">Read it on Safari</a>
</td>
<td valign="top" nowrap="nowrap">
<a href="http://examples.oreilly.com/googlehks">Get examples</a>
</td>
</tr>
Run Code Online (Sandbox Code Playgroud)
所以无论如何html已经改变了.您可以通过查看浏览器上的源代码来查看它.
当我运行脚本时,我收到此错误:
在/usr/lib/perl5/site_perl/5.8.8/HTML/TreeBuilder.pm第93行的子例程条目中使用未初始化的值.无法在./SpiderTutorial_19_09.pl第67行的未定义值上调用方法"as_HTML".有0本Perl书籍和0本Java书籍.Java比Perl多0个.
这是我正在尝试运行的代码.
#!/usr/bin/perl -w
use strict;
use LWP::Simple;
use HTML::TreeBuilder;
my $url = 'http://oreilly.com/store/complete.html';
my $page = get( $url ) or die $!;
my $p = HTML::TreeBuilder->new_from_content( $page );
my($book);
my($edition);
my @links = $p->look_down(
_tag => 'a',
href => qr{^ \Qhttp://oreilly.com/complete/\E \w+
$}x
);
my @rows = map { $_->parent->parent } @links;
my @books;
for my $row (@rows) {
my %book;
my @cells = $row->look_down( _tag => 'td' );
$book{title} =$cells[0]->as_trimmed_text;
$book{price} =$cells[2]->as_trimmed_text;
$book{price} =~ s/^\$//;
$book{url} = get_url( $cells[0] );
$book{ebook} = get_url( $cells[3] );
$book{safari} = get_url( $cells[4] );
$book{examples} = get_url( $cells[5] );
push @books, \%book;
}
sub get_url {
my $node = shift;
my @hrefs = $node->look_down( _tag => 'a');
return unless @hrefs;
my $url = $hrefs[0]->atr('href');
$url =~ s/\s+$//;
return $url;
}
$p = $p->delete; #we don't need this anymore.
{
my $count = 1;
my @perlbooks = sort { $a->{price} <=> $b->{price} }
grep { $_->{title} =~/perl/i } @books;
print $count++, "\t", $_->{price}, "\t", $_->{title} for @perlbooks;
}
{
my @perlbooks = grep { $_->{title} =~ /perl/i } @books;
my @javabooks = grep { $_->{title} =~ /java/i } @books;
my $diff = @javabooks - @perlbooks;
print "There are ".@perlbooks." Perl books and ".@javabooks. " Java books. $diff more Java than Perl.";
}
for my $book ( $books[34] ) {
my $url = $book->{url};
my $page = get( $url );
my $tree = HTML::TreeBuilder->new_from_content( $page );
my ($pubinfo) = $tree->look_down(
_tag => 'span',
class => 'secondary2'
);
my $html = $pubinfo->as_HTML; print $html;
my ($pages) = $html =~ /(\d+) pages/,
my ($edition) = $html =~ /(\d)(?:st|nd|rd|th) Edition/;
my ($date) = $html =~ /(\w+ (19|20)\d\d)/;
print "\n$pages $edition $date\n";
my ($img_node) = $tree->look_down(
_tag => 'img',
src => qr{^/catalog/covers/},
);
my $img_url = 'http://www.oreilly.com'.$img_node->attr('src');
my $cover = get( $img_url );
# now save $cover to disk
}
Run Code Online (Sandbox Code Playgroud)
表格的错误:
Can't call method _________ on an undefined value at _________ line ___
Run Code Online (Sandbox Code Playgroud)
意味着你有这样的结构:
$object->method
Run Code Online (Sandbox Code Playgroud)
并且左边($object)的东西的值是未定义的.
这意味着在你的情况下,第67行附近$pubinfo是未定义的.您必须在视觉上通过代码进行备份以找出原因.在这种情况下,$tree->look_down()必须返回未定义的值.
正如已经指出的那样,这可能与页面结构的变化有关.元素不再是它们应该存在的地方.获取HTML页面的源代码和代码,看看您是否能够理解它最初尝试做什么并将其应用到新页面.希望这本书足够好,即使没有一个有效的例子,你也能理解代码.
| 归档时间: |
|
| 查看次数: |
495 次 |
| 最近记录: |