Perl WWW :: Mechanize как дочерний класс;не может оставаться в системе на очищенном сайте - PullRequest
3 голосов
/ 03 мая 2011

У меня есть простой скрипт входа в систему, использующий Perl WWW :: Mechanize. Я пишу сценарии для входа в систему Moodle . Когда я просто делаю шаги входа в систему как процедурные шаги, это работает. Например (предположим, что "$ site_url", USERNAME и PASSWORD были установлены соответствующим образом):

#THIS WORKS
$updater->get("http://".$site_url."/login/index.php");
$updater->form_id("login");
$updater->field('username', USERNAME);
$updater->field('password', PASSWORD);
$updater->click();
$updater->get("http://".$site_url."/");
print $updater->content();

Когда я пытаюсь инкапсулировать эти шаги в дочерний класс WWW: Mechanize, get () и content () и другие методы, кажется, работают, но вход на сайт - нет. У меня есть ощущение, что это связано с переменной областью, но я не знаю, как ее решить.

Пример (не работает):

my $updater = new AutoUpdater( $site_url, USERNAME, PASSWORD );
$updater->do_login();

{
package AutoUpdater;
use base qw( WWW::Mechanize );

sub new {
    my $class = shift;
    my $self = {
        site_url => shift,
        USERNAME => shift,
        PASSWORD => shift,
   };
    bless $self, $class;
    return $self;
}

sub do_login {
    my $self = shift;
    $self->get("http://".$site_url."/");
    $self->get("http://".$site_url."/login/index.php");
    $self->form_id("login");
    $self->field("username", $self->{USERNAME});
    $self->field("password", $self->{PASSWORD});
    $self->click();
    $self->get("http://".$site_url."/");
    print $self->content();
}
}

Это не удалось. «Fail» означает, что он не входит в систему. Однако он захватывает веб-страницу, и я могу манипулировать данными HTML. Он просто не входит в систему. Ярг! (Да, "Ярг" был необходим)

Спасибо!

1 Ответ

2 голосов
/ 03 мая 2011

Вот пересмотренная версия:

use strict;
use warnings;

my $updater = AutoUpdater->new( $site_url, USERNAME, PASSWORD );
$updater->do_login();

{
package AutoUpdater;
use parent qw( WWW::Mechanize );

sub new {
  my $class = shift;

  my $self = $class->SUPER::new();

  $self->{AutoUpdater} = {
    site_url => shift,
    USERNAME => shift,
    PASSWORD => shift,
  };

  return $self;
}

sub do_login {
  my $self = shift;
  my $data = $self->{AutoUpdater};

  $self->get("http://$data->{site_url}/login/index.php");
  $self->form_id("login");
  $self->field("username", $data->{USERNAME});
  $self->field("password", $data->{PASSWORD});
  $self->click();
  $self->get("http://$data->{site_url}/");
  print $self->content();
}
} # end package AutoUpdater

Некоторые примечания:

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

Синтаксис косвенного объекта не рекомендуется.Используйте Class->new вместо new Class.

Прагма base имеет некоторые нежелательные эффекты, которые нельзя исправить по причинам обратной совместимости.Для его замены была разработана прагма parent .

Ваша большая проблема заключалась в том, что Perl не инициализирует базовые классы автоматически.При необходимости вы должны явно вызвать $class->SUPER::new.

Другая ваша большая проблема заключалась в понимании того, как обрабатываются данные экземпляра объекта.Большинство объектов Perl являются hashrefs, и вы обращаетесь к данным экземпляра, используя синтаксис hashref.При создании подкласса класса, который я не писал, мне нравится использовать второй хэш-код, чтобы избежать конфликтов с родительским классом.Помните, что вы делитесь объектом с базовыми классами.Если ваш подкласс использует поле site_url, а затем более поздняя версия базового класса начнет использовать site_url для чего-то другого, ваш код внезапно сломается без видимой причины.Используя только один ключ в hashref базового объекта (и тот, который базовый класс вряд ли начнет использовать), вы сводите к минимуму вероятность поломки в будущем.

В то время как Moose предоставляет некоторые приятные функциидля OO-программирования на Perl, если вы просто пишете довольно простой подкласс класса, не принадлежащего Moose, вероятно, лучше этого избегать.

...