如何让浏览器等待 Capybara & Kimurai?
How do I get the browser to wait with Capybara & Kimurai?
我正在抓取 [此页面][1] 以查找包含在 CSS 选择器 .box .column
中的学校的详细信息,这些选择器包含在 div .schools
这是动态加载的,需要一些时间才能出现。
我已经用 watir gem 完成了这个并且没有任何问题。这是参考代码。
browser = Watir::Browser.new
browser.goto('https://educationdestinationmalaysia.com/schools/pre-university')
js_doc = browser.element(css: '.schools').wait_until(&:present?)
schools_list = Nokogiri::HTML(js_doc.inner_html)
school_cards = schools_list.css('.box .columns .column:nth-child(2)')
我现在正尝试使用 kimurai
gem 实现相同的效果,但我对水豚并不十分熟悉。
我试过的
- 更改默认最长等待时间
def parse(response, url:, data: {})
Capybara.default_max_wait_time = 20
puts browser.has_css?('div.schools')
end
using_wait_time
browser.using_wait_time(20) do
puts browser.has_css?('.schools')
end
- 将
wait
参数传递给 has_css?
browser.has_css?('.schools', wait: 20)
感谢阅读!
[1]: https://educationdestinationmalaysia.com/schools/pre-university
您的 Watir 代码
js_doc = browser.element(css: '.schools').wait_until(&:present?)
return 是元素,但在您的 Capybara 代码中,您正在调用谓词方法(has_css?、has_xpath?、has_selector?等)只是 return 真或假。这些谓词方法只会在 Capybara.predicates_wait
为真时等待。不过,您使用谓词是否有特定原因?相反,您可以只 find
您感兴趣的元素,它将等待 Capybara.default_max_wait_time
或者您可以指定自定义等待选项。
的 Watir 示例的“等效”
js_doc = browser.element(css: '.schools').wait_until(&:present?)
schools_list = Nokogiri::HTML(js_doc.inner_html)
school_cards = schools_list.css('.box .columns .column:nth-child(2)'
假设您已经 Capybara.default_max_wait_time 设置了一个足够高的数字来满足您的应用和测试设置
school_cards = browser.find('.schools').all('.box .columns .column:nth-child(2)')
如果您确实需要延长对其中一项发现的等待时间,您可以这样做
school_cards = browser.find('.schools', wait: 10).all('.box .columns .column:nth-child(2)')
最多等待 10 秒,让 .schools
元素出现。这也可以折叠成
school_cards = browser.all('.schools .box .columns .column:nth-child(2)')
这也将等待(最多 Capybara.default_max_wait_time)至少一个匹配元素存在,然后再 returning 它,尽管取决于您的确切 HTML
school_cards = browser.all('.schools .column:nth-child(2)')
可能同样好而且不那么脆弱
注意:您必须使用支持 JS 的 Kimurai 引擎 - https://github.com/vifreefly/kimuraframework#available-engines - 否则您将无法与动态网站进行交互
我正在抓取 [此页面][1] 以查找包含在 CSS 选择器 .box .column
中的学校的详细信息,这些选择器包含在 div .schools
这是动态加载的,需要一些时间才能出现。
我已经用 watir gem 完成了这个并且没有任何问题。这是参考代码。
browser = Watir::Browser.new
browser.goto('https://educationdestinationmalaysia.com/schools/pre-university')
js_doc = browser.element(css: '.schools').wait_until(&:present?)
schools_list = Nokogiri::HTML(js_doc.inner_html)
school_cards = schools_list.css('.box .columns .column:nth-child(2)')
我现在正尝试使用 kimurai
gem 实现相同的效果,但我对水豚并不十分熟悉。
我试过的
- 更改默认最长等待时间
def parse(response, url:, data: {})
Capybara.default_max_wait_time = 20
puts browser.has_css?('div.schools')
end
using_wait_time
browser.using_wait_time(20) do
puts browser.has_css?('.schools')
end
- 将
wait
参数传递给has_css?
browser.has_css?('.schools', wait: 20)
感谢阅读! [1]: https://educationdestinationmalaysia.com/schools/pre-university
您的 Watir 代码
js_doc = browser.element(css: '.schools').wait_until(&:present?)
return 是元素,但在您的 Capybara 代码中,您正在调用谓词方法(has_css?、has_xpath?、has_selector?等)只是 return 真或假。这些谓词方法只会在 Capybara.predicates_wait
为真时等待。不过,您使用谓词是否有特定原因?相反,您可以只 find
您感兴趣的元素,它将等待 Capybara.default_max_wait_time
或者您可以指定自定义等待选项。
js_doc = browser.element(css: '.schools').wait_until(&:present?)
schools_list = Nokogiri::HTML(js_doc.inner_html)
school_cards = schools_list.css('.box .columns .column:nth-child(2)'
假设您已经 Capybara.default_max_wait_time 设置了一个足够高的数字来满足您的应用和测试设置
school_cards = browser.find('.schools').all('.box .columns .column:nth-child(2)')
如果您确实需要延长对其中一项发现的等待时间,您可以这样做
school_cards = browser.find('.schools', wait: 10).all('.box .columns .column:nth-child(2)')
最多等待 10 秒,让 .schools
元素出现。这也可以折叠成
school_cards = browser.all('.schools .box .columns .column:nth-child(2)')
这也将等待(最多 Capybara.default_max_wait_time)至少一个匹配元素存在,然后再 returning 它,尽管取决于您的确切 HTML
school_cards = browser.all('.schools .column:nth-child(2)')
可能同样好而且不那么脆弱
注意:您必须使用支持 JS 的 Kimurai 引擎 - https://github.com/vifreefly/kimuraframework#available-engines - 否则您将无法与动态网站进行交互