开发者

Passing mechanized browser to subroutine (Perl with WWW::Mechanized)

I am still learning Perl so apologies on lack of technical term knowledge and general newbie-ness.

I am trying to write a script to log into my course works account and download all the files. I can only stay in for about an hour until I have to re-log in, so I want to do the log-in work in a subroutine so that way depending on the time I can just call it and log-back in and continue crawling. My problem is that I want to be able to pass the browser (? on terminology, see example below it will make more sense) back and forth between the subroutine and main code.

This is what I have so far and it does not work:

use strict;
use WWW::Mechanize;

login();
my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $browser = WWW::Mechanize->new();

my $response = login ($username,$password,$url,$browser);
print $response->content;

sub login {
    my ($user,$pass,$url,$browser) = @_;
    $browser -> get($url);
    $browser -> form_name('theform');
开发者_开发问答    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
    return $browser;
}

This says I cannot "call method 'get' on an undefined value" at $browser -> get($url);. So I'm guessing that initializing the browser in the main code didn't work (as in it was not passed to the subroutine) Y/N??

Ok cool so then I tried to do it in the subroutine itself as follows:

use strict;
use WWW::Mechanize;

login();
my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $response = login ($username,$password,$url,$browser);
print $response->content;

sub login {
    my ($user,$pass,$url) = @_;
    my $browser = WWW::Mechanize->new();
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
    return $browser;
}

This time I get the following error message: "Missing base argument at C:/Perl64/lib/HTTP/Response.pm line 93"

So, I deleted lines in the subroutine until it worked, and found out that it compiles when it looks as follows:

use strict;
use WWW::Mechanize;

login();
my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $response = login ($username,$password,$url,$browser);
print $response->content;

sub login {
    my ($user,$pass,$url) = @_;
    my $browser = WWW::Mechanize->new();
#   $browser -> get($url);
#   $browser -> form_name('theform');
#   $browser -> field ('username' => $user);
#   $browser -> field ('password' => $pass);
#   $browser -> click ('log in');
    return $browser;
}

but it obviously just returns garbage.

I think the problem is, as I said, trying to pass the browser object to the subroutine as I don't think it is simply a scalar (because I can get things like "content" from it), but I'm actually really not sure. I am also confused because when I initialize it in the subroutine I still get a problem!!????? I also tried to make $browser a global variable, but I get the same errors in both codes. Obviously I am missing something here.

Thanks in advance to all who get through it I know its a little long-winded for probably a really simple answer that hits at my inexperience.


Your first call to login provides no browser, username etc.

If you need but one instance of Mechanize (and will login with the same user) throughout the script, you could rely on global variables.

use strict;
use WWW::Mechanize;

my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $browser = WWW::Mechanize->new();

login();
print $browser->$response->content;

sub login {
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
}

Or better, pass your data to login each time:

use strict;
use WWW::Mechanize;

my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $browser = WWW::Mechanize->new();

login ($username,$password,$url);
print $browser->$response->content;

sub login {
    my ($user,$pass,$url) = @_;
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
}

If you want a new Mechanize instance each time, instance it in login and return it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜