http://www.perlmonks.org?node_id=689492

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

I have logged into my adsl modem using the following code.

use strict; use WWW::Mechanize; use LWP::Simple; use MIME::Base64; my $pubIP = get("http://whatismyip.org/"); my $url = "http://$pubIP/resetrouter.html"; my $username = "foo"; my $password = "bar"; my $button = "Save/Reboot"; my @args = ( Authorization => "Basic " . MIME::Base64::encode( $username . ':' . $password ) ); my $mech = WWW::Mechanize->new(autocheck => 1); $mech->credentials( $url, "test", $username, $password ); $mech->get( $url, @args ) or die $mech->die; print $mech->content; $mech->click($button);

the return value of print $mech->content; is as follows which means i have successfully logged into my adsl modem:

<html> <head> <meta HTTP-EQUIV='Pragma' CONTENT='no-cache'> <link rel="stylesheet" href='stylemain.css' type='text/css'> <link rel="stylesheet" href='colors.css' type='text/css'> <script language="javascript"> <!-- hide function btnReset() { var code = 'location="rebootinfo.cgi"'; eval(code); } function frmLoad() { var sysReboot = '0'; var lanRefresh = '0'; if ( sysReboot == '1' ) btnReset(); else if ( lanRefresh == '1' ) { var code = 'location="resetrouter.cgi?lanRefresh=0"'; eval(code); } } // done hiding --> </script> </head> <body onLoad='frmLoad()'> <blockquote> <center> <br> <strong>Click the button below to save and reboot the rout +er.</strong> </blockquote></center> <p align="center"> <input type='button' onClick='btnReset()' value='Save/Reboot' +> <br> </p> </body> </html>

but immediately after print statement, as i pass through the $mech->click($button) statement i am getting the error Can't call method "click" on an undefined value at c:/Perl/site/lib/WWW/Mechanize.pm line 707.

did lot of googling and searching perl monk as well...got the results as saying the object is not initiated...in my case $mech....but i can't see how.

Please suggest me where am i doing it wrong.

Replies are listed 'Best First'.
Re: Can't call method "click" on an undefined value
by ikegami (Pope) on Jun 01, 2008 at 03:41 UTC

    Note that the error is origination from within WWW::Mechanize. It's not $mech that's undefined. WWW::Mechanize::click in turns calls the method click of another object.

    The problem is that WWW::Mechanize doesn't find the button you want it to find but proceeds to try to click it anyway. According to the docs,

    The first argument is the name of the button to be clicked

    The document doesn't contain any buttons named Save/Reboot. You'd be better off using a method that can locate a button by value, such as click_button.

    $mech->click_button( value => $button );
      Actually, its because he hasn't selected a form (form_name form_number), and since there are no forms on the page
Re: Can't call method "click" on an undefined value
by Anonymous Monk on Jun 01, 2008 at 03:42 UTC
Re: Can't call method "click" on an undefined value
by ikegami (Pope) on Jun 01, 2008 at 21:07 UTC

    In short, it sounds like you have three problems, one of which hasn't been mentioned yet.

    • There's no FORM element, and it sounds like WWW::Mechanize needs one. That's not even valid HTML.
    • ->click($bttn_val) should probably be ->click_button(value => $bttn_val)
    • WWW::Mechanize can't process JavaScript.
Re: Can't call method "click" on an undefined value
by Anonymous Monk on Jun 01, 2008 at 04:13 UTC
    Look at the javascript, to reset the router, just ->get('.../rebootinfo.cgi');
      appending the cgi to url did it for time being...i am now able to reboot my adsl modem...

      but still i would have wanted to achieve it by clicking the button...anyways will keep trying...am sure object instantiation is creating problem somewhere...but unable to trace it

      thanks for ur help monks...truly appreciated

        That is impossible.
        1. The html is broken (no form tags), which is why there is no default form, to be set as default, or for you to select (via $mech->form_name or $mech->form_number), and why $mech->click doesn't work. This is a bug in WWW::Mechanize, it should throw a useful error messages, example
        use WWW::Mechanize; $ua=WWW::Mechanize->new; $ua->get('http://search.cpan.org');#got a form warn $ua->forms; warn $ua->submit; $ua->get('http://cpan.org');#no forms here warn $ua->forms; warn $ua->submit; #dies here __END__ HTML::Form=HASH(0x1d76ca0) at - line 6. HTTP::Response=HASH(0x1d77114) at - line 7. Warning: something's wrong at - line 9. Can't call method "make_request" on an undefined value at D:/Perl/site +/lib/WWW/Mechanize.pm line 1641.
        2. Clicking the button calls javascript, which is not supported (see WWW::Mechanize::FAQ). Besides, the javascript only redirects to rebootinfo.cgi (and it does that with eval -- whoever wrote this should be shot).
Re: Can't call method "click" on an undefined value
by Anonymous Monk on Jun 01, 2008 at 03:36 UTC
    Please suggest me where am i doing it wrong.

    Upgrade WWW::Mechanize

      upgraded to 1.34 still getting the same error:

      Can't call method "click" on an undefined value at c:/Perl/lib/WWW/Mechanize.pm line 1541.

      eventhough the click function exists in Mechanize.pm

      and changed...$mech->click($buttton) to $mech->click_button(value => $button) which resulted in the following error

      Can't call method "find_input" on an undefined value at c:/Perl/lib/WWW/Mechanize.pm line 1614.