Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

How do I call a JavaScript function from WWW::Scripter?

by bbrelin (Initiate)
on Nov 30, 2011 at 23:15 UTC ( #940970=perlquestion: print w/ replies, xml ) Need Help??
bbrelin has asked for the wisdom of the Perl Monks concerning the following question:

Hello all,

I'm trying to write a small script using WWW::Scripter that will take data from a client's web site in order to automate some of their processes. The problem that I'm running into is that to access the data, I have to log on to the web site.

The web site uses a small JavaScript function to handle this. The function is:

function Login() { if(document.forms[0].login_name.value == "") { alert("Please fill in your login name"); document.forms[0]; return; } if(document.forms[0].login_pwd.value == "") { alert("Please fill in your password"); document.forms[0]; return; } document.forms[0].submit(); }

Using WWW::Scripter and the JavaScript plugin (and JE as the back end JS Engine) i've tried doing this:

my sourceWebSite="http://xxxxxxxx"; my $agent = WWW::Scripter->new(); my $code; $agent->use_plugin(JavaScript => engine => "JE", ); $agent->get("$sourceWebSite"); $agent->plugin('JavaScript')->set( $agent,'document','forms[0]','login_name','value'=> 'xxxxxx' ); $agent->plugin('JavaScript')->set( $agent,'document','forms[0]','login_pwd','value'=> 'xxxxxx' );

I'm trying to use the Scripter class eval method to actually run the code. I set a variable $code to contain a string which is basically the JS function listed above and then called the eval method like so.


This doesn't work. At least, it won't then log in and provide me with the "member" content.

Anybody got any thoughts on what I'm missing?


Comment on How do I call a JavaScript function from WWW::Scripter?
Select or Download Code
Replies are listed 'Best First'.
Re: How do I call a JavaScript function from WWW::Scripter?
by keszler (Priest) on Dec 01, 2011 at 00:47 UTC

    Since the javascript is merely checking that both login_name and login_pwd are set to something, and you know that your code will set them both, why bother? Just set the fields and submit the form.

Re: How do I call a JavaScript function from WWW::Scripter?
by Anonymous Monk on Dec 01, 2011 at 09:39 UTC

    ... I'm trying to use the Scripter class eval method to actually run the code....

    You shouldn't have to do that :) any onsubmit or onclick functions should be called by virtue of using a javascript plugin, when you use the submit method

    Like the docs say, WWW::Scripter is a subclass of WWW::Mechanize

    #!/usr/bin/perl -- use strict; use warnings; use URI; use WWW::Scripter; Main( @ARGV ); exit( 0 ); sub Main { my $w = WWW::Scripter->new( autocheck => 1, show_progress => 1, # prints to stderr ); $w->use_plugin('JavaScript'); #~ $w->add_handler("request_send", sub { shift->dump; return }); #~ $w->add_handler("response_done", sub { shift->dump; return }); $w->timeout(0.00000000001); for my $return ( qw/ false true / ) { warn "BowlingRETURNVALUE => $return \n"; $w->get( data_url($return) ); $w->submit; #~ $w->submit_form( #~ form_number => 0, #~ fields => { qw' user_choice Enter ' }, #~ ); } } BEGIN { my $html = <<'HTML'; <html> <head> <title> localhost form </title> <html> <script type="text/javascript"> function Bowling(){ alert("\nStrike\n"); /* prints to stdout */ return BowlingRETURNVALUE; } </script> </head> <body> <base href="http://localhost/"> <form method="POST" action="http://localhost/" onsubmit="return Bowli +ng();">> <input id="enterbutton" type="submit" name="user_choice" value="Enter" + /> <input type="submit" name="user_choice" value="Leave" /> </form> </body> </html> HTML sub data_url { my $return = shift; my $h = $html; $h =~ s/BowlingRETURNVALUE/$return/; my $u = new URI 'data:'; $u->media_type('text/html'); $u->data( $h ); return $u; } } __END__

    As you can see from the log below, first submit doesn't trigger http activity because the onsubmit javascript returns false, but the next one does , because onsubmit callback returns true

    Since I don't have a server on localhost, the timeout causes an almost instant internal 500 error -- everything is working as expected

    BowlingRETURNVALUE => false ** GET data:text/html;base64,PGh0bWw+ID...Pgo= ==> 200 Document follow +s Strike BowlingRETURNVALUE => true ** GET data:text/html;base64,PGh0bWw+ID...+Cg== ==> 200 Document follo +ws Strike ** POST http://localhost/ ==> 500 Can't connect to localhost:80 (timeo +ut) Error POSTing http://localhost/: Can't connect to localhost:80 (timeou +t) at C:/perl/site/5.14.1/lib/WWW/ line 598

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2015-11-26 01:01 GMT
Find Nodes?
    Voting Booth?

    What would be the most significant thing to happen if a rope (or wire) tied the Earth and the Moon together?

    Results (695 votes), past polls