这是我的HTML:
<tbody><tr><th>SHOES</th></tr>
<tr>
<td>
Shoe 1 <br>shoe 2<br> shoe3 <br>
</td>
</tr>
</tbody>
这是我的代码:
nodes = page.css("tr").select do |el|
el.css('th').text =~ /SHOES/
end
nodes.each do |value|
puts value.css("td").text
end
我希望获得值shoe 1
,shoe 2
和shoe 3
,但没有输出。我怀疑<tr></tr>
之间有一个额外的<tr><th>SHOES</th></tr>
。或者<br>
是罪魁祸首?
还有其他结构,如:
<tr>
<th>SHOES</th>
<td>NBA</td>
</tr>
我得到了所需的输出"NBA"
。
我做错了什么?
我有两种结构:
Name1: value
Name1: value2
以上将给出:
<tr>
<th>Name1</th>
<td>Value</td>
</tr>
但有时它是:
Name:
value
value2
value3
所以HTML是:
<tbody><tr><th>Name</th></tr>
<tr>
<td>value<br>value2<br> ....</td>
答案 0 :(得分:3)
在HTML中,表由行组成。当您按这些行进行迭代时,只有其中一行是标题。虽然逻辑上你看到了主体行和标题行之间的关系,但对于HTML(因此对于Nokogiri)来说,没有。
如果您想要的是获取具有特定标题的单元格的每个值,您可以做的是计算特定列,然后从那里获取值。
将此HTML用作源
html = '<tbody><tr><th>HATS</th><th>SHOES</th></tr>
<tr>
<td>
hat 1 <br>hat 2<br> hat3 <br>
</td>
<td>
Shoe 1 <br>shoe 2<br> shoe3 <br>
</td>
</tr>
</tbody>'
然后我们按照在表格的第一行中获取右边的位置
page = Nokogiri::HTML(html)
shoes_position = page.css("tr")[0].css('th').find_index do |el|
el.text =~ /SHOES/
end
然后,我们在每个其他行中找到该位置的s,并从该
中获取文本shoes_tds = page.css('tr').map {|row| row.css('td')[shoes_position] }.compact
shoes_names = shoes_tds.map { |td| td.text }
我使用compact来删除nil值,因为第一行(带标题的那一行)没有td,因此返回nil
答案 1 :(得分:0)
你可以用css到达那里:
td = doc.at('tr:has(th[text()=SHOES]) + tr td')
td.children.map{|x| x.text.strip}.reject(&:empty?)
#=> ["Shoe 1", "shoe 2", "shoe3"]
但也许将它与xpath混合起来更好:
td.search('./text()').map{|x| x.text.strip}
#=> ["Shoe 1", "shoe 2", "shoe3"]