Как использовать и отлаживать 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, что может повлиять на меня и попытку входа в систему?

Что-нибудь еще я делаю неправильно?

Благодарю за помощь, Янив


person Community    schedule 09.06.2009    source источник


Ответы (5)


Это произошло через несколько месяцев, но я решил ту же проблему, основываясь на аналогичных вопросах, которые я задавал. См. Можно ли автоматизировать обратную передачу со стороны клиента? для получения дополнительной информации.

Вместо этого я использовал Python's Mechanize или Perl, но принцип тот же.

Резюмируя мой предыдущий ответ:

Страницам ASP.NET требуется скрытый параметр с именем __EVENTTARGET в форме, которого не будет при обычном использовании механизирования.

При посещении обычным пользователем на этих страницах есть функция __doPostBack('foo'), которая присваивает соответствующее значение __EVENTTARGET через событие javascript onclick для каждой из ссылок, но поскольку механизация не использует 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
person anschauung    schedule 17.08.2009
comment
Я пробовал это, но для моей проблемы это все еще не работает. Firebug показал, что передается еще один параметр (__EVENTARGUMENT). Я добавил и это, и __EVENTTARGET, но они, кажется, игнорируются — я всегда получаю одни и те же результаты (мне они нужны для пейджинга — доступа к последующим страницам). - person HD.; 29.09.2009
comment
@HD: Вы попали на свою страницу с помощью отправки формы? (Например, функция «Поиск виджетов», которая дает вам постраничный список результатов). Если вы попали на страницу с помощью формы, это может быть намного сложнее, поскольку вам также придется справиться с этим длинным __VIEWSTATE. Если бы вы могли скинуть ссылку, я бы посмотрел - person anschauung; 29.09.2009
comment
@HD: я также обнаружил на некоторых сайтах, что вам также нужно удалить некоторые посторонние значения формы. Вы можете увидеть все значения полей, используя select_form, и очистить их любыми средствами, которые ваш предпочтительный язык использует для удаления элементов массива. (например, .pop() в python). К сожалению, метод проб и ошибок — единственный способ найти эти элементы. - person anschauung; 29.09.2009

Вы можете механизировать только то, что знаете. Прежде чем писать код, я предлагаю вам использовать такой инструмент, как Firebug, и проверить, что происходит в вашем браузере, когда вы делаете это вручную.

Конечно, могут быть файлы cookie, которые используются. Или, может быть, вы забыли скрытый параметр формы? Только ты можешь сказать.

РЕДАКТИРОВАТЬ:

  • WWW::Mechanize должен позаботиться о файлах cookie без какого-либо дополнительного вмешательства.
  • Вы всегда должны проверять, были ли вызванные вами методы успешными. Работает ли первый метод get()?
  • Может быть полезно взглянуть на журналы сервера, чтобы увидеть, что на самом деле запрашивается и какой код состояния HTTP отправляется в качестве ответа.
person innaM    schedule 09.06.2009
comment
Спасибо Манни. У меня есть Firebug, но я точно не знаю, что искать. Где я могу проверить файлы cookie? Просмотрел все параметры, скрытых нет. - person ; 09.06.2009
comment
Посмотрите на вкладку с надписью Net. Он покажет все HTTP-заголовки, отправленные сервером, включая любые файлы cookie. - person innaM; 09.06.2009
comment
Вот что я получил из своего кода: GET XXXX/Console/login/login.aspx Accept -Кодировка: gzip, x-gzip, deflate User-Agent: libwww-perl/5.822 (без содержимого) HTTP/1.1 200 OK Cache-Control: private Connection: close Дата: понедельник, 08 июня 2009 г., 15:08:32 GMT Server : Microsoft-IIS/6.0 Content-Length: 14720 Content-Type: text/html; charset = utf-8 Client-Date: Mon, 08 Jun 2009 15:08:32 GMT Client-Peer: X.X.X.X:80 Client-Response-Num: 1 - person ; 09.06.2009
comment
Ссылка: ‹../server.css›; отн=таблица стилей; type=text/css Обновление: 6010; URL=../login/login.aspx?logoff=true Set-Cookie: ASP.NET_SessionId=ivz5k045r4en4eehrn3yed55; путь=/; HttpOn +ly Заголовок: Консоль — вход X-AspNet-Version: 2.0.50727 X-Meta-CODE-LANGUAGE: C# X-Meta-GENERATOR: Microsoft Visual Studio .NET 7.1 X-Meta-Vs-DefaultClientScript: JavaScript X-Meta -Vs-TargetSchema: schemas.microsoft.com/intellisense/ie5 X-Powered-By: ASP.NET - person ; 09.06.2009
comment
Это не совсем легко читать, но это определенно говорит что-то о файле cookie, содержащем идентификатор сеанса. - person innaM; 09.06.2009
comment
Теперь я ввожу правильные значения, так как вижу в дампе: ctl00$ctl00$cphserver$cphLogin$txtUser=someone (текст) ctl00$ctl00$cphserver$cphLogin$txtPW= (пароль) ctl00$ctl00$cphserver$cphLogin$ ddlServers= Live (опция) [* Live| Тест] ctl00$ctl00$cphserver$cphLogin$btnSignIn=Войти (отправить) ctl00$ctl00$cphserver$cphLogin$btnConfigure=Настроить (отправить) - person ; 09.06.2009
comment
Хорошо, я вижу, что мой user-agnet не тот, мой код отправляет: User-Agent: libwww-perl/5.822 И я пытаюсь использовать это: $mech-›agent_alias('Windows Mozilla'); А в дампе разницы нет!? Зачем? - person ; 09.06.2009

Если вы работаете в Windows, используйте Fiddler, чтобы увидеть, какие данные отправляются при выполнении этого процесса вручную, а затем используйте Fiddler, чтобы сравнить его с данными, полученными при выполнении вашего скрипта.

По моему опыту, прокси-сервер веб-отладки, такой как Fiddler, более полезен, чем Firebug при проверке сообщений формы.

person Mick    schedule 10.05.2012

Я нашел очень полезным использовать утилиту Wireshark при написании веб-автоматизации с помощью WWW::Mechanize. Это поможет вам несколькими способами:

  1. Позволяет вам понять, был ли ваш HTTP-запрос успешным или нет.
  2. См. причину сбоя на уровне HTTP.
  3. Отследите точные данные, которые вы передаете на сервер, и посмотрите, что вы получите обратно.

Просто установите фильтр HTTP для сетевого трафика и запустите сценарий Perl.

person Eugene S    schedule 19.03.2013

Очень краткий смысл страниц aspx заключается в том, что они содержат всю информацию о локальном сеансе в паре переменных с префиксом «__» в общей форме aspx. Обычно это форма верхнего уровня, и все элементы формы будут ее частью, но я предполагаю, что это может варьироваться в зависимости от реализации.

Для конкретной реализации, с которой я имел дело, мне нужно было беспокоиться о двух из этих переменных состояния, а именно:

__VIEWSTATE
__EVENTVALIDATION.

Ваша цель — убедиться, что эти переменные отправлены в форму, которую вы отправляете, поскольку они могут быть частью основной формы aspxform, о которой я упоминал выше, а вы, вероятно, отправляете другую форму.

Когда браузер загружает страницу aspx, фрагмент javascript передает эту информацию о сеансе вместе с взаимодействием сервера и клиента asp, но, конечно, у нас нет такой роскоши с механизмом perl, поэтому вам нужно будет вручную опубликовать их, добавив элементы в текущую форму с помощью механизации.

В случае, который я только что решил, я в основном сделал это:

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();
person kamelkev    schedule 10.05.2012