簡體   English   中英

我如何使用和調試WWW :: Mechanize?

[英]How do I use and debug WWW::Mechanize?

我是Perl的新手,當我嘗試自動化一些項目工作時,我正在學習。 到目前為止它已經很有趣了。

我正在為客戶生成報告。 我可以從我可以訪問的網頁上獲取此報告。 首先,我需要用我的用戶名,密碼填寫表格,然后從下拉列表中選擇一個服務器,然后登錄。其次,我需要點擊報告部分的鏈接。 第三,需要填寫表格來創建報告。

這是我到目前為止寫的:

my $mech = WWW::Mechanize->new();
my $url = 'http://X.X.X.X/Console/login/login.aspx';

$mech->get( $url );

$mech->submit_form(
     form_number => 1,
     fields      =>{
        'ctl00$ctl00$cphVeriCentre$cphLogin$txtUser'  => 'someone',
        'ctl00$ctl00$cphVeriCentre$cphLogin$txtPW'    => '12345',
        'ctl00$ctl00$cphVeriCentre$cphLogin$ddlServers'  => 'Live',
     button => 'Sign-In'
   },   
);
die unless ($mech->success);

$mech->dump_forms();

我不明白為什么,但是,在此之后我看看什么轉儲輸出,我看到第一個登錄頁面的代碼,而我相信我應該在我成功登錄后到達下一頁。

可能有一些cookie可以影響我和登錄嘗試嗎?

還有別的我做錯了嗎?

Yaniv,感謝您的幫助

這是事后幾個月,但我根據我提出的類似問題解決了同樣的問題。 請參閱是否可以從客戶端自動回發? 了解更多信息。

我使用Python的Mechanize而不是Perl,但同樣的原則適用。

總結我之前的回應:

ASP.NET頁面在表單中需要一個名為__EVENTTARGET的隱藏參數,當您正常使用mechanize時,該參數將不存在。

當普通用戶訪問時,這些頁面上有一個__doPostBack('foo')函數,通過每個鏈接上的javascript onclick事件為__EVENTTARGET提供相關值,但由於機械化不使用javascript,您需要自己設定這些值。

python解決方案如下所示,但它不應該太難以適應perl。

def add_event_target(form, target):
    #Creates a new __EVENTTARGET control and adds the value specified
    #.NET doesn't generate this in mechanize for some reason -- suspect maybe is 
    #normally generated by javascript or some useragent thing?
    form.new_control('hidden','__EVENTTARGET',attrs = dict(name='__EVENTTARGET'))
    form.set_all_readonly(False)
    form["__EVENTTARGET"] = target

如果您使用的是Windows,請在手動執行此過程時使用Fiddler查看正在發送的數據,然后使用Fiddler將其與腳本執行時捕獲的數據進行比較。

根據我的經驗,在檢查表單帖子時,像Fiddler這樣的Web調試代理比Firebug更有用。

你只能機械化你知道的東西。 在您編寫更多代碼之前,我建議您使用Firebug之類的工具,並在手動執行此操作時檢查瀏覽器中發生的情況。

當然可能會使用cookie。 或者你忘了一個隱藏的表格參數? 只有你可以告訴。

編輯:

  • WWW :: Mechanize應該在沒有任何進一步干預的情況下處理cookie。
  • 您應該始終檢查您調用的方法是否成功。 第一個get()是否有效?
  • 查看服務器日志以查看實際請求的內容以及作為響應發送的HTTP狀態代碼可能很有用。

我發現在使用WWW::Mechanize編寫Web自動化時使用Wireshark實用程序非常有用。 它會以幾種方式幫助您:

  1. 使您能夠意識到您的HTTP請求是否成功。
  2. 查看HTTP級別失敗的原因。
  3. 跟蹤傳遞給服務器的確切數據,並查看收到的內容。

只需為網絡流量設置HTTP過濾器並啟動Perl腳本。

aspx的一個非常簡短的要點就是它將所有本地會話信息保存在一般aspxform中以“__”為前綴的幾個變量中。 通常這是一個頂級形式,所有表單元素都將成為其中的一部分,但我想這可能因實現而異。

對於我正在處理的特定實現,我需要擔心其中的兩個狀態變量,具體來說:

__VIEWSTATE
__EVENTVALIDATION.

您的目標是確保將這些變量提交到您提交的表單中,因為它們可能是我上面提到的主表單aspxform的一部分,並且您可能提交的表單不同於此。

當瀏覽器加載一個aspx頁面時,一段javascript會在asp服務器/客戶端交互中傳遞此會話信息,但當然我們沒有使用perl mechanize的那種奢侈,所以你需要通過添加手動發布這些使用mechanize的當前表單元素。

在我剛剛解決的情況下,我基本上做了這個:

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

# fetch the login page to get the initial session variables
my $login_page = 'http://www.example.com/login.aspx';
$response = $browser->get( $login_page);

# very short way to find the fields so you can add them to your post
$viewstate = ($browser->find_all_inputs( type => 'hidden', name => '__VIEWSTATE' ))[0]->value;
$validation = ($browser->find_all_inputs( type => 'hidden', name => '__EVENTVALIDATION' ))[0]->value;

# post back the formdata you need along with the session variables
$browser->post( $login_page, [ username => 'user', password => 'password, __VIEWSTATE => $viewstate, __EVENTVALIDATION => $validation ]);

# finally get back the content and make sure it looks right
print $response->content();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM