Как использовать метод синхронизации с WWW::Mechanize::Firefox?

Я использую WWW::Mechanize::Firefox и я пытаюсь использовать synchronize метод вроде так:

$mech->get('http://example.com/wp-login.php');
$mech->submit_form( with_fields => {log => 'admin', pwd => 'password'});
$self->synchronize( 'DOMContentLoaded', sub {print Dumper($self->title()); });
exit;

Печатается название только что загруженной страницы, но затем скрипт просто зависает. Это никогда не выходит. Что мне не хватает?

2 ответа

Подпрограмма, которую вы передаете synchronize предназначен для того, чтобы сделать что-то, что запускает обновление страницы браузера. synchronize вызывает его, а затем ожидает указанное вами событие, прежде чем оно вернется

Ясно ваш print оператор не изменит веб-страницу вообще, поэтому никакие события не будут запущены, и ваш код будет приостановлен на неопределенный срок

Я предлагаю вам позвонить submit_form в подпрограмме вы переходите к synchronize, Это, по крайней мере, имеет шанс вызвать DOMContentLoaded уволить

Это будет выглядеть так

$mech->get('http://example.com/wp-login.php');

$mech->synchronize('DOMContentLoaded', sub {
    $mech->submit_form( with_fields => { log => 'admin', pwd => 'password' });  
});

print Dumper $self->title;

Ниже приведены два коротких решения - не указывайте событие, которое нужно ждать (чтобы использовался его список по умолчанию), или используйте click метод, который ждет самостоятельно, а не submit_form,


Я вижу ту же проблему с form_submit и с synchronize метод. Либо следующий вызов все еще получает отправляемую страницу, либо скрипт зависает с synchronize (использовал, правильно, как в ответе Бородина). Я тестирую сайт, который выполняет небольшую работу, так как форма отправляется.

Упаковка звонков в synchronize несут с собой некоторые тонкости. Какие события запускаются или нет неясно и также могут быть затронуты (ранее в коде). Я обнаружил, что код работает, когда в вызове не указано никаких событий, и список по умолчанию events() Таким образом проверяется на.

mech->synchronize( sub { 
    $mech->submit_form( with_fields => { log => 'admin', pwd => 'password' } );
});
$mech->save_content('after_submit.html');

Следующий вызов получает правильную страницу.


В документации никогда не упоминается ожидание с form методы, поэтому необходима некоторая синхронизация. Тем не менее click по умолчанию метод ожидает (можно изменить это с помощью synchronize опция).

Так что я нашел это, чтобы решить проблему: заполните форму и click Это.

# Get the page with the form
$mech->fields( log => 'admin', pwd => 'password' );
$mech->click( name => 'Login' );  # whatever the name is  
$mech->save_content('after_submit.html');

Следующий звонок после click получает актуальную следующую страницу.

Если форма не имеет имени на <input> например, это работает также

$mech->click_button(input => 'submit');
Другие вопросы по тегам