fdavidg2019 has asked for the wisdom of the Perl Monks concerning the following question:
Hello, I have been away from Perl for about 10 years and I am trying to get back up to speed. The following script returns a "Not a HASH reference" error as shown in this printout from running the script (the script follow the ouput:
C:\Strawberry\perl\bin>C:\Strawberry\perl\bin\perl.exe "C:\Users\Bonni +e\My Documents\alexa2.pl" http://www.gamegrene.com/ URI: http://data.alexa.com/data?cli=10&dat=snba&ver=7.0&url=http%3A%2F +%2Fwww.gam egrene.com%2F Page: <?xml version="1.0" encoding="UTF-8"?> <!-- Need more Alexa data? Find our APIs here: https://aws.amazon.com +/alexa/ -- > <ALEXA VER="0.9" URL="gamegrene.com/" HOME="0" AID="=" IDN="gamegrene. +com/"> <RLS PREFIX="http://" more="0"> <RL HREF="www.gamereport.com/" TITLE="The Game Report Online"/> <RL HREF="www.chimeramag.com/" TITLE="Chimera The Codependent Gaming M +agazine"/> <RL HREF="www.videounderbelly.com/wiki/Main_Page" TITLE="Main Page - V +ideo Under belly"/> <RL HREF="www.ncbuy.com/" TITLE="Ncbuy"/> <RL HREF="www.gnomestew.com/" TITLE="Gnome Stew, the Game Mastering Bl +og"/> <RL HREF="www.findwhitepapers.com/" TITLE="Find White Papers and Techn +ology Rese arch"/> <RL HREF="www.disobey.com/" TITLE="Disobey: Content for the Discontent +ed"/> <RL HREF="www.3dgamers.com/" TITLE="3D Gamers"/> <RL HREF="andreys.info/" TITLE="andrey's daily light and shadow | + photo blo g | photography by"/> <RL HREF="www.womengamers.com/" TITLE="Women Gamers"/> </RLS> <SD TITLE="A" FLAGS="" HOST="gamegrene.com"> <TITLE TEXT="Gamegrene"/> <OWNER NAME="Disobey"/> </SD> <SD><POPULARITY URL="gamegrene.com/" TEXT="6678166" SOURCE="panel"/><R +EACH RANK= "5826716"/><RANK DELTA="-550802"/></SD></ALEXA> XML: HASH(0x410f378) XML: HASH(0x410f378) Not a HASH reference at C:\Users\Bonnie\My Documents\alexa2.pl line 65 + (#1) (F) Perl was trying to evaluate a reference to a hash value, but f +ound a reference to something else instead. You can use the ref() functi +on to find out what kind of ref it really was. See perlref. Uncaught exception from user code: Not a HASH reference at C:\Users\Bonnie\My Documents\alexa2.pl + line 65. main::handle_xml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\x +{d}\x{a}\x {d}\x{a}<!-- Need more Alex"...) called at C:\Users\Bonnie\My Document +s\alexa2.p l line 83 C:\Strawberry\perl\bin>
#!/usr/bin/perl -w use diagnostics; use strict; no strict qw(refs); use URI; use LWP::Simple; use Net::Amazon; use XML::Simple; use constant AMAZON_TOKEN => 'amzn.mws.ccb04f71-d980-5fa6-0aed-b874a4b +a9d58'; use constant DEBUG => 0; # get our arguments. the first argument is the # URL to fetch, and the second is the output. my $url = shift || die "$0 <url> [<output>]\n"; my $output = shift || '/www/htdocs/cloud.html'; # we'll need to fetch the Alexa XML at some point, and # we'll do it a few different times, so we create a # subroutine for it. Using the URI module, we can # correctly encode a URL with a query. In fact, you'll # notice the majority of this function is involved with # this, and at the end we use LWP::Simple to actually # download and return the XML. ##################################################### sub fetch_xml { my $url = shift; $url = "http://$url" unless $url =~ m[^http://]; warn "Fetching Alexa data for $url\n" if DEBUG; my @args = ( cli => 10, dat => 'snba', ver => '7.0', url => $url ); my $base = 'http://data.alexa.com/data'; my $uri = URI->new( $base ); $uri->query_form( @args ); $uri = $uri->as_string; print "\nURI: $uri\n"; return get( $uri ); } # raw XML is no good for us, though, as we want to extract # particular items of interest. we use XML::Simple to turn # the XML into Perl data structures, because it's easier # than fiddling with event handling (as with XML::Parser # or XML::SAX), and we know there's only a small amount of # data. we want the list of related sites and the list of # related products. we extract and return both. ##################################################### sub handle_xml { my $page = shift; print "\nPage: $page\n"; my $xml = XMLin( $page ); print "\nXML: $xml\n"; my @related = map { { asin => $_->{ASIN}, title => $_->{TITLE}, href => $xml->{RLS}{PREFIX}.$_->{HREF} } } @{ $xml->{RLS}{RL} }; print "\nXML: $xml\n"; print $xml->{SD}{AMZN}{PRODUCT}; my $refxml = (ref($xml->{SD}{AMZN}{PRODUCT})); print $refxml; my @products; if (ref($xml->{SD}{AMZN}{PRODUCT}) eq "ARRAY") { @products = map { $_->{ASIN} } @{ $xml->{SD}{AMZN}{PRODUCT} }; } else { @products = $xml->{SD}{AMZN}{PRODUCT}{ASIN}; } return ( \@related, \@products ); } # Functions done; now for the program: warn "Start URL is $url\n" if DEBUG; my @products; # running accumulation of product ASINs { my $page = fetch_xml( $url ); my ($related, $new_products) = handle_xml( $page ); @products = @$new_products; # running list for (@$related) { my $xml = fetch_xml( $_->{href} ); my ($related, $new_products) = handle_xml( $page ); push @products, @$new_products; } } # We now have a list of products in @products, so # we'd best do something with them. Let's look # them up on Amazon and see what their titles are. my $amazon = Net::Amazon->new( token => AMAZON_TOKEN ); my %products = map { $_ => undef } @products; for my $asin ( sort keys %products ) { warn "Searching for $asin...\n" if DEBUG; my $response = $amazon->search( asin => $asin ); my @products = $response->properties; die "ASIN is not unique!?" unless @products == 1; my $product = $products[0]; $products{$asin} = { name => $product->ProductName, price => $product->OurPrice, asin => $asin, }; } # Right. We now have name, price, and # ASIN. Let's output an HTML report: { umask 022; warn "Writing to $output\n" if DEBUG; open my $fh, '>', $output or die $!; print $fh "<html><head><title>Cloud around $url</title></head><bod +y>"; if (keys %products) { print $fh "<table>"; for my $asin (sort keys %products) { my $data = $products{$asin}; printf $fh "<tr><td>". "<a href=\"http://amazon.com/exec/obidos/ASIN/% +s\">". "%s</a></td> <td>%s</td></tr>", @{$data}{qw( asin name price )}; } print $fh "</table>"; } else { print $fh "No related products found.\n"; } print $fh "</body></html>\n"; }
The script is from the book "Spidering Hacks" and I wonder if I am running into problems as a result of changes in the Perl language from version 5.10 (when the book was written??) until today. I am using 5.30 Thank you for any and all insight on solving this. Frank
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Not a HASH reference
by poj (Abbot) on Jul 09, 2019 at 18:09 UTC | |
by fdavidg2019 (Initiate) on Jul 09, 2019 at 23:44 UTC | |
by tobyink (Canon) on Jul 10, 2019 at 00:01 UTC | |
|
Re: Not a HASH reference
by Jenda (Abbot) on Jul 10, 2019 at 08:46 UTC | |
|
Re: Not a HASH reference
by Anonymous Monk on Jul 09, 2019 at 16:14 UTC |