"元素在缓存中不存在"使用mechanize :: phantomjs选择单选按钮时出错

时间:2014-11-09 00:09:48

标签: html perl phantomjs mechanize browser-automation

我正在尝试自动化包含Perl中许多javascript函数的网页。到目前为止,我已经通过使用无头mechanize :: phantomjs工具包获得了成功,但我无法避免这个,可能是微不足道的错误。我看到一个带有单选按钮菜单的页面,当我尝试使用

选择其中任何一个时
$mech->set_fields('booking_choice' => "$i");

其中$ i是我的迭代器,'booking_choice'是按钮的名称,我得到下面列出的错误。这就是它在页面上的显示方式:

<tr bgcolor="white">
   <td>
      <input type="radio" name="booking_choice" value="1">
   </td>
   <td class="tableTxt">
      Friday, January 16, 2015</td>
   <td class="tableTxt">
      08:45 a.m.</td>
   <td class="tableTxt">
      45 minutes</td>
</tr>

还有另外两个单选按钮,其值为0和2,这就是迭代器的用途。但是,在选择按钮的任何一次迭代中,我都会收到以下错误:

Error while executing command: An element command failed because the referenced element is no longer attached to the DOM.: {"errorMessage":"Element does not exist in cache","request".....

我可以使用xpath找到页面上的按钮,并且它总是返回成功:

if ($mech->xpath('//*[@name="booking_choice"]', one => 1)) {
      say "Success";
}

我不明白的是:

  1. 为什么即使我可以在html源页面上看到该元素,也无法再访问该元素。
  2. 如何保持元素完好无损,以便可供选择。
  3. 我对webscraping,网络自动化非常陌生,我在这个论坛上发现了一些类似的问题但是它们要么是为ruby编写的,要么是使用其他一些webdriver而不是phantomjs。我不知道如何使用mechanize :: phantomjs实现任何给定的解决方案。我会感激任何帮助。谢谢!

    我已将源HTML文件放在此处:http://www.datafilehost.com/d/948c5371

1 个答案:

答案 0 :(得分:0)

mechanize要求您在设置表单字段之前选择表单。这可以通过各种功能完成,例如

  • $mech->form_name( $name [, %options] )
  • $mech->form_id( $id [, %options] )
  • $mech->form_number( $number [, %options] )
  • $mech->form_with_fields( [$options], @fields )

取自here


如果这不起作用,您始终可以在页面上下文中运行一些自定义代码来更改字段。对于无线电盒子,这将是这样的:

$mech->eval(<<'JS', $i);
    document.querySelectorAll("[name='formName'] [name='radioButtonName']")[arguments[0]].checked = true;
JS

虽然,这只会改变单选按钮的属性,但在大多数情况下这就足够了。但有时在DOM元素上有事件处理程序,在这种情况下不会被触发。

另一种方法是实际使用$mech->click( $name [,$x ,$y] )点击单选按钮并触发所有必要的事件。