我是nokogiri的新手,到目前为止最熟悉的CSS选择器,我试图从表中解析信息,下面是表的示例和我正在使用的代码,我坚持在适当的if声明,因为它似乎返回表的全部内容。
表:
<div class="holder">
<div class ="row">
<div class="c1">
<!-- Content I Don't need -->
</div>
<div class="c2">
<span class="data">
<!-- Content I Don't Need -->
<span class="data">
</div>
</div>
...
<div class="row">
<div class="c1">
SPECIFIC TEXT
</div>
<div class="c2">
<span class="data">
What I want
</span>
</div>
</div>
</div>
我的脚本:(如果在表格中找到SPECIFIC TEXT,它会返回每个“div.c2 span.data”变量 - 所以我要么搞砸了我对do循环或if语句的了解)
data = []
page.agent.get(url)
page.search('div.row').each do |row_data|
if (row_data.search('div.c1:contains("/SPECIFIC TEXT/")').text.strip
temp = row_data.search('div.c2 span.data').text.strip
data << temp
end
end
答案 0 :(得分:4)
当您可以在单个CSS选择器中提取所需内容时,无需停止并插入ruby逻辑。
data = page.search('div.row > div.c1:contains("SPECIFIC TEXT") + div.c2 span.data')
这将仅包括与选择器匹配的那些(例如,遵循SPECIFIC TEXT)。
这是你的逻辑可能出错的地方:
此代码
if (row_data.search('div.c1:contains("SPECIFIC TEXT")'...
temp = row_data.search('div.c2 span.data')...
首先在行中搜索特定文本,然后如果匹配,则返回与第二个查询匹配的所有行,这些行具有相同的起始点。关键是上面的CSS选择器中的+
将返回紧跟其后的元素(例如下一个兄弟元素)。当然,我正在假设下一个元素总是你想要的。
答案 1 :(得分:2)
我会做
require 'nokogiri'
html = <<_
<div class="holder">
<div class ="row">
<div class="c1">
<!-- Content I Don't need -->
</div>
<div class="c2">
<span class="data">
<!-- Content I Don't Need -->
<span class="data">
</div>
</div>
<div class="row">
<div class="c1">
SPECIFIC TEXT
</div>
<div class="c2">
<span class="data">
What I want
</span>
</div>
</div>
</div>
_
doc = Nokogiri::HTML(html)
css_string = 'div.row > div.c1[text()*="SPECIFIC TEXT"] + div.c2 span.data'
doc.at(css_string).text.strip
# => "What I want"
这些选择器如何在这里工作 -
[name*="value"]
- 选择具有指定属性的元素,其值包含给定的子字符串。
Child Selector (“parent > child”)
- 选择由“parent”指定的元素“child”指定的所有直接子元素。
Next Adjacent Selector (“prev + next”)
- 选择与“next”匹配的所有下一个元素,这些元素前面紧跟一个兄弟“prev”。
Class Selector (“.class”)
- 选择具有给定类的所有元素。
Descendant Selector (“ancestor descendant”)
- 选择作为给定祖先后代的所有元素。