javascripthtmlperlwww-mechanize-firefox

WWW::Mechanize::Firefox clicking all images of a class


I am trying to crawl all links on an internal site using WWW::Mechanize::Firefox. The site loads some content via javascript, so I have to click certain elements of the same class "expand" at first. The structure of the site is like this:

<table>
  <tr>
    <td>
     <a id="xyz" href="somesite"> Content </a>
    </td>
  </tr>
  <tr>
    <td>
      <div>
        <a id="twistie" onclick="expand_this">
          <img class="expand" border="0" width="13" height="13" alt="Show All" title="Show All" src="images/plus.gif">
        </a>
      </div>
    </td>
   </tr>
</table>

clicking on the image loads more content in the div-container. On the site, there are multiple of these images of class expand, and I have to click them all for accessing all content. This is where I fail.

What I have tried so far:

$mech->click( { xpath => '//img[@class="expand"]', synchronize => 0 } );

This clicks only the first of the image-elements.

my @images = $mech->xpath( '//img[@class="expand"]', synchronize => 0 );

returns as many array elements as I can count manually on my page. However, I am a bit lost on how to insert the array-elements returned into the click-action.

I can open the first element with

$mech->click( { xpath => '//img[@class="expand"][0]', synchronize => 0 } );

But

$mech->click( { xpath => '//img[@class="expand"][1]', synchronize => 0 } );

returns me

No elements found for //img[@class="expand"][1] at (eval 1377)[/usr/share/perl/5.18/perl5db.pl:732] line 2.

I tried this approach further:

foreach my $id ( 0 .. scalar @images ) { 
    print $id, "\n";
    $mech->click( { xpath => qq(//img[\@class="expand"]["$id"]), synchronize => 0 }); 

}   

but this doesn't open up any elements (no idea why).

Am I missing something here? What do I need to do to click all img-tags of a shared class, as the images unfortunately miss an id?


Solution

  • You have Perl array with image objects already - just iterate over it, instead of asking mech to iterate over its collection.

    foreach (@images) { $mech->click($_) }