简体   繁体   English

如何在WWW :: Mechanize :: Firefox中使用同步方法?

[英]How to use synchronize method with WWW::Mechanize::Firefox?

I'm using WWW::Mechanize::Firefox and am trying to use the synchronize method like so: 我正在使用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;

The title of the newly loaded page prints but then the script just hangs. 打印新加载的页面的标题,但是脚本只是挂起。 It never exits. 它永远不会退出。 What am I missing? 我想念什么?

The subroutine that you pass to synchronize is meant to do something that kicks off an update to the browser page. 您传递来进行synchronize的子例程旨在执行一些操作,以启动浏览器页面的更新。 synchronize calls it and then waits for the event you have specified before it returns synchronize调用它,然后在返回之前等待您指定的事件

Clearly your print statement won't change the web page at all, so no events will fire and your code will be suspended indefinitely 显然,您的print声明根本不会更改网页,因此不会触发任何事件,并且您的代码将无限期地暂停

I suggest you put the call to submit_form in the subroutine you pass to synchronize . 我建议你把电话给submit_form在传递给子程序synchronize That at least stands a chance of causing DOMContentLoaded to fire 至少有可能导致DOMContentLoaded触发

It would look like this 看起来像这样

$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;

Short Two solutions below -- Don't specify the event to wait for (so that its default list is used), or use click method which does wait on its own, instead of submit_form . 以下是两个简短的解决方案-不要指定要等待的事件(以便使用其默认列表),或者使用会自行等待的click方法,而不是submit_form


I see the same problem with form_submit , and with the synchronize method. 我看到了同样的问题form_submit ,并与synchronize方法。 Either the next call still gets the page being submitted, or the script hangs with synchronize (used, correctly, as in Borodin's answer ). 下一个调用仍然可以获取正在提交的页面,或者脚本因synchronize挂起(正确使用,如Borodin的答案所示 )。 I test with a site which does a bit of work as a form is submitted. 我在一个提交表单的网站上进行了一些测试。

Wrapping calls in synchronize is borne with some subtleties. synchronize包装呼叫有一些微妙之处。 What events are fired or not is not clear and can also be affected (earlier in the code). 是否触发什么事件尚不清楚,也可能会受到影响(代码前面)。 I found that the code works when no events are specified in the call, and the default list of events() is thus checked for. 我发现当调用中未指定任何事件时,该代码有效,并因此检查了events()的默认列表。

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

The following call gets the correct page. 以下调用获取正确的页面。


The documentation never mentions waiting with form methods, so some synchronization is needed. 该文档从未提及等待form方法,因此需要一些同步。 However, the click method does wait , by default (one can change that with synchronize option). 但是,默认情况下, click方法确实会等待 (可以使用synchronize选项更改该方法)。

So I found this to solve the problem as well: Fill the form and click it. 因此,我也找到了解决此问题的方法:填写表格, 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');

The next call after click gets the actual next page. click后的下一个呼叫将获取实际的下一页。

In case the form has no name on <input> , for example, this works as well 例如,如果表单在<input>上没有名称,这也可以

$mech->click_button(input => 'submit');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM