如何通过xpath指定多列

时间:2015-06-04 16:11:17

标签: ruby xpath nokogiri

我想从HTML中获取多个表数据:

html = <<EOF
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
</table>
EOF

我想从中获取两个数据:

noko = Nokogiri::HTML(html)
noko.xpath("//tr[1]/td[2]").text #=> "2"
noko.xpath("//tr[1]/td[3]").text #=> "3"

我对此代码的期望是&#34; 23&#34;,但它返回&#34; 123&#34;。 我怎样才能得到&#34; 23&#34;使用xpath?

noko.xpath("//tr[1]/td[2 and 3]").text

4 个答案:

答案 0 :(得分:1)

有多种方法可以解决这个问题。一个是:

require 'nokogiri'

html = <<EOF
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
</table>
EOF

noko = Nokogiri::HTML(html)
p noko.xpath("//tr[1]/td[position()= 2 or position() = 3]").map(&:text).join 
# => 23
# another way
p noko.xpath("//tr[1]/td[2]", "//tr[1]/td[3]").map(&:text).join
# => 23

答案 1 :(得分:0)

如果您不依赖于XPath,则可以使用CSS执行此操作:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOF)
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
</table>
EOF

td_data = doc.search('tr').map { |tr|
  tr.search('td:nth-child(2), td:nth-child(3)').map(&:text)
}
td_data # => [["2", "3"], ["5", "6"]]

对于较旧的,不兼容的浏览器:

td_data = doc.search('tr').map { |tr|
  tr.search('td:first-child + td, td:first-child + td + td').map(&:text)
}
td_data # => [["2", "3"], ["5", "6"]]

如果您需要返回的值为"23"和/或"56",请使用:

td_data.map(&:join) # => ["23", "56"]

虽然我不明白为什么它过于有用。

答案 2 :(得分:0)

怎么样:

doc.search('tr[1] td:gt(1)').text
#=> "23"

答案 3 :(得分:0)

使用position()使用xpath获取多个不同位置索引中的元素,例如:

//tr[1]/td[position()=2 or position()=3]

您还可以使用xpath union运算符(|)来组合多个xpath表达式,如下所示:

//tr[1]/td[2] | //tr[1]/td[3]

我更喜欢前一种方式,但工会可能是不同情况下的唯一选择,所以值得一提。