Как использовать метод синхронизации с 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');