2011-04-07 49 views
1

我試圖登錄到一個網站,使用這種形式與三個輸入進行身份驗證。爲什麼我可以用瀏覽器登錄這個表單,但不是LWP?

<form action="/login.html" method="post"> 
<div class="loginlabel1 aright">ID/Email: </div> 
<div class="bsearchfield"> 
<input type="text" name="profid" class="inputBx" size="15" value="" /> 
</div> 
<div class="clear"></div> 
<div class="loginlabel1 aright">Password: </div> 
<div class="bsearchfield"> 
<input type="password" name="password" class="inputBx" size="15" value="" /> 
</div> 
<div class="clear"></div> 
<div class="loginbutton1"> 
<input name="login"type="image" src="images/logi.gif" align="right" border="0" /> 
</div> 
</form> 

如果我通過瀏覽器登錄,登錄成功重定向我http://www.example.com/myhome.html

但是,以下腳本不會將我登錄並返回相同的login.html頁面。我錯過了什麼?我沒有收到任何錯誤消息。我發佈成功了嗎?

#!/usr/bin/perl -w 
use LWP 5.64; 
my $browser = LWP::UserAgent->new || die " Failed LWP USER AGENT : $!"; 
$ENV{HTTP_proxy} = "http://proxy:port"; 
$browser->env_proxy; 
$browser->cookie_jar({}); 
my @Header = (
        'User-Agent'  => 'Mozilla/4.76 [en] (Win98; U)', 
        'Accept'   => 'image/gif, image/x-xbitmap, image/jpeg,image/pjpeg, image/png, */*', 
        'Accept-Charset' => 'iso-8859-1,*,utf-8', 
        'Accept-Language' => 'en-US', 
      ); 

push @{$browser->requests_redirectable}, 'POST'; 
$response = $browser->post(
    "http://www.example.com/login.html", 
    [ 
     'profid' => 'username', 
     'password' => 'password' 
    ],@Header 
); 

$response->is_success or die "Failed to post: ", $response->status_line; 
print "Successfully posted username and password.\n" if $response->is_fresh; 

#printf("%s",$response->content); 
printf("%s\n", $response->status_line); 
printf("%s", $response->header("Accept-Ranges")); 
printf("%s", $response->header("Age")); 
printf("%s", $response->header("ETag")); 
printf("%s", $response->header("Location")); 
printf("%s", $response->header("Proxy-Authenticate")); 
printf("%s", $response->header("Retry-After")); 
printf("%s", $response->header("Server")); 
printf("%s", $response->header("Vary")); 
printf("%s", $response->header("WWW-Authenticate")); 
delete $ENV{HTTP_PROXY}; 
+0

也許您可以嘗試診斷問題。你是否得到重定向響應代碼或200 OK或其他東西? – 2011-04-07 19:11:40

+0

不,它將返回給我相同的登錄頁面。無錯誤代碼 – Jean 2011-04-07 19:18:25

+0

你的迴應代碼是什麼? 200行嗎?什麼是完整的標題? – 2011-04-07 19:39:10

回答

1

有時它們需要正確的接受編碼和/或引用標頭。當然,我也會嘗試用戶代理標題。

+2

+1這是調試這類問題的準確方法。將請求與網絡嗅探器(如Wireshark)進行比較也有所幫助。 – daxim 2011-04-07 22:54:06

+0

我試圖給一個虛擬標題(見編輯)..但它仍然失敗。 – Jean 2011-04-08 04:54:40

2

您的提交按鈕是一個圖像。當點擊類型圖像的輸入時,瀏覽器會將您單擊的像素座標發送到CGI。在您的表單中,瀏覽器會發送login.xlogin.y以及profidpassword

順便說一句,Firebug是一個很好的調試CGI工具。

0

我也爲Firefox推薦LiveHTTPHeaders。你打開它,然後提交你的表單,並確切顯示GET或POST到網站的所有信息,包括所有標題,參數和cookie,然後顯示來自服務器的所有響應,包括設置cookie,標題和重定向。

頁面上可能存在javascript創建額外的參數,當您只是查看錶單,圖像座標如上所述的PacoRG,或者可能需要先接受cookie並將其與登錄。 LiveHTTPHeaders還允許您修改標題和「重播」 - 這可以讓您修改發送到服務器的內容(任何標題,Cookie,參數等),以幫助確定服務器實際需要登錄的內容。

而且,我相信,LWP默認情況下自動進行重定向,所以頁面可能實際上被重定向和你沒有看到它(我相信「simple_request」功能不遵循redirs。)

在LWP響應,你可以通過任何重定向向後走像這樣:

my $prev_res = $res->previous(); 
while ($prev_res) { 
    print $prev_res->status_line . "\n"; 
    $prev_res = $prev_res->previous(); 
} 

希望這有助於!

-1

你沒有提交被點擊的提交按鈕的名稱;我懷疑另一端的代碼正在檢查請求中是否存在該變量,以查看該表單是否已提交。

由於PacoRG指出,提交按鈕是一個圖像;因此,通過在瀏覽器中單擊該按鈕來提交將提交名爲「login.x」和「login.y」的字段以及「登錄」。

的一個好方法,以避免類似問題的方法是使用WWW::Mechanize做了很多的工作適合你,比如:

my $mech = WWW::Mechanize->new; 
$mech->get('http://www.example.com/login.html'); 
$mech-submit_form(
    with_fields => { 
     profid => $username, 
     password => $password, 
    }, 
); 

以上將請登錄頁面,找到適當的形式,和提交它。另外,正如其他人所說,如果來自腳本的請求的處理方式與來自瀏覽器的請求的處理方式不同,調試的最佳方式是獲取發送的完整HTTP請求,並查找相關差異。對於瀏覽器,您可以使用Firefox的LiveHTTPHeaders或防篡改數據插件等擴展,或使用Wireshark等功能來捕獲發送的請求。對於腳本,您可以輕鬆地輸出請求發送。

例如,對於使用LWP :: UserAgent的或WWW ::機械化(其子類LWP ::用戶代理)的腳本,你可以添加:

$mech->add_handler("request_send", sub { shift->dump; return }); 
$mech->add_handler("response_done", sub { shift->dump; return }); 

這將轉儲原始的請求發送,隨着來自服務器的原始響應。 (將$mech更改爲您的LWP :: UserAgent/WWW :: Mechanize對象所在的變量)

相關問題