如何在watir中完成元素搜索?

时间:2018-10-03 13:53:55

标签: ruby-on-rails ruby watir

我应该保存页面https://www.walmart.com/ip/Ematic-9-Dual-Screen-Portable-DVD-Player-with-Dual-DVD-Players-ED929D/28806789中的所有评论。为此,我使用Watir,因为它是动态页面,并且需要单击按钮来更新结果。我先检查按钮是否存在,然后再刮取评论。但是当所有评论都保存在最后一页时,它并没有完成过程并搜索元素,并且30秒后我出现了错误。

错误:

Watir::Exception::UnknownObjectException (timed out after 30 seconds, waiting for #<Watir::Div: located: false; {:css=>".review-body-text", :index=>10, :tag_name=>:div}> to be located; Maybe look in an iframe?):

我的代码:

while  browser.element(:text => "Next Page").present?
      browser.elements(css:'.review-body-text').each do |comment|
        review= Review.new
        review.text=comment.text
        product.reviews<<review
        review.save
      end
        browser.button(:text => "Next Page").click
    end while  browser.element(:text => "Next Page").present?
    browser.close

3 个答案:

答案 0 :(得分:0)

实际上,“下一页”文本不在按钮中,而是在范围内,因此编写代码

while b.span(:text => "Next Page").present?
  b.elements(css: '.review-body-text').each do |comment|
    p comment
  end
  b.span(text: "Next Page").click
end

它将为您工作。

答案 1 :(得分:0)

def get_all_reviews
  loop do
    # Call method to get reviews on page     
    break unless b.span(:text => "Next Page").present?
    b.span(text: "Next Page").click
  end
end

我认为Rubys循环确实很适合这种操作。

我还建议您将变量分配给这些元素,以使代码更易于阅读,如下所示:

def get_all_reviews
  loop do
    # Call method to get reviews on page     
    break unless next_page.present?
    next_page.click
  end
end

答案 2 :(得分:0)

加载评论的下一页是异步完成的。这可能导致尝试在更改评论的过程中阅读评论。点击分页按钮后,您需要等待评论列表加载完成。

可能有多种方法可以检测到这一点。下面的示例等待分页控件更新为新的页码。

paginator_list = browser.ul(class: 'paginator-list')
last_page = paginator_list.button(aria_label: true, index: -1).text.to_i
1.upto(last_page) do |i|
  browser.divs(class: 'review-body-text').each do |comment|
    review= Review.new
    review.text=comment.text
    product.reviews<<review
    review.save
  end

  unless i == last_page
    browser.button(text: 'Next Page').click
    browser.wait_until do
      current = paginator_list.button(class: 'active').text.to_i
      current == i + 1
    end
  end
end