2011-05-21 79 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