使用Ruby和Nokogiri解析表格?

3
这是我的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

我希望能获取到鞋1鞋2鞋3的值,但没有输出。我怀疑在<tr><th>鞋</th></tr>之间有一个额外的<tr></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>

阅读此内容:这个这个 - Roman Kiselenko
因为在你的第二个tr中没有thel.css('th').text =~ /SHOES/ 选择只有th标签和文本模式SHOEStr - Arup Rakshit
那我应该将我的代码更改为 nodes = page.css("th").select do |el| 吗?那么我该如何获取 thSHOES 呢? - dorothy
@dorothy 为什么你需要 th - Arup Rakshit
@ArupRakshit,是的。我想改为nodes = page.css("th").select do |el|而不是nodes = page.css("tr").select do |el|应该没问题吧? - dorothy
显示剩余3条评论
2个回答

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 }

我使用一个紧凑函数来删除空值,因为第一行(具有标题的行)将不会有 td,因此返回 nil。


谢谢。虽然我已经使用.next_element解决了我的问题。 - dorothy

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"]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接