使用Nokogiri遍历没有CSS类的HTML?

Shp*_*ord 2 ruby xpath ruby-on-rails nokogiri

我有以下HTML:

<table width="100%" border="0" cellpadding="6" cellspacing="1">
  <tbody>
    <tr>
      <td bgcolor="#ffd204" width="40%" nowrap=""><b>Tracking Number:</b></td>
      <td bgcolor="#ffffff" width="60%" nowrap="">C123456789012345</td>
    </tr>
    <!-- ...there could be additional table rows here... -->
    <tr>
      <td bgcolor="#ffd204" width="40%" nowrap=""><b>Deliver To:</b></td>
      <td bgcolor="#ffffff" width="60%" nowrap="">ANYWHERE, NY</td>
    </tr>
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

比如说,我需要提取ANYWHERE, NY数据.我怎么用Nokogiri呢?或者是否有更好的东西来遍历这种没有任何CSS选择器来搜索的东西?

Phr*_*ogz 8

由于我们没有要使用的CSS类,id属性或其他语义标记,因此我们会在本文档中寻找可能不会更改的内容来锚定我们的搜索.在这种情况下,我怀疑"Deliver To:"标签总是在我们想要的td之前.所以:

require 'nokogiri'

html = # Fetch either from http via open-uri's open() or from file via IO.read()
doc = Nokogiri.HTML(html) 
delivery = doc.at_xpath '//td[preceding-sibling::td[b="Deliver To:"]]/text()'    
p delivery.content
#=> "ANYWHERE, NY"
Run Code Online (Sandbox Code Playgroud)

那个XPath表达式说:

  • // - 在任何级别,
  • td - 找到一个名为的元素 td
  • […] - 但只有......
    • preceding-sibling:: - 它有一个前面的兄弟姐妹
    • td - 这是一个名为的元素 td
    • […] - 但只有......
      • b - 它有一个名为的子元素 b
      • ="Deliver To:" - 其文本内容等于此字符串
  • /text()- 然后找到我的子文本节点td.

因为我们使用at_xpath而不是xpath,Nokogiri返回它可以找到的第一个匹配节点 - 在这种情况下碰巧是该td的唯一子文本节点 - 而不是节点数组.

如果<td>可以有标记,例如<td…>ANYWHERE,<br>NY</td>您可以修改表达式以省略尾随/text()(以便您只选择<td>自身),然后使用该text方法获取其中的组合可见文本.