2009-06-09 15 views
5

Tôi rất mới để Perl và tôi đang học trên bay trong khi tôi cố gắng để tự động hóa một số dự án cho công việc. Cho đến nay nó đã được rất nhiều niềm vui.Làm cách nào để sử dụng và gỡ lỗi WWW :: Mechanize?

Tôi đang làm việc để tạo báo cáo cho khách hàng. Tôi có thể nhận được báo cáo này từ một trang web mà tôi có thể truy cập. Trước tiên, tôi sẽ cần phải điền vào một biểu mẫu với tên người dùng, mật khẩu của tôi và chọn một máy chủ từ danh sách thả xuống và đăng nhập. Thứ hai tôi cần nhấp vào liên kết cho phần báo cáo. Thứ ba cần điền vào biểu mẫu để tạo báo cáo.

Dưới đây là những gì tôi đã viết cho đến nay:

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(); 

Tôi không hiểu tại sao, nhưng, sau này tôi nhìn vào những gì đổ ra và tôi thấy đoạn mã cho trang đăng nhập đầu tiên, trong khi i belive i nên đã đến trang tiếp theo sau khi đăng nhập thành công của tôi.

Có thể có thứ gì đó có cookie có thể ảnh hưởng đến tôi và nỗ lực đăng nhập không?

Bất kỳ điều gì khác tôi đang làm sai?

Đánh giá cao bạn giúp đỡ, Yaniv

Trả lời

2

Bạn chỉ có thể cơ giới hóa công cụ mà bạn biết. Trước khi bạn viết thêm bất kỳ mã nào, tôi khuyên bạn nên sử dụng một công cụ như Firebug và kiểm tra những gì đang xảy ra trong trình duyệt của bạn khi bạn thực hiện việc này theo cách thủ công.

Tất nhiên có thể có cookie được sử dụng. Hoặc có thể bạn đã quên tham số biểu mẫu ẩn? Chỉ có bạn mới có thể biết được.

EDIT:

  • WWW :: mechanize nên chăm sóc các tập tin cookie mà không cần bất kỳ sự can thiệp sâu hơn.
  • Bạn nên luôn kiểm tra xem các phương pháp bạn đã gọi có thành công hay không. Công cụ get() đầu tiên có hoạt động không?
  • Có thể hữu ích khi xem nhật ký máy chủ để xem những gì thực sự được yêu cầu và mã trạng thái HTTP nào được gửi dưới dạng phản hồi.
+0

Thanx Manni. Tôi có Firebug nhưng tôi không chắc chắn chính xác những gì cần tìm. Tôi kiểm tra cookie ở đâu? Tôi đã xem xét tất cả các thông số và không có thông số ẩn nào. –

+0

Nhìn vào tab có chữ "Net". Nó sẽ tiết lộ tất cả các tiêu đề HTTP được gửi bởi máy chủ, bao gồm bất kỳ cookie nào. – innaM

+0

Đây là những gì tôi nhận được từ mã của tôi: GET http: //XXXX/Console/login/login.aspx Accept-Encoding: gzip, x-gzip, deflate User-Agent: libwww-perl/5,822 (không có nội dung) HTTP/1.1 200 OK cache-Control: private kết nối: gần ngày: Mon, 08 Tháng sáu 2009 15:08:32 GMT server: Microsoft-IIS/6.0 Content-Length: 14.720 trang nội dung Loại: văn bản/html; charset = utf-8 Khách hàng-Ngày: Thứ Hai, 08 Tháng Sáu 2009 15:08:32 GMT Khách hàng-Peer: X.X.X.X: 80 Khách hàng-Trả lời-Num: 1 –

6

Đây là vài tháng sau khi thực tế, nhưng tôi đã giải quyết cùng một vấn đề dựa trên một câu hỏi tương tự mà tôi đã hỏi. Xem Is it possible to automate postback from the client side? để biết thêm thông tin.

Tôi đã sử dụng Cơ chế của Python thay vì hoặc Perl, nhưng nguyên tắc tương tự cũng được áp dụng.

Tóm tắt phản ứng trước đây của tôi:

trang ASP.NET cần một tham số ẩn có tên __EVENTTARGET theo hình thức, trong đó sẽ không tồn tại khi bạn sử dụng cơ giới hóa bình thường.

Khi được người dùng bình thường truy cập, có chức năng __doPostBack ('foo') trên các trang này cung cấp giá trị có liên quan cho __EVENTTARGET qua sự kiện javascript onclick trên mỗi liên kết, nhưng do cơ giới hóa không sử dụng javascript bạn sẽ cần phải tự mình đặt các giá trị này.

Giải pháp python ở dưới, nhưng không quá khó để thích ứng với 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 
+0

Tôi đã thử điều này nhưng đối với vấn đề của tôi nó vẫn không hoạt động. Firebug cho thấy rằng một param khác (__EVENTARGUMENT) cũng được thông qua. Tôi đã thêm cả điều đó và __EVENTTARGET nhưng chúng dường như bị bỏ qua - tôi luôn nhận được kết quả tương tự (tôi cần những kết quả này để phân trang - truy cập các trang tiếp theo). –

+0

@HD: Bạn đã truy cập trang của mình bằng cách gửi biểu mẫu chưa? (Ví dụ: chức năng "Tìm kiếm tiện ích" đã cung cấp cho bạn danh sách kết quả được phân trang) Nếu bạn truy cập trang bằng biểu mẫu, điều đó có thể phức tạp hơn vì bạn cũng sẽ có __VIEWSTATE dài để đối phó với điều đó. Nếu bạn có thể gửi một liên kết tôi có thể cung cấp cho nó một cái nhìn – anschauung

+0

@HD: Tôi cũng tìm thấy trên một số trang web mà bạn cần phải thanh lọc ra một số giá trị biểu mẫu không liên quan. Bạn có thể xem tất cả các giá trị trường bằng cách sử dụng select_form và xóa chúng bằng bất kỳ phương tiện nào mà ngôn ngữ ưa thích của bạn sử dụng để xóa các phần tử mảng. (ví dụ .pop() trong python) Thật không may, thử nghiệm và lỗi là cách duy nhất tôi đã tìm thấy để xác định vị trí các yếu tố này. – anschauung

0

Rất ngắn gọn về các trang aspx mà họ giữ tất cả thông tin phiên cục bộ trong một vài biến được bắt đầu bằng "__" trong dạng chung chung. Thông thường đây là một hình thức cấp cao nhất và tất cả các yếu tố hình thức sẽ là một phần của nó, nhưng tôi đoán rằng có thể khác nhau bằng cách thực hiện.

Đối với việc thực hiện đặc biệt là tôi đã làm việc với tôi cần phải lo lắng về 2 trong số này biến trạng thái, cụ thể:

__VIEWSTATE 
__EVENTVALIDATION. 

Mục tiêu của bạn là để đảm bảo rằng các biến này được nộp vào mẫu bạn đang gửi, vì chúng có thể là một phần của dạng biểu mẫu chính mà tôi đã đề cập ở trên và bạn có thể đang gửi một biểu mẫu khác.

Khi trình duyệt tải trang aspx một đoạn javascript chuyển thông tin phiên này cùng với tương tác máy chủ/khách hàng asp, nhưng tất nhiên chúng tôi không có sự sang trọng đó với cơ chế perl, vì vậy bạn sẽ cần đăng thủ công chính bạn bằng cách thêm các phần tử vào biểu mẫu hiện tại bằng cách sử dụng cơ giới hóa.

Trong trường hợp đó tôi chỉ giải quyết về cơ bản tôi đã làm điều này:

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(); 
2

Nếu bạn đang trên Windows, sử dụng Fiddler để xem những gì dữ liệu đang được gửi đi khi bạn thực hiện quá trình này bằng tay, và sau đó sử dụng Fiddler để so sánh nó với dữ liệu được chụp khi được kịch bản của bạn thực hiện.

Theo kinh nghiệm của tôi, proxy gỡ lỗi web như Fiddler hữu ích hơn Firebug khi kiểm tra bài đăng biểu mẫu.

1

Tôi thấy rất hữu ích khi sử dụng tiện ích Wireshark khi viết tự động hóa web với WWW::Mechanize. Nó sẽ giúp bạn theo một vài cách:

  1. Cho phép bạn nhận ra liệu yêu cầu HTTP của bạn có thành công hay không.
  2. Xem lý do lỗi trên cấp HTTP.
  3. Theo dõi dữ liệu chính xác mà bạn chuyển đến máy chủ và xem những gì bạn nhận được.

Chỉ cần đặt bộ lọc HTTP cho lưu lượng truy cập mạng và bắt đầu tập lệnh Perl của bạn.

Các vấn đề liên quan