http://qs321.pair.com?node_id=1108805

rbhyland has asked for the wisdom of the Perl Monks concerning the following question:

I am using the following code to try to get the src attribute from all the img tags from a webcomic

#!"C:\xampp\perl\bin\perl.exe" use strict; use warnings; use LWP::UserAgent; use CGI qw(:standard :cgi-lib -debug fatalsToBrowser warningsToBrowser +); use HTML::TokeParser; my $cgi = new CGI; print $cgi->header(); print start_html(-title =>'Save QC'); print "Starting...",br; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; $ua->agent('Mozilla/5.0 Windows Gecko/30.0 Firefox/30.0'); my $response = $ua->get('http://questionablecontent.net/'); if ($response->is_success) { # print $response->decoded_content; # or whatever print br,br,"Success!"; my $tp = HTML::TokeParser->new(\$response) || die "Can't open: $!" +; while (my $token = $tp->get_tag('img')) { my $src = $token->[1]{'src'}; print "src =",$src,br } } else { print $response->decoded_content; # or whatever print br,br,"Failure!"; die $response->status_line; } print end_html;
I get the whole page when I "print response->decoded_content;", but I don't get anything from the get-tag line. What am I doing wrong? I am running this on a windows machine.

Replies are listed 'Best First'.
Re: HTML::TokeParser not giving any tokens.
by jellisii2 (Hermit) on Dec 01, 2014 at 12:55 UTC
    It appears from a quick read of HTML::TokeParser it expects actual HTML in the form of a file handle or string, not a LWP::UserAgent object.
    use strict; use warnings; use LWP::UserAgent; use CGI qw(:standard :cgi-lib -debug fatalsToBrowser warningsToBrowser +); use HTML::TokeParser; my $cgi = new CGI; print $cgi->header(); print start_html(-title =>'Save QC'); print "Starting...",br; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; $ua->agent('Mozilla/5.0 Windows Gecko/30.0 Firefox/30.0'); my $response = $ua->get('http://questionablecontent.net/'); if ($response->is_success) { # print $response->decoded_content; # or whatever print br,br,"Success!"; my $tp = HTML::TokeParser->new(\$response->content) || die "Can't +open: $!"; while (my $token = $tp->get_tag('img')) { my $src = $token->[1]{'src'}; print "src =",$src,br } } else { print $response->decoded_content; # or whatever print br,br,"Failure!"; die $response->status_line; } print end_html;
    Nets the following output:
    (offline mode: enter name=value pairs on standard input; press ^D or ^ +Z when done) Content-Type: text/html; charset=ISO-8859-1 (offline mode: enter name=value pairs on standard input; press ^D or ^ +Z when done) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-U +S"> <head> <title>Save QC</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1 +" /> </head> <body> Starting...<br /><br /><br />Success!src =http://www.projectwonderful. +com/nojs.php?id=39770&type=5<br />src =http://www.questionablecontent +.net/images/patreonad.png<br />src =../images/logo14.png<br />src =ht +tp://www.questionablecontent.net/comics/2845.png<br />src =http://www +.questionablecontent.net/images/1s1k.gif<br />src =http://www.questio +nablecontent.net/images/station.gif<br />src =http://www.questionable +content.net/images/qc-vol04.jpg<br />src =http://www.questionablecont +ent.net/images/yelingboard.jpg<br />src =http://www.questionableconte +nt.net/images/18x24.jpg<br />src =http://www.questionablecontent.net/ +images/mlgshirt.jpg<br />src =../images/ag.gif<br />src =http://api.f +lattr.com/button/flattr-badge-large.png<br />src =http://www.question +ablecontent.net/images/patreonad2.png<br />src =http://www.projectwon +derful.com/nojs.php?id=138&type=2<br /> </body> </html>
    -- edit: Fixed HTML::TokeParser's link.

      That's got it. Thanks! I missed the difference between $response and $response->content. I've been monkeying around with that for about 16 hours.

Re: HTML::TokeParser not giving any tokens.
by karlgoethebier (Abbot) on Dec 01, 2014 at 13:06 UTC

    Try this:

    if ( $response->is_success ) { my $tp = HTML::TokeParser->new( \$response->decoded_content ) || die "Can't open: $!"; while ( my $token = $tp->get_tag('img') ) { print $token->[1]->{'src'}, qq{\n}; } } else { print $response->decoded_content; die $response->status_line; } __END__ Starting...<br /><br /><br />Success!http://www.projectwonderful.com/n +ojs.php?id=39770&type=5 http://www.questionablecontent.net/images/patreonad.png ../images/logo14.png http://www.questionablecontent.net/comics/2845.png http://www.questionablecontent.net/images/1s1k.gif http://www.questionablecontent.net/images/station.gif http://www.questionablecontent.net/images/qc-vol04.jpg http://www.questionablecontent.net/images/yelingboard.jpg http://www.questionablecontent.net/images/18x24.jpg http://www.questionablecontent.net/images/mlgshirt.jpg ../images/ag.gif http://api.flattr.com/button/flattr-badge-large.png http://www.questionablecontent.net/images/patreonad2.png http://www.projectwonderful.com/nojs.php?id=138&type=2

    Update: Added output. NB.: Saw solution above too late :-(

    Regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

      Thanks! I'm using your solution. There's no substitute for understanding. I see now what I did wrong, which is the most important thing.