Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

WWW::Mechanize::TreeBuilder and WWW::Mechanize. Following links but can't return without error

by mdro79 (Initiate)
on Jan 04, 2013 at 23:07 UTC ( #1011735=perlquestion: print w/ replies, xml ) Need Help??
mdro79 has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I am trying to better my understanding of WWW::Mechanize. I have built a simple website of a few pages to practice traversing with WWW::Mechanize and reading html tags, attributes and content with WWW::Mechanize::TreeBuilder.

The website I built is quite simple for now, it contains a top level index.html, which contains a single table. In the table rows are a few cells, containing text and links. I am trying to read the links, follow them to the next page, gather some data, print it, then come back to the next row of the table.

Ultimately I would like to traverse a large table, and make decisions row-by-row on whether to store data from that row, and follow a link to a following page, or whether to skip that row as it doesn't meet my criteria and move on to the next one with no action taken.

I am starting with a simple test skeleton, my index.html page, with rows and links leading to a few other pages -- s1.html, s2.html, s3.html

I run into problems after leaving the current page while looping through the list of links. I would like to leave, gather/print some data, and come back and continue my loop onto the next. What actually happens is my program crashes at this point, complaining of unitialized values in /path/to/HTML/Element.pm. With all that said, here is the code I am having problems with. If I can get my page following and retreating logic nailed down properly that will be a big step for me.

use WWW::Mechanize; use WWW::Mechanize::TreeBuilder; my $mech = ... my @list = $mech->look_down(_tag => "a", class => "links"); foreach (@list) { # see if I want to skip this row, or save/print some # data and follow link to next page # printing data works fine # following a link breaks the loop $mech->get($new_url); # finds the page no problem # do stuff on page, then go back $mech->back(); # complaint is of unitialized "tag", from the look_down # call I assume? }

What I believe is happening is the program runs the main loop OK, but when it leaves the current page, something happens to @list. I don't know what, but leaving the page with $mech->get() seems to break my program.

Comment on WWW::Mechanize::TreeBuilder and WWW::Mechanize. Following links but can't return without error
Download Code
Re: WWW::Mechanize::TreeBuilder and WWW::Mechanize. Following links but can't return without error
by Anonymous Monk on Jan 04, 2013 at 23:32 UTC

      Oh sorry, here is the full code (I thought a snippet would be more clear in that case). This is everything from the folder, the 4 html pages and the perl code.

      mech.pl

      #!/usr/bin/perl use strict; use warnings; use WWW::Mechanize; use WWW::Mechanize::TreeBuilder; my $mech = WWW::Mechanize->new(); WWW::Mechanize::TreeBuilder->meta->apply($mech); $mech->get('file:///home/example/path/index.html'); die "Cannot open file: ", $mech->response->status_line unless $mech->success; my @list = $mech->look_down(_tag => "a", class => "links); foreach (@list) { my $url = "file:///home/example/path/"; $url = $url . $_->attr("href"); print $_->as_text(), " - ", $url, "\n"; $mech->get($url); $mech->back(); }

      index.html

      <html> <head> <title>Web Scraper Testing Grounds</title> <style> .links { font-family: Sans-Serif; } .spans { font-family: Serif; } .trs { border: 1px solid; } </style> </head> <body> <h1>Test Page for WWW::Mechanize scraping</h1> <table> <tr class="trs"> <td><a href="s1.html" class="links">S1 Link Content</a></td> <td><span class="spans">Page S1</span></td> </tr> <tr class="trs"> <td><a href="s2.html" class="links">S2 Link Content</a></td> <td><span class="spans">Page S2</span></td> </tr> <tr class="trs"> <td><a href="s3.html" class="links">S3 Link Content</a></td> <td><span class="spans">Page S3</td> </tr> </table> </body> </html>

      s1.html

      <html> <head></head> <body> <h1>This is the S1 page, first in set</h1> </body> </html>

      s2.html

      <html> <head></head> <body> <h1>This is the S2 page, second in set</h1> </body> </html>

      s3.html

      <html> <head></head> <body> <h1>This is the S3 page, third and final</h1> </body> </html>

      When I try and run the code, this is the output I get

      mdro79@mycpu$ ./mech.pl S1 Link Content - file:///home/example/path/s1.html Use of uninitialized value in concatenation (.) or string at ./scrMe.p +l line 31. Use of uninitialized value $tag in string eq at /usr/local/share/perl/ +5.14.2/HTML/Element.pm line 1109. Use of uninitialized value $tag in string eq at /usr/local/share/perl/ +5.14.2/HTML/Element.pm line 1109. - file:///home/example/path/ Use of uninitialized value in concatenation (.) or string at ./scrMe.p +l line 31. Use of uninitialized value $tag in string eq at /usr/local/share/perl/ +5.14.2/HTML/Element.pm line 1109. Use of uninitialized value $tag in string eq at /usr/local/share/perl/ +5.14.2/HTML/Element.pm line 1109. - file:///home/example/path/

        Whoa, well that is the trouble with trees and trying to save memory :) you can work around it like this

        @list = map { $_->clone } @list;
        or
        my @list = map { $_->clone } $mech->look_down(_tag => "a", class => "l +inks" );
        You do not have to go back if you are not following the links. Also, if $url is static, you can declare it just once before entering the loop.
        لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1011735]
Approved by ansh batra
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (13)
As of 2014-09-19 09:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (133 votes), past polls