2011-05-21 83 views
3

我仍在学习Perl,因此缺乏技术术语知识和一般新手道歉。将机械化浏览器传递给子例程(Perl与WWW ::机械化)

我想写一个脚本来登录我的课程作品帐户并下载所有文件。我只能待上一个小时,直到我必须重新登录为止,所以我想在子程序中进行登录工作,这样我可以根据时间调用它并重新登录并继续爬行。我的问题是,我希望能够在子程序和主代码之间来回传递浏览器(术语,请参阅下面的示例,这将更有意义)。

这是我迄今为止,它不工作:

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; 
} 

这是说我不能在$browser -> get($url);“呼叫方法未定义的值‘得到’”。所以我猜测初始化主代码中的浏览器不起作用(因为它没有传递给子程序)Y/N?

好凉所以后来我试图做到这一点在子程序本身如下:

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; 
} 

这一次,我收到以下错误信息:“位于C缺少的基础参数:/ Perl64/lib目录/ HTTP/Response.pm线93"

所以,我删除线路中的子程序,直到它的工作,并发现它编译时,它看起来如下:

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; 
} 

但它显然只是返回加尔巴GE。

我认为问题是,正如我所说的,试图将浏览器对象传递给子例程,因为我不认为它只是一个标量(因为我可以从中得到类似“内容”的东西),但是我实际上并不确定。我也很困惑,因为当我在子程序中初始化它时,我仍然遇到问题!!我也试图让$ browser成为一个全局变量,但是我在两个代码中都得到了相同的错误。很明显,我在这里错过了一些东西。

感谢所有通过它的人,我知道它有点啰嗦,可能是一个非常简单的答案,打击我的经验不足。

回答

4

首次呼叫登录为整个剧本没有浏览器,用户名等

如果您需要,但机械化的一个实例(和将使用相同的用户登录),你可以依靠全局变量。

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'); 
} 

或者更好的,通过你的数据在每次登录:

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'); 
} 

如果你想有一个新的机械化实例每次,比如,它在登陆和返回。

+0

不错!我知道这是愚蠢的。我读过的教程之一是通过键入'sub();'来开始“初始化”子程序。我无法让你的代码工作,但我只是删除了'login();'这一行,它工作得很好! – msikd65 2011-05-21 09:26:00

+0

@ i-blis嗨,我最近有一个非常类似的问题,我想知道是否有可能在sub中创建一个新的'Mechanize'实例*然后返回它,然后作为参数传递给另一个sub? – 2013-03-19 02:29:18

+0

@EugeneS,当然,有一个实例化代理的子实体,做你想要的任何东西并返回它。你遇到了什么问题? – 2013-03-25 19:16:29