【问题标题】:How to use synchronize method with WWW::Mechanize::Firefox?如何在 WWW::Mechanize::Firefox 中使用同步方法?
【发布时间】:2018-10-06 01:52:20
【问题描述】:

我正在使用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;

打印新加载页面的标题,但脚本只是挂起。它永远不会退出。我错过了什么?

【问题讨论】:

  • DOMConentLoaded 应该是 DOMContentLoaded。另外,请注意,您提供的回调通常应该是一个会引发给定事件的操作(例如对click 的调用)。显然,一个简单的print 语句不会那样做。你想达到什么目的?
  • 我想在没有sleep 命令的情况下执行下一个操作之前等待页面加载。
  • 接下来的动作是检查页面的标题,看是否登录成功。如果我不sleep,它会返回登录页面的标题。
  • @StevieD:尝试在匿名子例程中调用submit_form,并将print 移动到synchronize 调用之后。这至少是它应该工作的方式。我在平板电脑上无法为您编写代码
  • @StevieD 这是怎么回事?我很想知道答案是否有效,就像它们对我一样。

标签: perl www-mechanize-firefox


【解决方案1】:

您传递给synchronize 的子例程旨在执行一些启动浏览器页面更新的操作。 synchronize 调用它,然后在它返回之前等待你指定的事件

显然您的print 语句根本不会更改网页,因此不会触发任何事件并且您的代码将无限期暂停

我建议你在传递给synchronize 的子例程中调用submit_form。这至少有可能导致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;

【讨论】:

  • 这是我已经尝试过的,同样的事情发生了:新页面被加载,然后脚本就挂了。
  • @StevieD:那么真的很难知道该建议什么。您能告诉我们网站的名称以便我进行测试吗?
  • 这只是一个通用的 WordPress 网站。但是,我不能给你它的登录凭据。
【解决方案2】:

Short 以下两种解决方案 - 不指定要等待的事件(以便使用其默认列表),或使用会自行等待的 click 方法,而不是submit_form.


我发现form_submitsynchronize 方法存在同样的问题。要么下一个调用仍然获得正在提交的页面,要么脚本挂起synchronize(正确使用,如Borodin's answer)。我使用一个网站进行测试,该网站在提交表单时会做一些工作。

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

【讨论】:

    猜你喜欢
    • 2016-04-12
    • 1970-01-01
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2013-10-05
    • 1970-01-01
    相关资源
    最近更新 更多